diff --git a/rust/src/conf.rs b/rust/src/conf.rs index 080396a642..58e8824145 100644 --- a/rust/src/conf.rs +++ b/rust/src/conf.rs @@ -16,6 +16,8 @@ */ use std::os::raw::c_char; +use std::os::raw::c_void; +use std::os::raw::c_int; use std::ffi::{CString, CStr}; use std::ptr; use std::str; @@ -24,6 +26,10 @@ use log::*; extern { fn ConfGet(key: *const c_char, res: *mut *const c_char) -> i8; + fn ConfGetChildValue(conf: *const c_void, key: *const c_char, + vptr: *mut *const c_char) -> i8; + fn ConfGetChildValueBool(conf: *const c_void, key: *const c_char, + vptr: *mut c_int) -> i8; } // Return the string value of a configuration value. @@ -65,3 +71,58 @@ pub fn conf_get_bool(key: &str) -> bool { return false; } + +/// Wrap a Suricata ConfNode and expose some of its methods with a +/// Rust friendly interface. +pub struct ConfNode { + pub conf: *const c_void, +} + +impl ConfNode { + + pub fn wrap(conf: *const c_void) -> ConfNode { + return ConfNode{ + conf: conf, + } + } + + pub fn get_child_value(&self, key: &str) -> Option<&str> { + let mut vptr: *const c_char = ptr::null_mut(); + + unsafe { + if ConfGetChildValue(self.conf, + CString::new(key).unwrap().as_ptr(), + &mut vptr) != 1 { + return None; + } + } + + if vptr == ptr::null() { + return None; + } + + let value = str::from_utf8(unsafe{ + CStr::from_ptr(vptr).to_bytes() + }).unwrap(); + + return Some(value); + } + + pub fn get_child_bool(&self, key: &str) -> bool { + let mut vptr: c_int = 0; + + unsafe { + if ConfGetChildValueBool(self.conf, + CString::new(key).unwrap().as_ptr(), + &mut vptr) != 1 { + return false; + } + } + + if vptr == 1 { + return true; + } + return false; + } + +}