-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ticket: 4863 On the way, convert unit test DetectSNMPCommunityTest to a SV test. And also, make snmp.pdu_type use a generic uint32 for detection, allowing operators, instead of just equality.
- Loading branch information
1 parent
9781f20
commit cf0f30c
Showing
16 changed files
with
243 additions
and
834 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,42 +17,251 @@ | |
|
||
// written by Pierre Chifflier <[email protected]> | ||
|
||
use crate::snmp::snmp::SNMPTransaction; | ||
use super::snmp::{SNMPTransaction, ALPROTO_SNMP}; | ||
use crate::detect::uint::{ | ||
rs_detect_u32_free, rs_detect_u32_match, rs_detect_u32_parse, DetectUintData, | ||
}; | ||
use crate::detect::{ | ||
DetectBufferSetActiveList, DetectHelperBufferMpmRegister, DetectHelperBufferRegister, | ||
DetectHelperGetData, DetectHelperKeywordRegister, DetectSignatureSetAppProto, SCSigTableElmt, | ||
SigMatchAppendSMToList, SIGMATCH_INFO_STICKY_BUFFER, SIGMATCH_NOOPT, | ||
}; | ||
use std::os::raw::{c_int, c_void}; | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn rs_snmp_tx_get_version(tx: &mut SNMPTransaction, version: *mut u32) { | ||
debug_assert!(tx.version != 0, "SNMP version is 0"); | ||
*version = tx.version; | ||
static mut G_SNMP_VERSION_KW_ID: c_int = 0; | ||
static mut G_SNMP_VERSION_BUFFER_ID: c_int = 0; | ||
static mut G_SNMP_PDUTYPE_KW_ID: c_int = 0; | ||
static mut G_SNMP_PDUTYPE_BUFFER_ID: c_int = 0; | ||
static mut G_SNMP_USM_BUFFER_ID: c_int = 0; | ||
static mut G_SNMP_COMMUNITY_BUFFER_ID: c_int = 0; | ||
|
||
unsafe extern "C" fn snmp_detect_version_setup( | ||
de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, | ||
) -> c_int { | ||
if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { | ||
return -1; | ||
} | ||
let ctx = rs_detect_u32_parse(raw) as *mut c_void; | ||
if ctx.is_null() { | ||
return -1; | ||
} | ||
if SigMatchAppendSMToList(de, s, G_SNMP_VERSION_KW_ID, ctx, G_SNMP_VERSION_BUFFER_ID).is_null() | ||
{ | ||
snmp_detect_version_free(std::ptr::null_mut(), ctx); | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn rs_snmp_tx_get_community( | ||
tx: &mut SNMPTransaction, buf: *mut *const u8, len: *mut u32, | ||
) { | ||
if let Some(ref c) = tx.community { | ||
*buf = c.as_ptr(); | ||
*len = c.len() as u32; | ||
unsafe extern "C" fn snmp_detect_version_match( | ||
_de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, | ||
_sig: *const c_void, ctx: *const c_void, | ||
) -> c_int { | ||
let tx = cast_pointer!(tx, SNMPTransaction); | ||
let ctx = cast_pointer!(ctx, DetectUintData<u32>); | ||
return rs_detect_u32_match(tx.version, ctx); | ||
} | ||
|
||
unsafe extern "C" fn snmp_detect_version_free(_de: *mut c_void, ctx: *mut c_void) { | ||
// Just unbox... | ||
let ctx = cast_pointer!(ctx, DetectUintData<u32>); | ||
rs_detect_u32_free(ctx); | ||
} | ||
|
||
unsafe extern "C" fn snmp_detect_pdutype_setup( | ||
de: *mut c_void, s: *mut c_void, raw: *const libc::c_char, | ||
) -> c_int { | ||
if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { | ||
return -1; | ||
} | ||
let ctx = rs_detect_u32_parse(raw) as *mut c_void; | ||
if ctx.is_null() { | ||
return -1; | ||
} | ||
if SigMatchAppendSMToList(de, s, G_SNMP_PDUTYPE_KW_ID, ctx, G_SNMP_PDUTYPE_BUFFER_ID).is_null() | ||
{ | ||
snmp_detect_pdutype_free(std::ptr::null_mut(), ctx); | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn rs_snmp_tx_get_pdu_type(tx: &mut SNMPTransaction, pdu_type: *mut u32) { | ||
match tx.info { | ||
Some(ref info) => { | ||
*pdu_type = info.pdu_type.0; | ||
} | ||
None => { | ||
*pdu_type = 0xffffffff; | ||
} | ||
unsafe extern "C" fn snmp_detect_pdutype_match( | ||
_de: *mut c_void, _f: *mut c_void, _flags: u8, _state: *mut c_void, tx: *mut c_void, | ||
_sig: *const c_void, ctx: *const c_void, | ||
) -> c_int { | ||
let tx = cast_pointer!(tx, SNMPTransaction); | ||
let ctx = cast_pointer!(ctx, DetectUintData<u32>); | ||
if let Some(ref info) = tx.info { | ||
let pdu_type = info.pdu_type.0; | ||
return rs_detect_u32_match(pdu_type, ctx); | ||
} | ||
return 0; | ||
} | ||
|
||
unsafe extern "C" fn snmp_detect_pdutype_free(_de: *mut c_void, ctx: *mut c_void) { | ||
// Just unbox... | ||
let ctx = cast_pointer!(ctx, DetectUintData<u32>); | ||
rs_detect_u32_free(ctx); | ||
} | ||
|
||
pub unsafe extern "C" fn snmp_detect_usm_setup( | ||
de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, | ||
) -> c_int { | ||
if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { | ||
return -1; | ||
} | ||
if DetectBufferSetActiveList(de, s, G_SNMP_USM_BUFFER_ID) < 0 { | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
pub unsafe extern "C" fn snmp_detect_usm_get( | ||
tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, | ||
) -> bool { | ||
let tx = cast_pointer!(tx, SNMPTransaction); | ||
if let Some(ref c) = tx.usm { | ||
*buffer = c.as_ptr(); | ||
*buffer_len = c.len() as u32; | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
pub unsafe extern "C" fn snmp_detect_usm_get_data( | ||
de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, | ||
tx: *const c_void, list_id: c_int, | ||
) -> *mut c_void { | ||
return DetectHelperGetData( | ||
de, | ||
transforms, | ||
flow, | ||
flow_flags, | ||
tx, | ||
list_id, | ||
snmp_detect_usm_get, | ||
); | ||
} | ||
|
||
pub unsafe extern "C" fn snmp_detect_community_setup( | ||
de: *mut c_void, s: *mut c_void, _raw: *const std::os::raw::c_char, | ||
) -> c_int { | ||
if DetectSignatureSetAppProto(s, ALPROTO_SNMP) != 0 { | ||
return -1; | ||
} | ||
if DetectBufferSetActiveList(de, s, G_SNMP_COMMUNITY_BUFFER_ID) < 0 { | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
pub unsafe extern "C" fn snmp_detect_community_get( | ||
tx: *const c_void, _flow_flags: u8, buffer: *mut *const u8, buffer_len: *mut u32, | ||
) -> bool { | ||
let tx = cast_pointer!(tx, SNMPTransaction); | ||
if let Some(ref c) = tx.community { | ||
*buffer = c.as_ptr(); | ||
*buffer_len = c.len() as u32; | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
pub unsafe extern "C" fn snmp_detect_community_get_data( | ||
de: *mut c_void, transforms: *const c_void, flow: *const c_void, flow_flags: u8, | ||
tx: *const c_void, list_id: c_int, | ||
) -> *mut c_void { | ||
return DetectHelperGetData( | ||
de, | ||
transforms, | ||
flow, | ||
flow_flags, | ||
tx, | ||
list_id, | ||
snmp_detect_community_get, | ||
); | ||
} | ||
#[no_mangle] | ||
pub unsafe extern "C" fn rs_snmp_tx_get_usm( | ||
tx: &mut SNMPTransaction, buf: *mut *const u8, len: *mut u32, | ||
) { | ||
if let Some(ref c) = tx.usm { | ||
*buf = c.as_ptr(); | ||
*len = c.len() as u32; | ||
pub unsafe extern "C" fn ScDetectSNMPRegister() { | ||
let kw = SCSigTableElmt { | ||
name: b"snmp.version\0".as_ptr() as *const libc::c_char, | ||
desc: b"match SNMP version\0".as_ptr() as *const libc::c_char, | ||
url: b"/rules/snmp-keywords.html#snmp-version\0".as_ptr() as *const libc::c_char, | ||
AppLayerTxMatch: Some(snmp_detect_version_match), | ||
Setup: snmp_detect_version_setup, | ||
Free: Some(snmp_detect_version_free), | ||
flags: 0, | ||
}; | ||
unsafe { | ||
G_SNMP_VERSION_KW_ID = DetectHelperKeywordRegister(&kw); | ||
G_SNMP_VERSION_BUFFER_ID = DetectHelperBufferRegister( | ||
b"snmp.version\0".as_ptr() as *const libc::c_char, | ||
ALPROTO_SNMP, | ||
true, | ||
true, | ||
); | ||
} | ||
|
||
let kw = SCSigTableElmt { | ||
name: b"snmp.pdu_type\0".as_ptr() as *const libc::c_char, | ||
desc: b"match SNMP PDU type\0".as_ptr() as *const libc::c_char, | ||
url: b"/rules/snmp-keywords.html#snmp-pdu-type\0".as_ptr() as *const libc::c_char, | ||
AppLayerTxMatch: Some(snmp_detect_pdutype_match), | ||
Setup: snmp_detect_pdutype_setup, | ||
Free: Some(snmp_detect_pdutype_free), | ||
flags: 0, | ||
}; | ||
unsafe { | ||
G_SNMP_PDUTYPE_KW_ID = DetectHelperKeywordRegister(&kw); | ||
G_SNMP_PDUTYPE_BUFFER_ID = DetectHelperBufferRegister( | ||
b"snmp.pdu_type\0".as_ptr() as *const libc::c_char, | ||
ALPROTO_SNMP, | ||
true, | ||
true, | ||
); | ||
} | ||
|
||
let kw = SCSigTableElmt { | ||
name: b"snmp.usm\0".as_ptr() as *const libc::c_char, | ||
desc: b"SNMP content modifier to match on the SNMP usm\0".as_ptr() as *const libc::c_char, | ||
url: b"/rules/snmp-keywords.html#snmp-usm\0".as_ptr() as *const libc::c_char, | ||
Setup: snmp_detect_usm_setup, | ||
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER, | ||
AppLayerTxMatch: None, | ||
Free: None, | ||
}; | ||
unsafe { | ||
let _g_snmp_usm_kw_id = DetectHelperKeywordRegister(&kw); | ||
G_SNMP_USM_BUFFER_ID = DetectHelperBufferMpmRegister( | ||
b"snmp.usm\0".as_ptr() as *const libc::c_char, | ||
b"SNMP USM\0".as_ptr() as *const libc::c_char, | ||
ALPROTO_SNMP, | ||
true, | ||
true, | ||
snmp_detect_usm_get_data, | ||
); | ||
} | ||
|
||
let kw = SCSigTableElmt { | ||
name: b"snmp.community\0".as_ptr() as *const libc::c_char, | ||
desc: b"SNMP content modifier to match on the SNMP community\0".as_ptr() | ||
as *const libc::c_char, | ||
url: b"/rules/snmp-keywords.html#snmp-community\0".as_ptr() as *const libc::c_char, | ||
Setup: snmp_detect_community_setup, | ||
flags: SIGMATCH_NOOPT | SIGMATCH_INFO_STICKY_BUFFER, | ||
AppLayerTxMatch: None, | ||
Free: None, | ||
}; | ||
unsafe { | ||
let _g_snmp_community_kw_id = DetectHelperKeywordRegister(&kw); | ||
G_SNMP_COMMUNITY_BUFFER_ID = DetectHelperBufferMpmRegister( | ||
b"snmp.community\0".as_ptr() as *const libc::c_char, | ||
b"SNMP Community identifier\0".as_ptr() as *const libc::c_char, | ||
ALPROTO_SNMP, | ||
true, | ||
true, | ||
snmp_detect_community_get_data, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.