@@ -21,7 +21,7 @@ use crate::core::{STREAM_TOCLIENT, STREAM_TOSERVER};
2121use crate :: detect:: uint:: {
2222 detect_match_uint, detect_parse_array_uint_enum, detect_parse_uint_bitflags,
2323 detect_uint_match_at_index, DetectBitflagModifier , DetectUintArrayData , DetectUintData ,
24- SCDetectU8Free , SCDetectU8Parse ,
24+ DetectUintIndex , SCDetectU8ArrayFree , SCDetectU8ArrayParse , SCDetectU8Free , SCDetectU8Parse ,
2525} ;
2626use crate :: detect:: {
2727 helper_keyword_register_multi_buffer, helper_keyword_register_sticky_buffer,
@@ -440,7 +440,7 @@ unsafe extern "C" fn mqtt_reason_code_setup(
440440 if SCDetectSignatureSetAppProto ( s, ALPROTO_MQTT ) != 0 {
441441 return -1 ;
442442 }
443- let ctx = SCDetectU8Parse ( raw) as * mut c_void ;
443+ let ctx = SCDetectU8ArrayParse ( raw) as * mut c_void ;
444444 if ctx. is_null ( ) {
445445 return -1 ;
446446 }
@@ -464,19 +464,61 @@ unsafe extern "C" fn mqtt_reason_code_match(
464464 tx : * mut c_void , _sig : * const Signature , ctx : * const SigMatchCtx ,
465465) -> c_int {
466466 let tx = cast_pointer ! ( tx, MQTTTransaction ) ;
467- let ctx = cast_pointer ! ( ctx, DetectUintData <u8 >) ;
467+ let ctx = cast_pointer ! ( ctx, DetectUintArrayData <u8 >) ;
468+ if ctx. index != DetectUintIndex :: Any {
469+ let mut vals = Vec :: new ( ) ;
470+ for msg in tx. msg . iter ( ) {
471+ match msg. op {
472+ MQTTOperation :: PUBACK ( ref v)
473+ | MQTTOperation :: PUBREL ( ref v)
474+ | MQTTOperation :: PUBREC ( ref v)
475+ | MQTTOperation :: PUBCOMP ( ref v) => {
476+ if let Some ( rcode) = v. reason_code {
477+ vals. push ( rcode) ;
478+ }
479+ }
480+ MQTTOperation :: AUTH ( ref v) => {
481+ vals. push ( v. reason_code ) ;
482+ }
483+ MQTTOperation :: CONNACK ( ref v) => {
484+ vals. push ( v. return_code ) ;
485+ }
486+ MQTTOperation :: DISCONNECT ( ref v) => {
487+ if let Some ( rcode) = v. reason_code {
488+ vals. push ( rcode) ;
489+ }
490+ }
491+ MQTTOperation :: UNSUBACK ( ref unsuback) => {
492+ if let Some ( ref reason_codes) = unsuback. reason_codes {
493+ for rc in reason_codes. iter ( ) {
494+ vals. push ( * rc) ;
495+ }
496+ }
497+ }
498+ MQTTOperation :: SUBACK ( ref suback) => {
499+ // in SUBACK these are stored as "QOS granted" historically
500+ for rc in suback. qoss . iter ( ) {
501+ vals. push ( * rc) ;
502+ }
503+ }
504+ _ => { }
505+ }
506+ }
507+
508+ return detect_uint_match_at_index :: < u8 , u8 > ( & vals, ctx, |v| Some ( * v) , tx. complete ) ;
509+ }
468510 if let Some ( v) = mqtt_tx_get_reason_code ( tx) {
469- if detect_match_uint ( ctx, v) {
511+ if detect_match_uint ( & ctx. du , v) {
470512 return 1 ;
471513 }
472514 }
473- return mqtt_tx_suback_unsuback_has_reason_code ( tx, ctx) ;
515+ return mqtt_tx_suback_unsuback_has_reason_code ( tx, & ctx. du ) ;
474516}
475517
476518unsafe extern "C" fn mqtt_reason_code_free ( _de : * mut DetectEngineCtx , ctx : * mut c_void ) {
477519 // Just unbox...
478- let ctx = cast_pointer ! ( ctx, DetectUintData <u8 >) ;
479- SCDetectU8Free ( ctx) ;
520+ let ctx = cast_pointer ! ( ctx, DetectUintArrayData <u8 >) ;
521+ SCDetectU8ArrayFree ( ctx) ;
480522}
481523
482524unsafe extern "C" fn mqtt_parse_qos ( ustr : * const std:: os:: raw:: c_char ) -> * mut u8 {
0 commit comments