]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/log: move rust log and debug utils to debug module
authorJason Ish <jason.ish@oisf.net>
Fri, 17 Jan 2025 18:06:53 +0000 (12:06 -0600)
committerVictor Julien <victor@inliniac.net>
Fri, 17 Jan 2025 21:06:56 +0000 (22:06 +0100)
Move Rust logging, and debug_validation to a debug module to mirrow
the C side.

rust/src/common.rs
rust/src/core.rs
rust/src/dcerpc/dcerpc.rs
rust/src/debug.rs [moved from rust/src/log.rs with 61% similarity]
rust/src/lib.rs
rust/src/plugin.rs
src/util-debug.c

index c874cc58b87d01851f2ae157164085b3a8594028..aa7741f5e1b49c1aba09247e1a009aeb5675e7e4 100644 (file)
@@ -62,39 +62,6 @@ pub mod nom7 {
     }
 }
 
-#[cfg(not(feature = "debug-validate"))]
-#[macro_export]
-macro_rules! debug_validate_bug_on (
-  ($item:expr) => {};
-);
-
-#[cfg(feature = "debug-validate")]
-#[macro_export]
-macro_rules! debug_validate_bug_on (
-  ($item:expr) => {
-    if $item {
-        panic!("Condition check failed");
-    }
-  };
-);
-
-#[cfg(not(feature = "debug-validate"))]
-#[macro_export]
-macro_rules! debug_validate_fail (
-  ($msg:expr) => {};
-);
-
-#[cfg(feature = "debug-validate")]
-#[macro_export]
-macro_rules! debug_validate_fail (
-  ($msg:expr) => {
-    // Wrap in a conditional to prevent unreachable code warning in caller.
-    if true {
-      panic!($msg);
-    }
-  };
-);
-
 /// Convert a String to C-compatible string
 ///
 /// This function will consume the provided data and use the underlying bytes to construct a new
index 387d2b1524d22d9a1b58711bdf32fb8cdfe81b69..7e1094a39e907496c4cb732d69b54f8ef1415d98 100644 (file)
@@ -176,7 +176,6 @@ pub struct SuricataFileContext {
 /// cbindgen:ignore
 extern {
     pub fn SCGetContext() -> &'static mut SuricataContext;
-    pub fn SCLogGetLogLevel() -> i32;
 }
 
 pub static mut SC: Option<&'static SuricataContext> = None;
index 433dc4b5bf642f3f0fcfb475493bcfa5dbb61563..c8c377a3724e5acfb6f74bcc8828511413801e41 100644 (file)
@@ -1388,7 +1388,6 @@ pub unsafe extern "C" fn rs_dcerpc_register_parser() {
 #[cfg(test)]
 mod tests {
     use crate::applayer::AppLayerResult;
-    use crate::core::*;
     use crate::dcerpc::dcerpc::DCERPCState;
     use crate::direction::Direction;
     use std::cmp;
similarity index 61%
rename from rust/src/log.rs
rename to rust/src/debug.rs
index 7bf0be8a97c6350eeda296fd74e43c30656fdd32..caeecff93a680544dff53990256661ac5b2e6f26 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Open Information Security Foundation
+/* Copyright (C) 2017-2025 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
  * 02110-1301, USA.
  */
 
-//! Logging utility module.
+//! Logging and debug utilities, like util-debug.c.
 
-use std;
-use std::ffi::CString;
-use std::path::Path;
+use std::{ffi::CString, path::Path};
 
-use crate::core::*;
+use crate::core::SC;
+
+/// cbindgen:ignore
+extern {
+    pub fn SCLogGetLogLevel() -> i32;
+}
 
 #[derive(Debug)]
 #[repr(C)]
@@ -40,21 +43,13 @@ pub enum Level {
 
 pub static mut LEVEL: i32 = Level::NotSet as i32;
 
-pub fn get_log_level() -> i32 {
-    unsafe {
-        LEVEL
-    }
-}
-
-pub fn log_set_level(level: i32) {
-    unsafe {
-        LEVEL = level;
-    }
-}
-
+/// Set the Rust context's idea of the log level.
+///
+/// This will be called during Suricata initialization with the
+/// runtime log level.
 #[no_mangle]
-pub extern "C" fn rs_log_set_level(level: i32) {
-    log_set_level(level);
+pub unsafe extern "C" fn SCSetRustLogLevel(level: i32) {
+    LEVEL = level;
 }
 
 fn basename(filename: &str) -> &str {
@@ -67,17 +62,55 @@ fn basename(filename: &str) -> &str {
     return filename;
 }
 
-pub fn sclog(level: Level, file: &str, line: u32, function: &str,
-         message: &str)
-{
+pub fn sclog(level: Level, file: &str, line: u32, function: &str, message: &str) {
     let filename = basename(file);
     let noext = &filename[0..filename.len() - 3];
-    sc_log_message(level,
-                   filename,
-                   line,
-                   function,
-                   noext,
-                   message);
+    sc_log_message(level, filename, line, function, noext, message);
+}
+
+/// SCLogMessage wrapper. If the Suricata C context is not registered
+/// a more basic log format will be used (for example, when running
+/// Rust unit tests).
+pub fn sc_log_message(
+    level: Level, filename: &str, line: std::os::raw::c_uint, function: &str, module: &str,
+    message: &str,
+) -> std::os::raw::c_int {
+    unsafe {
+        if let Some(c) = SC {
+            return (c.SCLogMessage)(
+                level as i32,
+                to_safe_cstring(filename).as_ptr(),
+                line,
+                to_safe_cstring(function).as_ptr(),
+                to_safe_cstring(module).as_ptr(),
+                to_safe_cstring(message).as_ptr(),
+            );
+        }
+    }
+
+    // Fall back if the Suricata C context is not registered which is
+    // the case when Rust unit tests are running.
+    //
+    // We don't log the time right now as I don't think it can be done
+    // with Rust 1.7.0 without using an external crate. With Rust
+    // 1.8.0 and newer we can unix UNIX_EPOCH.elapsed() to get the
+    // unix time.
+    println!("{}:{} <{:?}> -- {}", filename, line, level, message);
+    return 0;
+}
+
+// Convert a &str into a CString by first stripping NUL bytes.
+fn to_safe_cstring(val: &str) -> CString {
+    let mut safe = Vec::with_capacity(val.len());
+    for c in val.as_bytes() {
+        if *c != 0 {
+            safe.push(*c);
+        }
+    }
+    match CString::new(safe) {
+        Ok(cstr) => cstr,
+        _ => CString::new("<failed to encode string>").unwrap(),
+    }
 }
 
 // This macro returns the function name.
@@ -86,23 +119,24 @@ pub fn sclog(level: Level, file: &str, line: u32, function: &str,
 // is released under the MIT license as there is currently no macro in Rust
 // to provide the function name.
 #[macro_export(local_inner_macros)]
-macro_rules!function {
+macro_rules! function {
     () => {{
-         // Okay, this is ugly, I get it. However, this is the best we can get on a stable rust.
-         fn __f() {}
-         fn type_name_of<T>(_: T) -> &'static str {
-             std::any::type_name::<T>()
-         }
-         let name = type_name_of(__f);
-         &name[..name.len() - 5]
-    }}
+        // Okay, this is ugly, I get it. However, this is the best we can get on a stable rust.
+        fn __f() {}
+        fn type_name_of<T>(_: T) -> &'static str {
+            std::any::type_name::<T>()
+        }
+        let name = type_name_of(__f);
+        &name[..name.len() - 5]
+    }};
 }
 
 #[macro_export]
 macro_rules!do_log {
     ($level:expr, $($arg:tt)*) => {
-        if $crate::log::get_log_level() >= $level as i32 {
-            $crate::log::sclog($level, file!(), line!(), $crate::function!(),
+        #[allow(unused_unsafe)]
+        if unsafe { $crate::debug::LEVEL } >= $level as i32 {
+            $crate::debug::sclog($level, file!(), line!(), $crate::function!(),
                   &(format!($($arg)*)));
         }
     }
@@ -111,42 +145,42 @@ macro_rules!do_log {
 #[macro_export]
 macro_rules!SCLogError {
     ($($arg:tt)*) => {
-        $crate::do_log!($crate::log::Level::Error, $($arg)*);
+        $crate::do_log!($crate::debug::Level::Error, $($arg)*);
     };
 }
 
 #[macro_export]
 macro_rules!SCLogWarning {
     ($($arg:tt)*) => {
-        $crate::do_log!($crate::log::Level::Warning, $($arg)*);
+        $crate::do_log!($crate::debug::Level::Warning, $($arg)*);
     };
 }
 
 #[macro_export]
 macro_rules!SCLogNotice {
     ($($arg:tt)*) => {
-        $crate::do_log!($crate::log::Level::Notice, $($arg)*);
+        $crate::do_log!($crate::debug::Level::Notice, $($arg)*);
     }
 }
 
 #[macro_export]
 macro_rules!SCLogInfo {
     ($($arg:tt)*) => {
-        $crate::do_log!($crate::log::Level::Info, $($arg)*);
+        $crate::do_log!($crate::debug::Level::Info, $($arg)*);
     }
 }
 
 #[macro_export]
 macro_rules!SCLogPerf {
     ($($arg:tt)*) => {
-        $crate::do_log!($crate::log::Level::Perf, $($arg)*);
+        $crate::do_log!($crate::debug::Level::Perf, $($arg)*);
     }
 }
 
 #[macro_export]
 macro_rules!SCLogConfig {
     ($($arg:tt)*) => {
-        $crate::do_log!($crate::log::Level::Config, $($arg)*);
+        $crate::do_log!($crate::debug::Level::Config, $($arg)*);
     }
 }
 
@@ -155,7 +189,7 @@ macro_rules!SCLogConfig {
 #[macro_export]
 macro_rules!SCLogDebug {
     ($($arg:tt)*) => {
-        do_log!($crate::log::Level::Debug, $($arg)*);
+        do_log!($crate::debug::Level::Debug, $($arg)*);
     }
 }
 
@@ -165,55 +199,40 @@ macro_rules!SCLogDebug {
 // about unused variables, but is otherwise the equivalent to a no-op.
 #[cfg(not(feature = "debug"))]
 #[macro_export]
-macro_rules!SCLogDebug {
-    ($($arg:tt)*) => ()
+macro_rules! SCLogDebug {
+    ($($arg:tt)*) => {};
 }
 
-/// SCLogMessage wrapper. If the Suricata C context is not registered
-/// a more basic log format will be used (for example, when running
-/// Rust unit tests).
-pub fn sc_log_message(level: Level,
-                      filename: &str,
-                      line: std::os::raw::c_uint,
-                      function: &str,
-                      module: &str,
-                      message: &str) -> std::os::raw::c_int
-{
-    unsafe {
-        if let Some(c) = SC {
-            return (c.SCLogMessage)(
-                level as i32,
-                to_safe_cstring(filename).as_ptr(),
-                line,
-                to_safe_cstring(function).as_ptr(),
-                to_safe_cstring(module).as_ptr(),
-                to_safe_cstring(message).as_ptr());
-        }
-    }
+#[cfg(not(feature = "debug-validate"))]
+#[macro_export]
+macro_rules! debug_validate_bug_on (
+  ($item:expr) => {};
+);
 
-    // Fall back if the Suricata C context is not registered which is
-    // the case when Rust unit tests are running.
-    //
-    // We don't log the time right now as I don't think it can be done
-    // with Rust 1.7.0 without using an external crate. With Rust
-    // 1.8.0 and newer we can unix UNIX_EPOCH.elapsed() to get the
-    // unix time.
-    println!("{}:{} <{:?}> -- {}", filename, line, level, message);
-    return 0;
-}
 
-// Convert a &str into a CString by first stripping NUL bytes.
-fn to_safe_cstring(val: &str) -> CString {
-    let mut safe = Vec::with_capacity(val.len());
-    for c in val.as_bytes() {
-        if *c != 0 {
-            safe.push(*c);
-        }
+#[cfg(feature = "debug-validate")]
+#[macro_export]
+macro_rules! debug_validate_bug_on (
+  ($item:expr) => {
+    if $item {
+        panic!("Condition check failed");
     }
-    match CString::new(safe) {
-        Ok(cstr) => cstr,
-        _ => {
-            CString::new("<failed to encode string>").unwrap()
-        }
+  };
+);
+
+#[cfg(not(feature = "debug-validate"))]
+#[macro_export]
+macro_rules! debug_validate_fail (
+  ($msg:expr) => {};
+);
+
+#[cfg(feature = "debug-validate")]
+#[macro_export]
+macro_rules! debug_validate_fail (
+  ($msg:expr) => {
+    // Wrap in a conditional to prevent unreachable code warning in caller.
+    if true {
+      panic!($msg);
     }
-}
+  };
+);
index 855ee11e29587549b8fd625299549cb8925a05ec..f28e4c249acefdd657b84a65f0d8c358a6bf84bd 100644 (file)
@@ -79,13 +79,12 @@ extern crate ldap_parser;
 #[macro_use]
 extern crate suricata_derive;
 
-#[macro_use]
-pub mod log;
-
 #[macro_use]
 pub mod core;
 
 #[macro_use]
+pub(crate) mod debug;
+
 pub mod common;
 pub mod conf;
 pub mod jsonbuilder;
index ad214aaa47f55930e55eba84390b8eeacd583efc..7f3758640846c99aa2805c29686cb2ad31e1be0b 100644 (file)
@@ -22,7 +22,6 @@ pub fn init() {
         let context = super::core::SCGetContext();
         super::core::init_ffi(context);
 
-        let level = super::core::SCLogGetLogLevel();
-        super::log::log_set_level(level);
+        super::debug::SCSetRustLogLevel(super::debug::SCLogGetLogLevel());
     }
 }
index f2a7b2dd212412dcf2e3d47534e7e5c35c5b64a3..56258a034f94605f0f971083f86ce8dcc7d0045c 100644 (file)
@@ -1414,7 +1414,7 @@ void SCLogInitLogModule(SCLogInitData *sc_lid)
 
     //SCOutputPrint(sc_did->startup_message);
 
-    rs_log_set_level(sc_log_global_log_level);
+    SCSetRustLogLevel(sc_log_global_log_level);
 }
 
 void SCLogLoadConfig(int daemon, int verbose, uint32_t userid, uint32_t groupid)