@@ -38,6 +38,8 @@ pub enum DetectUintMode {
3838 DetectUintModeRange ,
3939 DetectUintModeNe ,
4040 DetectUintModeNegRg ,
41+ DetectUintModeBitmask ,
42+ DetectUintModeNegBitmask ,
4143}
4244
4345#[ derive( Debug ) ]
@@ -173,6 +175,37 @@ pub fn detect_parse_uint_start_interval<T: DetectIntType>(
173175 ) )
174176}
175177
178+ pub fn detect_parse_uint_bitmask < T : DetectIntType > (
179+ i : & str ,
180+ ) -> IResult < & str , DetectUintData < T > > {
181+ let ( i, _) = opt ( is_a ( " " ) ) ( i) ?;
182+ let ( i, _) = tag ( "&" ) ( i) ?;
183+ let ( i, _) = opt ( is_a ( " " ) ) ( i) ?;
184+ let ( i, arg1) = detect_parse_uint_value ( i) ?;
185+ let ( i, _) = opt ( is_a ( " " ) ) ( i) ?;
186+ let ( i, neg) = opt ( tag ( "!" ) ) ( i) ?;
187+ let ( i, _) = tag ( "=" ) ( i) ?;
188+ let ( i, _) = opt ( is_a ( " " ) ) ( i) ?;
189+ let ( i, arg2) = detect_parse_uint_value ( i) ?;
190+ if arg2 & arg1 != arg2 {
191+ // could never match
192+ return Err ( Err :: Error ( make_error ( i, ErrorKind :: Verify ) ) ) ;
193+ }
194+ let mode = if neg. is_none ( ) {
195+ DetectUintMode :: DetectUintModeBitmask
196+ } else {
197+ DetectUintMode :: DetectUintModeNegBitmask
198+ } ;
199+ Ok ( (
200+ i,
201+ DetectUintData {
202+ arg1,
203+ arg2,
204+ mode,
205+ } ,
206+ ) )
207+ }
208+
176209fn detect_parse_uint_start_interval_inclusive < T : DetectIntType > (
177210 i : & str ,
178211) -> IResult < & str , DetectUintData < T > > {
@@ -298,13 +331,24 @@ pub fn detect_match_uint<T: DetectIntType>(x: &DetectUintData<T>, val: T) -> boo
298331 return true ;
299332 }
300333 }
334+ DetectUintMode :: DetectUintModeBitmask => {
335+ if val & x. arg1 == x. arg2 {
336+ return true ;
337+ }
338+ }
339+ DetectUintMode :: DetectUintModeNegBitmask => {
340+ if val & x. arg1 != x. arg2 {
341+ return true ;
342+ }
343+ }
301344 }
302345 return false ;
303346}
304347
305348pub fn detect_parse_uint_notending < T : DetectIntType > ( i : & str ) -> IResult < & str , DetectUintData < T > > {
306349 let ( i, _) = opt ( is_a ( " " ) ) ( i) ?;
307350 let ( i, uint) = alt ( (
351+ detect_parse_uint_bitmask,
308352 detect_parse_uint_start_interval,
309353 detect_parse_uint_start_equal,
310354 detect_parse_uint_start_symbol,
@@ -487,6 +531,24 @@ mod tests {
487531 assert_eq ! ( ctx. mode, DetectUintMode :: DetectUintModeGt ) ;
488532 }
489533
534+ #[ test]
535+ fn test_parse_uint_bitmask ( ) {
536+ let ( _, val) = detect_parse_uint :: < u64 > ( "&0x40!=0" ) . unwrap ( ) ;
537+ assert_eq ! ( val. arg1, 0x40 ) ;
538+ assert_eq ! ( val. arg2, 0 ) ;
539+ assert_eq ! ( val. mode, DetectUintMode :: DetectUintModeNegBitmask ) ;
540+ assert ! ( !detect_match_uint( & val, 0xBF ) ) ;
541+ assert ! ( detect_match_uint( & val, 0x40 ) ) ;
542+ let ( _, val) = detect_parse_uint :: < u64 > ( "&0xc0=0x80" ) . unwrap ( ) ;
543+ assert_eq ! ( val. arg1, 0xc0 ) ;
544+ assert_eq ! ( val. arg2, 0x80 ) ;
545+ assert_eq ! ( val. mode, DetectUintMode :: DetectUintModeBitmask ) ;
546+ assert ! ( detect_match_uint( & val, 0x80 ) ) ;
547+ assert ! ( !detect_match_uint( & val, 0x40 ) ) ;
548+ assert ! ( !detect_match_uint( & val, 0xc0 ) ) ;
549+ // could never match
550+ assert ! ( detect_parse_uint:: <u64 >( "&0xc0=12" ) . is_err( ) ) ;
551+ }
490552 #[ test]
491553 fn test_parse_uint_hex ( ) {
492554 let ( _, val) = detect_parse_uint :: < u64 > ( "0x100" ) . unwrap ( ) ;
0 commit comments