diff --git a/experimental/src/generic/mod.rs b/experimental/src/generic/mod.rs index 75b27617a..189ea8017 100644 --- a/experimental/src/generic/mod.rs +++ b/experimental/src/generic/mod.rs @@ -1,8 +1,10 @@ extern crate serde; extern crate serde_json; -use snmp::{r_snmp_bulk_walk, SnmpResult}; use serde::Deserialize; +use snmp::{r_snmp_bulk_walk, SnmpResult, SnmpValue}; + +use std::collections::BTreeMap; #[derive(Copy, Clone, PartialEq)] pub enum Status { @@ -177,199 +179,227 @@ impl Command { target: &str, version: &str, community: &str, - ext: &CommandExt, + //ext: &CommandExt, ) -> CmdResult { -// let mut agregation = ("", 0, Operation::None); -// let mut res: Option<(&str, SnmpResult)> = None; -// for (idx, entry) in self.leaf.entries.iter().enumerate() { -// match entry { -// Entry::Agregation(op) => { -// agregation = (&op.name, idx, op.op); -// } -// Entry::Query(query) => match query.query { -// QueryType::Walk => { -// res = Some(( -// &query.name, -// r_snmp_bulk_walk(target, version, community, &query.oid), -// )); -// } -// }, -// } -// } -// match res { -// Some(r) => { -// let mut values: Vec<(String, f32)> = Vec::new(); -// let mut idx = 0; -// r.1.variables.iter().for_each(|v| { -// let label = r.0.replace("{idx}", &idx.to_string()); -// values.push((label, v.value.parse().unwrap())); -// idx += 1; -// }); -// let count = values.len(); -// let ag = match agregation.2 { -// Operation::Average => { -// let sum: f32 = values.iter().map(|(_, v)| v).sum(); -// let avg = sum / values.len() as f32; -// Some((agregation.0, agregation.1, avg)) -// } -// _ => None, -// }; -// let (metrics, status) = build_metrics(&values, &ag, &ext); -// let output = self.build_output(count, status, &metrics, &ag, &ext); -// return CmdResult { status, output }; -// } -// None => { -// return CmdResult { -// status: Status::Unknown, -// output: "No result".to_string(), -// }; -// } -// } + let mut res: BTreeMap = BTreeMap::new(); + for s in self.collect.snmp.iter() { + match s.query { + QueryType::Walk => { + let r = r_snmp_bulk_walk(target, version, community, &s.oid); + match r.variables.len() { + 1 => { + let result = r.variables.get(0).unwrap(); + if let SnmpValue::Integer(v) = result.value { + res.insert(s.name.clone(), v); + } + } + _ => { + for (idx, result) in r.variables.iter().enumerate() { + if let SnmpValue::Integer(v) = result.value { + res.insert(format!("{}_{}", &s.name, idx), v); + } + } + } + } + } + QueryType::Get => { + // let r = r_snmp_bulk_get(target, version, community, &s.oid); + // res.insert(&s.name, r); + } + } + } + println!("{:?}", res); + // let mut aggregation = ("", 0, Operation::None); + // let mut res: Option<(&str, SnmpResult)> = None; + // for (idx, entry) in self.leaf.entries.iter().enumerate() { + // match entry { + // Entry::Agregation(op) => { + // agregation = (&op.name, idx, op.op); + // } + // Entry::Query(query) => match query.query { + // QueryType::Walk => { + // res = Some(( + // &query.name, + // r_snmp_bulk_walk(target, version, community, &query.oid), + // )); + // } + // }, + // } + // } + // match res { + // Some(r) => { + // let mut values: Vec<(String, f32)> = Vec::new(); + // let mut idx = 0; + // r.1.variables.iter().for_each(|v| { + // let label = r.0.replace("{idx}", &idx.to_string()); + // values.push((label, v.value.parse().unwrap())); + // idx += 1; + // }); + // let count = values.len(); + // let ag = match agregation.2 { + // Operation::Average => { + // let sum: f32 = values.iter().map(|(_, v)| v).sum(); + // let avg = sum / values.len() as f32; + // Some((agregation.0, agregation.1, avg)) + // } + // _ => None, + // }; + // let (metrics, status) = build_metrics(&values, &ag, &ext); + // let output = self.build_output(count, status, &metrics, &ag, &ext); + // return CmdResult { status, output }; + // } + // None => { + // return CmdResult { + // status: Status::Unknown, + // output: "No result".to_string(), + // }; + // } + // } CmdResult { status: Status::Unknown, output: "No result".to_string(), } } -// fn build_output( -// &self, -// count: usize, -// status: Status, -// metrics: &Vec, -// ag: &Option<(&str, usize, f32)>, -// ext: &CommandExt, -// ) -> String { -// let no_threshold = ext.warning_core.is_none() -// && ext.critical_core.is_none() -// && ext.warning_agregation.is_none() -// && ext.critical_agregation.is_none(); -// let write_details = -// no_threshold || (ext.warning_core.is_some() || ext.critical_core.is_some()); -// let write_agregation_details = -// no_threshold || (ext.warning_agregation.is_some() || ext.critical_agregation.is_some()); -// let mut output_text = "".to_string(); -// let mut begun = false; -// if &self.leaf.output.header != "" { -// output_text = self.leaf.output.header.replace("{status}", status.as_str()); -// } -// for line in &self.leaf.output.text { -// if line.contains("idx") { -// if write_details { -// // We have to iterate on metrics -// let mut output_vec = (Vec::new(), Vec::new(), Vec::new()); -// let mut idx = 0; -// for m in metrics.iter() { -// if !m.agregated { -// let text = line -// .replace("{idx}", idx.to_string().as_str()) -// .replace("{name}", m.name.as_str()) -// .replace("{value}", format!("{:.2}", m.value).as_str()) -// .replace("{count}", count.to_string().as_str()); -// match m.status { -// Status::Ok => { -// output_vec.0.push(text); -// } -// Status::Warning => { -// output_vec.1.push(text); -// } -// Status::Critical => { -// output_vec.2.push(text); -// } -// Status::Unknown => (), -// } -// idx += 1; -// } -// } -// if !output_vec.2.is_empty() { -// if begun { -// output_text += " - "; -// } else { -// begun = true; -// } -// output_text += output_vec.2.join(" - ").as_str(); -// } -// if !output_vec.1.is_empty() { -// if begun { -// output_text += " - "; -// } else { -// begun = true; -// } -// output_text += output_vec.1.join(" - ").as_str(); -// } -// if !output_vec.0.is_empty() { -// if begun { -// output_text += " - "; -// } -// output_text += output_vec.0.join(" - ").as_str(); -// } -// } -// } else { -// if write_agregation_details { -// match ag { -// Some(a) => { -// output_text += line -// .replace( -// format!("{{{}}}", a.0).as_str(), -// format!("{:.2}", a.2).as_str(), -// ) -// .replace("{count}", count.to_string().as_str()) -// .as_str(); -// begun = true; -// } -// None => output_text += line, -// }; -// } -// } -// } -// -// let mut perfdata = " |".to_string(); -// match &self.leaf.data { -// Some(d) => { -// metrics.iter().for_each(|m| { -// perfdata += format!( -// " '{}'={}{};{};{};{};{}", -// m.name, -// m.value, -// d.uom, -// match m.warning { -// Some(m) => m.to_string(), -// None => "".to_string(), -// }, -// match m.critical { -// Some(m) => m.to_string(), -// None => "".to_string(), -// }, -// match d.min { -// Some(m) => m.to_string(), -// None => "".to_string(), -// }, -// match d.max { -// Some(m) => m.to_string(), -// None => "".to_string(), -// }, -// ) -// .as_str(); -// }); -// } -// None => { -// metrics.iter().for_each(|m| { -// perfdata += format!( -// " '{}'={};{};{}", -// m.name, -// m.value, -// match m.warning { -// Some(v) => v.to_string(), -// None => "".to_string(), -// }, -// match m.critical { -// Some(v) => v.to_string(), -// None => "".to_string(), -// } -// ) -// .as_str(); -// }); -// } -// }; -// output_text + &perfdata -// } + // fn build_output( + // &self, + // count: usize, + // status: Status, + // metrics: &Vec, + // ag: &Option<(&str, usize, f32)>, + // ext: &CommandExt, + // ) -> String { + // let no_threshold = ext.warning_core.is_none() + // && ext.critical_core.is_none() + // && ext.warning_agregation.is_none() + // && ext.critical_agregation.is_none(); + // let write_details = + // no_threshold || (ext.warning_core.is_some() || ext.critical_core.is_some()); + // let write_agregation_details = + // no_threshold || (ext.warning_agregation.is_some() || ext.critical_agregation.is_some()); + // let mut output_text = "".to_string(); + // let mut begun = false; + // if &self.leaf.output.header != "" { + // output_text = self.leaf.output.header.replace("{status}", status.as_str()); + // } + // for line in &self.leaf.output.text { + // if line.contains("idx") { + // if write_details { + // // We have to iterate on metrics + // let mut output_vec = (Vec::new(), Vec::new(), Vec::new()); + // let mut idx = 0; + // for m in metrics.iter() { + // if !m.agregated { + // let text = line + // .replace("{idx}", idx.to_string().as_str()) + // .replace("{name}", m.name.as_str()) + // .replace("{value}", format!("{:.2}", m.value).as_str()) + // .replace("{count}", count.to_string().as_str()); + // match m.status { + // Status::Ok => { + // output_vec.0.push(text); + // } + // Status::Warning => { + // output_vec.1.push(text); + // } + // Status::Critical => { + // output_vec.2.push(text); + // } + // Status::Unknown => (), + // } + // idx += 1; + // } + // } + // if !output_vec.2.is_empty() { + // if begun { + // output_text += " - "; + // } else { + // begun = true; + // } + // output_text += output_vec.2.join(" - ").as_str(); + // } + // if !output_vec.1.is_empty() { + // if begun { + // output_text += " - "; + // } else { + // begun = true; + // } + // output_text += output_vec.1.join(" - ").as_str(); + // } + // if !output_vec.0.is_empty() { + // if begun { + // output_text += " - "; + // } + // output_text += output_vec.0.join(" - ").as_str(); + // } + // } + // } else { + // if write_agregation_details { + // match ag { + // Some(a) => { + // output_text += line + // .replace( + // format!("{{{}}}", a.0).as_str(), + // format!("{:.2}", a.2).as_str(), + // ) + // .replace("{count}", count.to_string().as_str()) + // .as_str(); + // begun = true; + // } + // None => output_text += line, + // }; + // } + // } + // } + // + // let mut perfdata = " |".to_string(); + // match &self.leaf.data { + // Some(d) => { + // metrics.iter().for_each(|m| { + // perfdata += format!( + // " '{}'={}{};{};{};{};{}", + // m.name, + // m.value, + // d.uom, + // match m.warning { + // Some(m) => m.to_string(), + // None => "".to_string(), + // }, + // match m.critical { + // Some(m) => m.to_string(), + // None => "".to_string(), + // }, + // match d.min { + // Some(m) => m.to_string(), + // None => "".to_string(), + // }, + // match d.max { + // Some(m) => m.to_string(), + // None => "".to_string(), + // }, + // ) + // .as_str(); + // }); + // } + // None => { + // metrics.iter().for_each(|m| { + // perfdata += format!( + // " '{}'={};{};{}", + // m.name, + // m.value, + // match m.warning { + // Some(v) => v.to_string(), + // None => "".to_string(), + // }, + // match m.critical { + // Some(v) => v.to_string(), + // None => "".to_string(), + // } + // ) + // .as_str(); + // }); + // } + // }; + // output_text + &perfdata + // } } diff --git a/experimental/src/main.rs b/experimental/src/main.rs index de83cf382..7fe9731fd 100644 --- a/experimental/src/main.rs +++ b/experimental/src/main.rs @@ -71,6 +71,8 @@ fn main() { let mut parser = lexopt::Parser::from_env(); let mut hostname = "localhost".to_string(); let mut port = 161; + let mut snmp_version = "2c".to_string(); + let mut snmp_community = "public".to_string(); let mut json = None; loop { let arg = parser.next(); @@ -91,6 +93,14 @@ fn main() { json = Some(parser.value().unwrap().into_string().unwrap()); println!("json: {:?}", json); }, + Short('v') | Long("snmp-version") => { + snmp_version = parser.value().unwrap().into_string().unwrap(); + println!("snmp_version: {}", snmp_version); + }, + Short('c') | Long("snmp-community") => { + snmp_community = parser.value().unwrap().into_string().unwrap(); + println!("snmp_community: {}", snmp_community); + }, _ => { println!("other"); } @@ -123,7 +133,7 @@ fn main() { // warning_agregation: cli.warning_agregation, // critical_agregation: cli.critical_agregation, //}; - //let result = cmd.execute(&url, &cli.snmp_version, &cli.community, &ext); + let result = cmd.execute(&url, &snmp_version, &snmp_community); //println!("{}", result.output); //std::process::exit(result.status as i32); } diff --git a/experimental/src/snmp/mod.rs b/experimental/src/snmp/mod.rs index 157105e3c..9186538a2 100644 --- a/experimental/src/snmp/mod.rs +++ b/experimental/src/snmp/mod.rs @@ -4,6 +4,7 @@ extern crate rasn_smi; extern crate rasn_snmp; use log::{info, trace, warn}; +use rasn::types::IntegerType; use rasn::types::ObjectIdentifier; use rasn_snmp::v2::Pdus; use rasn_snmp::v2::VarBind; @@ -11,6 +12,7 @@ use rasn_snmp::v2::VarBindValue; use rasn_snmp::v2::{BulkPdu, Pdu}; use rasn_snmp::v2::{GetBulkRequest, GetNextRequest, GetRequest}; use rasn_snmp::v2c::Message; +use std::convert::TryInto; use std::ffi::CStr; use std::ffi::CString; use std::net::UdpSocket; @@ -23,14 +25,20 @@ pub struct SnmpResult { type CSnmpVariable = c_void; +#[derive(Debug, PartialEq)] +pub enum SnmpValue { + Integer(i64), + String(String), +} + #[derive(Debug, PartialEq)] pub struct SnmpVariable { pub name: String, - pub value: String, + pub value: SnmpValue, } impl SnmpVariable { - fn new(name: String, value: String) -> SnmpVariable { + fn new(name: String, value: SnmpValue) -> SnmpVariable { SnmpVariable { name, value } } } @@ -44,7 +52,7 @@ impl SnmpResult { } } - fn add_variable(&mut self, name: String, value: String) { + fn add_variable(&mut self, name: String, value: SnmpValue) { self.variables.push(SnmpVariable::new(name, value)); } @@ -53,83 +61,83 @@ impl SnmpResult { } } -#[allow(non_snake_case)] -#[no_mangle] -pub extern "C" fn snmpresult_DESTROY(p: *mut CSnmpResult) { - unsafe { Box::from_raw(p as *mut SnmpResult) }; -} +//#[allow(non_snake_case)] +//#[no_mangle] +//pub extern "C" fn snmpresult_DESTROY(p: *mut CSnmpResult) { +// unsafe { Box::from_raw(p as *mut SnmpResult) }; +//} -#[allow(non_snake_case)] -#[no_mangle] -pub extern "C" fn snmpresult_get_variable(p: *mut CSnmpResult, index: usize) -> *mut CSnmpVariable { - trace!("snmpresult_get_variable {}", index); - let p = p as *mut SnmpResult; - let p = unsafe { &mut *p }; - if index >= p.variables.len() { - return Box::into_raw(Box::new(SnmpVariable::new("".to_string(), "".to_string()))) - as *mut CSnmpVariable; - } - let v = &p.variables[index]; - Box::into_raw(Box::new(SnmpVariable { - name: v.name.clone(), - value: v.value.clone(), - })) as *mut CSnmpVariable -} +//#[allow(non_snake_case)] +//#[no_mangle] +//pub extern "C" fn snmpresult_get_variable(p: *mut CSnmpResult, index: usize) -> *mut CSnmpVariable { +// trace!("snmpresult_get_variable {}", index); +// let p = p as *mut SnmpResult; +// let p = unsafe { &mut *p }; +// if index >= p.variables.len() { +// return Box::into_raw(Box::new(SnmpVariable::new("".to_string(), "".to_string()))) +// as *mut CSnmpVariable; +// } +// let v = &p.variables[index]; +// Box::into_raw(Box::new(SnmpVariable { +// name: v.name.clone(), +// value: v.value.clone(), +// })) as *mut CSnmpVariable +//} +// +//#[allow(non_snake_case)] +//#[no_mangle] +//pub extern "C" fn snmpresult_variables_count(p: *mut CSnmpResult) -> usize { +// let p = p as *mut SnmpResult; +// let p = unsafe { &mut *p }; +// p.variables.len() +//} +// +//#[allow(non_snake_case)] +//#[no_mangle] +//pub extern "C" fn snmpvariable_DESTROY(p: *mut CSnmpVariable) { +// unsafe { Box::from_raw(p as *mut SnmpVariable) }; +//} -#[allow(non_snake_case)] -#[no_mangle] -pub extern "C" fn snmpresult_variables_count(p: *mut CSnmpResult) -> usize { - let p = p as *mut SnmpResult; - let p = unsafe { &mut *p }; - p.variables.len() -} +//#[allow(non_snake_case)] +//#[no_mangle] +//pub extern "C" fn snmpvariable_get_name(p: *mut CSnmpVariable) -> *mut c_char { +// let p = p as *mut SnmpVariable; +// let p = unsafe { &mut *p }; +// let c = CString::new(p.name.clone()).unwrap(); +// c.into_raw() +//} +// +//#[allow(non_snake_case)] +//#[no_mangle] +//pub extern "C" fn snmpvariable_get_value(p: *mut CSnmpVariable) -> *mut c_char { +// let p = p as *mut SnmpVariable; +// let p = unsafe { &mut *p }; +// let c = CString::new(p.value.clone()).unwrap(); +// c.into_raw() +//} -#[allow(non_snake_case)] -#[no_mangle] -pub extern "C" fn snmpvariable_DESTROY(p: *mut CSnmpVariable) { - unsafe { Box::from_raw(p as *mut SnmpVariable) }; -} - -#[allow(non_snake_case)] -#[no_mangle] -pub extern "C" fn snmpvariable_get_name(p: *mut CSnmpVariable) -> *mut c_char { - let p = p as *mut SnmpVariable; - let p = unsafe { &mut *p }; - let c = CString::new(p.name.clone()).unwrap(); - c.into_raw() -} - -#[allow(non_snake_case)] -#[no_mangle] -pub extern "C" fn snmpvariable_get_value(p: *mut CSnmpVariable) -> *mut c_char { - let p = p as *mut SnmpVariable; - let p = unsafe { &mut *p }; - let c = CString::new(p.value.clone()).unwrap(); - c.into_raw() -} - -#[no_mangle] -pub extern "C" fn snmp_get(target: *const c_char, oid: *const c_char) -> *mut CSnmpResult { - if target.is_null() { - return Box::into_raw(Box::new(SnmpResult::new())) as *mut CSnmpResult; - } - let target = unsafe { CStr::from_ptr(target) }; - let target = match target.to_str() { - Ok(s) => s, - Err(_) => "", - }; - - if oid.is_null() { - return Box::into_raw(Box::new(SnmpResult::new())) as *mut CSnmpResult; - } - let oid = unsafe { CStr::from_ptr(oid) }; - let oid = match oid.to_str() { - Ok(s) => s, - Err(_) => "", - }; - - Box::into_raw(Box::new(r_snmp_get(target, oid, "public"))) as *mut CSnmpResult -} +//#[no_mangle] +//pub extern "C" fn snmp_get(target: *const c_char, oid: *const c_char) -> *mut CSnmpResult { +// if target.is_null() { +// return Box::into_raw(Box::new(SnmpResult::new())) as *mut CSnmpResult; +// } +// let target = unsafe { CStr::from_ptr(target) }; +// let target = match target.to_str() { +// Ok(s) => s, +// Err(_) => "", +// }; +// +// if oid.is_null() { +// return Box::into_raw(Box::new(SnmpResult::new())) as *mut CSnmpResult; +// } +// let oid = unsafe { CStr::from_ptr(oid) }; +// let oid = match oid.to_str() { +// Ok(s) => s, +// Err(_) => "", +// }; +// +// Box::into_raw(Box::new(r_snmp_get(target, oid, "public"))) as *mut CSnmpResult +//} pub fn r_snmp_get(target: &str, oid: &str, community: &str) -> SnmpResult { let oid_tab = oid @@ -175,27 +183,27 @@ pub fn r_snmp_get(target: &str, oid: &str, community: &str) -> SnmpResult { build_response(decoded, false).0 } -#[no_mangle] -pub extern "C" fn snmp_walk(target: *const c_char, oid: *const c_char) -> *mut CSnmpResult { - if target.is_null() { - return Box::into_raw(Box::new(SnmpResult::new())) as *mut CSnmpResult; - } - let target = unsafe { CStr::from_ptr(target) }; - let target = match target.to_str() { - Ok(s) => s, - Err(_) => "", - }; - - if oid.is_null() { - return Box::into_raw(Box::new(SnmpResult::new())) as *mut CSnmpResult; - } - let oid = unsafe { CStr::from_ptr(oid) }; - let oid = match oid.to_str() { - Ok(s) => s, - Err(_) => "", - }; - Box::into_raw(Box::new(r_snmp_walk(target, oid))) as *mut CSnmpResult -} +//#[no_mangle] +//pub extern "C" fn snmp_walk(target: *const c_char, oid: *const c_char) -> *mut CSnmpResult { +// if target.is_null() { +// return Box::into_raw(Box::new(SnmpResult::new())) as *mut CSnmpResult; +// } +// let target = unsafe { CStr::from_ptr(target) }; +// let target = match target.to_str() { +// Ok(s) => s, +// Err(_) => "", +// }; +// +// if oid.is_null() { +// return Box::into_raw(Box::new(SnmpResult::new())) as *mut CSnmpResult; +// } +// let oid = unsafe { CStr::from_ptr(oid) }; +// let oid = match oid.to_str() { +// Ok(s) => s, +// Err(_) => "", +// }; +// Box::into_raw(Box::new(r_snmp_walk(target, oid))) as *mut CSnmpResult +//} pub fn r_snmp_walk(target: &str, oid: &str) -> SnmpResult { let community = "public"; @@ -258,6 +266,87 @@ pub fn r_snmp_walk(target: &str, oid: &str) -> SnmpResult { retval } +/// +/// Bulk get +/// This function is similar to the get function but it uses the GetBulkRequest PDU +/// to retrieve multiple values at once. +/// +/// # Arguments +/// * `target` - The target IP address and port +/// * `oid` - The OID to walk +/// # Returns +/// An SnmpResult structure containing the variables +/// +/// # Example +/// ``` +/// 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"); +/// ``` +pub fn r_snmp_bulk_get(target: &str, _version: &str, community: &str, oid: &str) -> SnmpResult { + let mut oid_tab = oid + .split('.') + .map(|x| x.parse::().unwrap()) + .collect::>(); + + let mut retval = SnmpResult::new(); + let mut request_id: i32 = 1; + + let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); + socket.connect(target).expect("connect function failed"); + + loop { + let variable_bindings = vec![VarBind { + name: ObjectIdentifier::new_unchecked(oid_tab.to_vec().into()), + value: VarBindValue::Unspecified, + }]; + + let pdu = BulkPdu { + request_id, + non_repeaters: 0, + max_repetitions: 10, + variable_bindings, + }; + + let get_request: GetBulkRequest = GetBulkRequest(pdu); + + let message: Message = Message { + version: 1.into(), + community: community.to_string().into(), + data: get_request.into(), + }; + + // Send the message through an UDP socket + let encoded: Vec = rasn::der::encode(&message).unwrap(); + let res: usize = socket.send(&encoded).unwrap(); + assert!(res == encoded.len()); + + let mut buf: [u8; 1024] = [0; 1024]; + let resp: (usize, std::net::SocketAddr) = socket.recv_from(buf.as_mut_slice()).unwrap(); + + trace!("Received {} bytes", resp.0); + assert!(resp.0 > 0); + let decoded: Message = rasn::ber::decode(&buf[0..resp.0]).unwrap(); + if let Pdus::Response(resp) = &decoded.data { + let resp_oid = &resp.0.variable_bindings[0].name; + 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::().unwrap()) + .collect::>(); + } + retval +} + /// /// Bulk walk /// This function is similar to the walk function but it uses the GetBulkRequest PDU @@ -378,17 +467,18 @@ fn build_response(decoded: Message, walk: bool) -> (SnmpResult, bool) { info!("Simple {:?}", value); match value { rasn_smi::v2::SimpleSyntax::Integer(value) => { - retval.add_variable(name, value.to_string()); + let v = value.try_into().unwrap(); + retval.add_variable(name, SnmpValue::Integer(v)); } rasn_smi::v2::SimpleSyntax::String(value) => { // We transform the value into a rust String retval.add_variable( name, - String::from_utf8(value.to_vec()).unwrap(), + SnmpValue::String(String::from_utf8(value.to_vec()).unwrap()), ); } _ => { - retval.add_variable(name, String::from("Other")); + retval.add_variable(name, SnmpValue::String("Other".to_string())); } }; }