Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic alprotos : make SNMP totally dynamic #12402

Closed
37 changes: 37 additions & 0 deletions rust/src/applayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,12 +472,49 @@ pub type ApplyTxConfigFn = unsafe extern "C" fn (*mut c_void, *mut c_void, c_int
pub type GetFrameIdByName = unsafe extern "C" fn(*const c_char) -> c_int;
pub type GetFrameNameById = unsafe extern "C" fn(u8) -> *const c_char;

// Also defined in output-json.h
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasonish what do you think about this ?

I do not like to see this defined twice

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you get the C to use this? In some cases there will be no way around it, at least not without bindgen to output C types, and cbindgen to output Rust types. But currently some things just can't include "rust.h" to get the types as rust.h might have a dependency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you get the C to use this?

I did not manage

But currently some things just can't include "rust.h" to get the types as rust.h might have a dependency.

Indeed the problem

I will try again a bit more

/// cbindgen:ignore
#[repr(u8)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[allow(non_camel_case_types)]
pub enum OutputJsonLogDirection {
LOG_DIR_PACKET = 0,
LOG_DIR_FLOW = 1,
}

// Also defined in output.h
// canot use JsonBuilder as it is not #[repr(C)]
pub type EveJsonSimpleTxLogFunc = unsafe extern "C" fn(*const c_void, *mut c_void) -> bool;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should cbindgen export types that are function prototypes ?


// Also defined in output.h
#[repr(C)]
#[allow(non_snake_case)]
pub struct EveJsonTxLoggerRegistrationData {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like to see it defined twice neither

pub confname: *const c_char,
pub logname: *const c_char,
pub alproto: AppProto,
pub dir: u8,
pub LogTx: EveJsonSimpleTxLogFunc,
}

// Defined in output.h
/// cbindgen:ignore
extern {
pub fn OutputPreRegisterLogger(reg_data: EveJsonTxLoggerRegistrationData) -> c_int;
}

// Defined in detect-engine-register.h
/// cbindgen:ignore
extern {
pub fn SigTablePreRegister(cb: unsafe extern "C" fn ());
}

// Defined in app-layer-register.h
/// cbindgen:ignore
extern {
pub fn AppLayerRegisterProtocolDetection(parser: *const RustParser, enable_default: c_int) -> AppProto;
pub fn AppLayerRegisterParserAlias(parser_name: *const c_char, alias_name: *const c_char);
pub fn AppProtoNewProtoFromString(name: *const c_char) -> AppProto;
}

#[allow(non_snake_case)]
Expand Down
4 changes: 2 additions & 2 deletions rust/src/dns/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ pub extern "C" fn SCDnsLogJsonQuery(
/// "dns" object.
///
/// This logger implements V3 style DNS logging.
fn log_json(tx: &mut DNSTransaction, flags: u64, jb: &mut JsonBuilder) -> Result<(), JsonError> {
fn log_json(tx: &DNSTransaction, flags: u64, jb: &mut JsonBuilder) -> Result<(), JsonError> {
jb.open_object("dns")?;
jb.set_int("version", 3)?;

Expand Down Expand Up @@ -921,7 +921,7 @@ fn log_json(tx: &mut DNSTransaction, flags: u64, jb: &mut JsonBuilder) -> Result

/// FFI wrapper around the common V3 style DNS logger.
#[no_mangle]
pub extern "C" fn SCDnsLogJson(tx: &mut DNSTransaction, flags: u64, jb: &mut JsonBuilder) -> bool {
pub extern "C" fn SCDnsLogJson(tx: &DNSTransaction, flags: u64, jb: &mut JsonBuilder) -> bool {
log_json(tx, flags, jb).is_ok()
}

Expand Down
4 changes: 2 additions & 2 deletions rust/src/krb/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use crate::jsonbuilder::{JsonBuilder, JsonError};
use crate::krb::krb5::{KRB5Transaction,test_weak_encryption};

fn krb5_log_response(jsb: &mut JsonBuilder, tx: &mut KRB5Transaction) -> Result<(), JsonError>
fn krb5_log_response(jsb: &mut JsonBuilder, tx: &KRB5Transaction) -> Result<(), JsonError>
{
jsb.open_object("krb5")?;
match tx.error_code {
Expand Down Expand Up @@ -70,7 +70,7 @@ fn krb5_log_response(jsb: &mut JsonBuilder, tx: &mut KRB5Transaction) -> Result<
}

#[no_mangle]
pub extern "C" fn rs_krb5_log_json_response(tx: &mut KRB5Transaction, jsb: &mut JsonBuilder) -> bool
pub extern "C" fn rs_krb5_log_json_response(tx: &KRB5Transaction, jsb: &mut JsonBuilder) -> bool
{
krb5_log_response(jsb, tx).is_ok()
}
26 changes: 13 additions & 13 deletions rust/src/mime/smtp_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use digest::Update;
use md5::Md5;
use std::ffi::CStr;

fn log_subject_md5(js: &mut JsonBuilder, ctx: &mut MimeStateSMTP) -> Result<(), JsonError> {
fn log_subject_md5(js: &mut JsonBuilder, ctx: &MimeStateSMTP) -> Result<(), JsonError> {
for h in &ctx.headers[..ctx.main_headers_nb] {
if mime::slice_equals_lowercase(&h.name, b"subject") {
let hash = format!("{:x}", Md5::new().chain(&h.value).finalize());
Expand All @@ -36,12 +36,12 @@ fn log_subject_md5(js: &mut JsonBuilder, ctx: &mut MimeStateSMTP) -> Result<(),

#[no_mangle]
pub unsafe extern "C" fn SCMimeSmtpLogSubjectMd5(
js: &mut JsonBuilder, ctx: &mut MimeStateSMTP,
js: &mut JsonBuilder, ctx: &MimeStateSMTP,
) -> bool {
return log_subject_md5(js, ctx).is_ok();
}

fn log_body_md5(js: &mut JsonBuilder, ctx: &mut MimeStateSMTP) -> Result<(), JsonError> {
fn log_body_md5(js: &mut JsonBuilder, ctx: &MimeStateSMTP) -> Result<(), JsonError> {
if ctx.md5_state == MimeSmtpMd5State::MimeSmtpMd5Completed {
let hash = format!("{:x}", ctx.md5_result);
js.set_string("body_md5", &hash)?;
Expand All @@ -51,13 +51,13 @@ fn log_body_md5(js: &mut JsonBuilder, ctx: &mut MimeStateSMTP) -> Result<(), Jso

#[no_mangle]
pub unsafe extern "C" fn SCMimeSmtpLogBodyMd5(
js: &mut JsonBuilder, ctx: &mut MimeStateSMTP,
js: &mut JsonBuilder, ctx: &MimeStateSMTP,
) -> bool {
return log_body_md5(js, ctx).is_ok();
}

fn log_field_array(
js: &mut JsonBuilder, ctx: &mut MimeStateSMTP, c: &str, e: &str,
js: &mut JsonBuilder, ctx: &MimeStateSMTP, c: &str, e: &str,
) -> Result<(), JsonError> {
let mark = js.get_mark();
let mut found = false;
Expand All @@ -81,7 +81,7 @@ fn log_field_array(

#[no_mangle]
pub unsafe extern "C" fn SCMimeSmtpLogFieldArray(
js: &mut JsonBuilder, ctx: &mut MimeStateSMTP, email: *const std::os::raw::c_char,
js: &mut JsonBuilder, ctx: &MimeStateSMTP, email: *const std::os::raw::c_char,
config: *const std::os::raw::c_char,
) -> bool {
let e: &CStr = CStr::from_ptr(email); //unsafe
Expand All @@ -101,7 +101,7 @@ enum FieldCommaState {
}

fn log_field_comma(
js: &mut JsonBuilder, ctx: &mut MimeStateSMTP, c: &str, e: &str,
js: &mut JsonBuilder, ctx: &MimeStateSMTP, c: &str, e: &str,
) -> Result<(), JsonError> {
for h in &ctx.headers[..ctx.main_headers_nb] {
if mime::slice_equals_lowercase(&h.name, e.as_bytes()) {
Expand Down Expand Up @@ -158,7 +158,7 @@ fn log_field_comma(

#[no_mangle]
pub unsafe extern "C" fn SCMimeSmtpLogFieldComma(
js: &mut JsonBuilder, ctx: &mut MimeStateSMTP, email: *const std::os::raw::c_char,
js: &mut JsonBuilder, ctx: &MimeStateSMTP, email: *const std::os::raw::c_char,
config: *const std::os::raw::c_char,
) -> bool {
let e: &CStr = CStr::from_ptr(email); //unsafe
Expand All @@ -172,7 +172,7 @@ pub unsafe extern "C" fn SCMimeSmtpLogFieldComma(
}

fn log_field_string(
js: &mut JsonBuilder, ctx: &mut MimeStateSMTP, c: &str, e: &str,
js: &mut JsonBuilder, ctx: &MimeStateSMTP, c: &str, e: &str,
) -> Result<(), JsonError> {
for h in &ctx.headers[..ctx.main_headers_nb] {
if mime::slice_equals_lowercase(&h.name, e.as_bytes()) {
Expand All @@ -185,7 +185,7 @@ fn log_field_string(

#[no_mangle]
pub unsafe extern "C" fn SCMimeSmtpLogFieldString(
js: &mut JsonBuilder, ctx: &mut MimeStateSMTP, email: *const std::os::raw::c_char,
js: &mut JsonBuilder, ctx: &MimeStateSMTP, email: *const std::os::raw::c_char,
config: *const std::os::raw::c_char,
) -> bool {
let e: &CStr = CStr::from_ptr(email); //unsafe
Expand All @@ -199,7 +199,7 @@ pub unsafe extern "C" fn SCMimeSmtpLogFieldString(
}

fn log_data_header(
js: &mut JsonBuilder, ctx: &mut MimeStateSMTP, hname: &str,
js: &mut JsonBuilder, ctx: &MimeStateSMTP, hname: &str,
) -> Result<(), JsonError> {
for h in &ctx.headers[..ctx.main_headers_nb] {
if mime::slice_equals_lowercase(&h.name, hname.as_bytes()) {
Expand All @@ -210,7 +210,7 @@ fn log_data_header(
return Ok(());
}

fn log_data(js: &mut JsonBuilder, ctx: &mut MimeStateSMTP) -> Result<(), JsonError> {
fn log_data(js: &mut JsonBuilder, ctx: &MimeStateSMTP) -> Result<(), JsonError> {
log_data_header(js, ctx, "from")?;
log_field_comma(js, ctx, "to", "to")?;
log_field_comma(js, ctx, "cc", "cc")?;
Expand All @@ -236,6 +236,6 @@ fn log_data(js: &mut JsonBuilder, ctx: &mut MimeStateSMTP) -> Result<(), JsonErr
}

#[no_mangle]
pub unsafe extern "C" fn SCMimeSmtpLogData(js: &mut JsonBuilder, ctx: &mut MimeStateSMTP) -> bool {
pub unsafe extern "C" fn SCMimeSmtpLogData(js: &mut JsonBuilder, ctx: &MimeStateSMTP) -> bool {
return log_data(js, ctx).is_ok();
}
2 changes: 1 addition & 1 deletion rust/src/modbus/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::jsonbuilder::{JsonBuilder, JsonError};
use sawp_modbus::{Data, Message, Read, Write};

#[no_mangle]
pub extern "C" fn rs_modbus_to_json(tx: &mut ModbusTransaction, js: &mut JsonBuilder) -> bool {
pub extern "C" fn rs_modbus_to_json(tx: &ModbusTransaction, js: &mut JsonBuilder) -> bool {
log(tx, js).is_ok()
}

Expand Down
8 changes: 4 additions & 4 deletions rust/src/nfs/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crc::crc32;

#[no_mangle]
pub extern "C" fn rs_nfs_tx_logging_is_filtered(state: &mut NFSState,
tx: &mut NFSTransaction)
tx: &NFSTransaction)
-> u8
{
// TODO probably best to make this configurable
Expand Down Expand Up @@ -119,7 +119,7 @@ fn nfs_log_request(state: &NFSState, tx: &NFSTransaction, js: &mut JsonBuilder)
}

#[no_mangle]
pub extern "C" fn rs_nfs_log_json_request(state: &mut NFSState, tx: &mut NFSTransaction,
pub extern "C" fn rs_nfs_log_json_request(state: &mut NFSState, tx: &NFSTransaction,
js: &mut JsonBuilder) -> bool
{
nfs_log_request(state, tx, js).is_ok()
Expand Down Expand Up @@ -152,7 +152,7 @@ fn nfs_log_response(state: &NFSState, tx: &NFSTransaction, js: &mut JsonBuilder)
}

#[no_mangle]
pub extern "C" fn rs_nfs_log_json_response(state: &mut NFSState, tx: &mut NFSTransaction,
pub extern "C" fn rs_nfs_log_json_response(state: &mut NFSState, tx: &NFSTransaction,
js: &mut JsonBuilder) -> bool
{
nfs_log_response(state, tx, js).is_ok()
Expand All @@ -173,7 +173,7 @@ fn rpc_log_response(tx: &NFSTransaction, js: &mut JsonBuilder)
}

#[no_mangle]
pub extern "C" fn rs_rpc_log_json_response(tx: &mut NFSTransaction,
pub extern "C" fn rs_rpc_log_json_response(tx: &NFSTransaction,
js: &mut JsonBuilder) -> bool
{
rpc_log_response(tx, js).is_ok()
Expand Down
2 changes: 1 addition & 1 deletion rust/src/rdp/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::rdp::windows;
use x509_parser::prelude::{X509Certificate, FromDer};

#[no_mangle]
pub extern "C" fn rs_rdp_to_json(tx: &mut RdpTransaction, js: &mut JsonBuilder) -> bool {
pub extern "C" fn rs_rdp_to_json(tx: &RdpTransaction, js: &mut JsonBuilder) -> bool {
log(tx, js).is_ok()
}

Expand Down
2 changes: 1 addition & 1 deletion rust/src/sip/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ fn log(tx: &SIPTransaction, js: &mut JsonBuilder) -> Result<(), JsonError> {
}

#[no_mangle]
pub extern "C" fn rs_sip_log_json(tx: &mut SIPTransaction, js: &mut JsonBuilder) -> bool {
pub extern "C" fn rs_sip_log_json(tx: &SIPTransaction, js: &mut JsonBuilder) -> bool {
log(tx, js).is_ok()
}
4 changes: 2 additions & 2 deletions rust/src/smb/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,13 +445,13 @@ fn smb_common_header(jsb: &mut JsonBuilder, state: &SMBState, tx: &SMBTransactio
}

#[no_mangle]
pub extern "C" fn rs_smb_log_json_request(jsb: &mut JsonBuilder, state: &mut SMBState, tx: &mut SMBTransaction) -> bool
pub extern "C" fn rs_smb_log_json_request(jsb: &mut JsonBuilder, state: &mut SMBState, tx: &SMBTransaction) -> bool
{
smb_common_header(jsb, state, tx).is_ok()
}

#[no_mangle]
pub extern "C" fn rs_smb_log_json_response(jsb: &mut JsonBuilder, state: &mut SMBState, tx: &mut SMBTransaction) -> bool
pub extern "C" fn rs_smb_log_json_response(jsb: &mut JsonBuilder, state: &mut SMBState, tx: &SMBTransaction) -> bool
{
smb_common_header(jsb, state, tx).is_ok()
}
Expand Down
6 changes: 4 additions & 2 deletions rust/src/snmp/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn str_of_pdu_type(t:&PduType) -> Cow<str> {
}
}

fn snmp_log_response(jsb: &mut JsonBuilder, tx: &mut SNMPTransaction) -> Result<(), JsonError>
fn snmp_log_response(jsb: &mut JsonBuilder, tx: &SNMPTransaction) -> Result<(), JsonError>
{
jsb.open_object("snmp")?;
jsb.set_uint("version", tx.version as u64)?;
Expand Down Expand Up @@ -77,7 +77,9 @@ fn snmp_log_response(jsb: &mut JsonBuilder, tx: &mut SNMPTransaction) -> Result<
}

#[no_mangle]
pub extern "C" fn rs_snmp_log_json_response(tx: &mut SNMPTransaction, jsb: &mut JsonBuilder) -> bool
pub unsafe extern "C" fn rs_snmp_log_json_response(tx: *const std::os::raw::c_void, jsb: *mut std::os::raw::c_void) -> bool
{
let tx = cast_pointer!(tx, SNMPTransaction);
let jsb = cast_pointer!(jsb, JsonBuilder);
snmp_log_response(jsb, tx).is_ok()
}
20 changes: 15 additions & 5 deletions rust/src/snmp/snmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
use crate::snmp::snmp_parser::*;
use crate::core::{self, *};
use crate::applayer::{self, *};
use super::log::rs_snmp_log_json_response;
use super::detect::ScDetectSNMPRegister;
use std;
use std::ffi::CString;

Expand Down Expand Up @@ -410,20 +412,28 @@ pub unsafe extern "C" fn rs_register_snmp_parser() {
get_frame_name_by_id: None,
};
let ip_proto_str = CString::new("udp").unwrap();
ALPROTO_SNMP = AppProtoNewProtoFromString(PARSER_NAME.as_ptr() as *const std::os::raw::c_char);
let reg_data = EveJsonTxLoggerRegistrationData {
confname: b"eve-log.snmp\0".as_ptr() as *const std::os::raw::c_char,
logname: b"JsonSNMPLog\0".as_ptr() as *const std::os::raw::c_char,
alproto: ALPROTO_SNMP,
dir: OutputJsonLogDirection::LOG_DIR_PACKET as u8,
LogTx: rs_snmp_log_json_response,
};
OutputPreRegisterLogger(reg_data);
SigTablePreRegister(ScDetectSNMPRegister);
if AppLayerProtoDetectConfProtoDetectionEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
// port 161
let alproto = AppLayerRegisterProtocolDetection(&parser, 1);
// store the allocated ID for the probe function
ALPROTO_SNMP = alproto;
_ = AppLayerRegisterProtocolDetection(&parser, 1);
if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
let _ = AppLayerRegisterParser(&parser, alproto);
let _ = AppLayerRegisterParser(&parser, ALPROTO_SNMP);
}
// port 162
let default_port_traps = CString::new("162").unwrap();
parser.default_port = default_port_traps.as_ptr();
let _ = AppLayerRegisterProtocolDetection(&parser, 1);
if AppLayerParserConfParserEnabled(ip_proto_str.as_ptr(), parser.name) != 0 {
let _ = AppLayerRegisterParser(&parser, alproto);
let _ = AppLayerRegisterParser(&parser, ALPROTO_SNMP);
}
AppLayerParserRegisterLogger(IPPROTO_UDP, ALPROTO_SNMP);
} else {
Expand Down
4 changes: 2 additions & 2 deletions rust/src/tftp/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use crate::jsonbuilder::{JsonBuilder, JsonError};
use crate::tftp::tftp::TFTPTransaction;

fn tftp_log_request(tx: &mut TFTPTransaction,
fn tftp_log_request(tx: &TFTPTransaction,
jb: &mut JsonBuilder)
-> Result<(), JsonError>
{
Expand All @@ -37,7 +37,7 @@ fn tftp_log_request(tx: &mut TFTPTransaction,
}

#[no_mangle]
pub extern "C" fn rs_tftp_log_json_request(tx: &mut TFTPTransaction,
pub extern "C" fn rs_tftp_log_json_request(tx: &TFTPTransaction,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasonish thoughts about this ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks OK.

jb: &mut JsonBuilder)
-> bool
{
Expand Down
Loading
Loading