@ -20,8 +20,8 @@
use crate ::core ::{ STREAM_TOCLIENT , STREAM_TOSERVER } ;
use crate ::detect ::uint ::{
detect_match_uint , detect_parse_array_uint_enum , detect_parse_uint_bitflags ,
detect_uint_match_at_index , Detect UintArrayData, DetectUintData , SCDetectU8Free ,
SCDetectU8 Parse,
detect_uint_match_at_index , Detect BitflagModifier, Detect UintArrayData, DetectUintData ,
SCDetectU8 Free, SCDetectU8 Parse,
} ;
use crate ::detect ::{
helper_keyword_register_multi_buffer , helper_keyword_register_sticky_buffer ,
@ -674,12 +674,16 @@ pub enum MqttFlag {
Retain = 0x1 ,
}
fn mqtt_flags_parse ( s : & str ) -> Option < DetectUintData < u8 > > {
detect_parse_uint_bitflags ::< u8 , MqttFlag > ( s , DetectBitflagModifier ::Plus , false )
}
unsafe extern "C" fn mqtt_parse_flags (
ustr : * const std ::os ::raw ::c_char ,
) -> * mut DetectUintData < u8 > {
let ft_name : & CStr = CStr ::from_ptr ( ustr ) ; //unsafe
if let Ok ( s ) = ft_name . to_str ( ) {
if let Some ( ctx ) = detect_parse_uint_bitflags::< u8 , MqttFlag > ( s ) {
if let Some ( ctx ) = mqtt_flags_parse ( s ) {
let boxed = Box ::new ( ctx ) ;
return Box ::into_raw ( boxed ) as * mut _ ;
}
@ -753,12 +757,16 @@ pub enum MqttConnFlag {
Clean_session = 0x2 ,
}
fn mqtt_connflags_parse ( s : & str ) -> Option < DetectUintData < u8 > > {
detect_parse_uint_bitflags ::< u8 , MqttConnFlag > ( s , DetectBitflagModifier ::Plus , false )
}
unsafe extern "C" fn mqtt_parse_conn_flags (
ustr : * const std ::os ::raw ::c_char ,
) -> * mut DetectUintData < u8 > {
let ft_name : & CStr = CStr ::from_ptr ( ustr ) ; //unsafe
if let Ok ( s ) = ft_name . to_str ( ) {
if let Some ( ctx ) = detect_parse_uint_bitflags::< u8 , MqttConnFlag > ( s ) {
if let Some ( ctx ) = mqtt_connflags_parse ( s ) {
let boxed = Box ::new ( ctx ) ;
return Box ::into_raw ( boxed ) as * mut _ ;
}
@ -1191,60 +1199,49 @@ mod test {
#[ test ]
fn mqtt_parse_flags ( ) {
let ctx = detect_parse_uint_bitflags::< u8 , MqttFlag > ( "retain" ) . unwrap ( ) ;
let ctx = mqtt_flags_parse ( "retain" ) . unwrap ( ) ;
assert_eq! ( ctx . arg1 , 1 ) ;
assert_eq! ( ctx . arg2 , 1 ) ;
let ctx = detect_parse_uint_bitflags::< u8 , MqttFlag > ( "dup" ) . unwrap ( ) ;
let ctx = mqtt_flags_parse ( "dup" ) . unwrap ( ) ;
assert_eq! ( ctx . arg1 , 8 ) ;
assert_eq! ( ctx . arg2 , 8 ) ;
let ctx = detect_parse_uint_bitflags::< u8 , MqttFlag > ( "retain,dup" ) . unwrap ( ) ;
let ctx = mqtt_flags_parse ( "retain,dup" ) . unwrap ( ) ;
assert_eq! ( ctx . arg1 , 8 | 1 ) ;
assert_eq! ( ctx . arg2 , 8 | 1 ) ;
let ctx = detect_parse_uint_bitflags::< u8 , MqttFlag > ( "dup, retain" ) . unwrap ( ) ;
let ctx = mqtt_flags_parse ( "dup, retain" ) . unwrap ( ) ;
assert_eq! ( ctx . arg1 , 8 | 1 ) ;
assert_eq! ( ctx . arg2 , 8 | 1 ) ;
let ctx = detect_parse_uint_bitflags::< u8 , MqttFlag > ( "retain,!dup" ) . unwrap ( ) ;
let ctx = mqtt_flags_parse ( "retain,!dup" ) . unwrap ( ) ;
assert_eq! ( ctx . arg1 , 1 | 8 ) ;
assert_eq! ( ctx . arg2 , 1 ) ;
assert! ( detect_parse_uint_bitflags::< u8 , MqttFlag > ( "ref" ) . is_none ( ) ) ;
assert! ( detect_parse_uint_bitflags::< u8 , MqttFlag > ( "dup,!" ) . is_none ( ) ) ;
assert! ( detect_parse_uint_bitflags::< u8 , MqttFlag > ( "dup,!dup" ) . is_none ( ) ) ;
assert! ( detect_parse_uint_bitflags::< u8 , MqttFlag > ( "!retain,retain" ) . is_none ( ) ) ;
assert! ( mqtt_flags_parse ( "ref" ) . is_none ( ) ) ;
assert! ( mqtt_flags_parse ( "dup,!" ) . is_none ( ) ) ;
assert! ( mqtt_flags_parse( "dup,!dup" , ) . is_none ( ) ) ;
assert! ( mqtt_flags_parse( "!retain,retain" , ) . is_none ( ) ) ;
}
#[ test ]
fn mqtt_parse_conn_flags ( ) {
let ctx = detect_parse_uint_bitflags::< u8 , MqttConnFlag > ( "username" ) . unwrap ( ) ;
let ctx = mqtt_connflags_parse ( "username" ) . unwrap ( ) ;
assert_eq! ( ctx . arg1 , 0x80 ) ;
assert_eq! ( ctx . arg2 , 0x80 ) ;
let ctx = detect_parse_uint_bitflags ::< u8 , MqttConnFlag > (
"username,password,will,will_retain,clean_session" ,
)
. unwrap ( ) ;
let ctx = mqtt_connflags_parse ( "username,password,will,will_retain,clean_session" ) . unwrap ( ) ;
assert_eq! ( ctx . arg1 , 0xE6 ) ;
assert_eq! ( ctx . arg2 , 0xE6 ) ;
let ctx = detect_parse_uint_bitflags ::< u8 , MqttConnFlag > (
"!username,!password,!will,!will_retain,!clean_session" ,
)
. unwrap ( ) ;
let ctx =
mqtt_connflags_parse ( "!username,!password,!will,!will_retain,!clean_session" ) . unwrap ( ) ;
assert_eq! ( ctx . arg1 , 0xE6 ) ;
assert_eq! ( ctx . arg2 , 0 ) ;
let ctx = detect_parse_uint_bitflags::< u8 , MqttConnFlag > ( " username,password" ) . unwrap ( ) ;
let ctx = mqtt_connflags_parse ( " username,password" ) . unwrap ( ) ;
assert_eq! ( ctx . arg1 , 0xC0 ) ;
assert_eq! ( ctx . arg2 , 0xC0 ) ;
assert! ( detect_parse_uint_bitflags ::< u8 , MqttConnFlag > ( "foobar" ) . is_none ( ) ) ;
assert! ( detect_parse_uint_bitflags ::< u8 , MqttConnFlag > ( "will,!" ) . is_none ( ) ) ;
assert! ( detect_parse_uint_bitflags ::< u8 , MqttConnFlag > ( "" ) . is_none ( ) ) ;
assert! ( detect_parse_uint_bitflags ::< u8 , MqttConnFlag > ( "username, username" ) . is_none ( ) ) ;
assert! ( detect_parse_uint_bitflags ::< u8 , MqttConnFlag > ( "!username, username" ) . is_none ( ) ) ;
assert! (
detect_parse_uint_bitflags ::< u8 , MqttConnFlag > ( "!username,password,!password" )
. is_none ( )
) ;
assert! ( detect_parse_uint_bitflags ::< u8 , MqttConnFlag > (
"will, username,password, !will, will"
)
. is_none ( ) ) ;
assert! ( mqtt_connflags_parse ( "foobar" ) . is_none ( ) ) ;
assert! ( mqtt_connflags_parse ( "will,!" ) . is_none ( ) ) ;
assert! ( mqtt_connflags_parse ( "" ) . is_none ( ) ) ;
assert! ( mqtt_connflags_parse ( "username, username" ) . is_none ( ) ) ;
assert! ( mqtt_connflags_parse ( "!username, username" ) . is_none ( ) ) ;
assert! ( mqtt_connflags_parse ( "!username,password,!password" ) . is_none ( ) ) ;
assert! ( mqtt_connflags_parse ( "will, username,password, !will, will" , ) . is_none ( ) ) ;
}
#[ test ]