* 3:-1 will have subslice [4,5]
* -4:4 will have subslice [3,4]
-If one index is out of bounds, an empty subslice is used.
\ No newline at end of file
+If one index is out of bounds, an empty subslice is used.
+
+Count
+-----
+
+Multi-integer can also just count the number of occurences
+without matching to a specific value.
+
+The syntax is::
+ keyword: count [mode] value;
+
+Examples::
+
+ http2.window:count >5;
OrAbsent,
Index((bool, i32)),
NumberMatches(DetectUintData<u32>),
+ Count(DetectUintData<u32>),
}
#[derive(Debug, PartialEq)]
return Some((start, end));
}
+fn parse_uint_count(s: &str) -> IResult<&str, DetectUintData<u32>> {
+ let (s, _) = tag("count")(s)?;
+ let (s, _) = opt(is_a(" "))(s)?;
+ let (s, du32) = detect_parse_uint::<u32>(s)?;
+ Ok((s, du32))
+}
+
fn parse_uint_index(parts: &[&str]) -> Option<DetectUintIndex> {
let index = if parts.len() >= 2 {
match parts[1] {
// not only a literal, but some numeric value
_ => return parse_uint_index_val(parts[1]),
}
+ } else if let Ok((_, du)) = parse_uint_count(parts[0]) {
+ DetectUintIndex::Count(du)
} else {
DetectUintIndex::Any
};
}
let index = parse_uint_index(&parts)?;
+ if let DetectUintIndex::Count(_) = &index {
+ return Some(DetectUintArrayData {
+ du: DetectUintData::<T> {
+ arg1: T::min_value(),
+ arg2: T::min_value(),
+ mode: DetectUintMode::DetectUintModeEqual,
+ },
+ index,
+ start: 0,
+ end: 0,
+ });
+ }
+
let (_, du) = detect_parse_uint::<T>(parts[0]).ok()?;
let (start, end) = parse_uint_subslice(&parts)?;
}
let index = parse_uint_index(&parts)?;
+ if let DetectUintIndex::Count(_) = &index {
+ return Some(DetectUintArrayData {
+ du: DetectUintData::<T1> {
+ arg1: T1::min_value(),
+ arg2: T1::min_value(),
+ mode: DetectUintMode::DetectUintModeEqual,
+ },
+ index,
+ start: 0,
+ end: 0,
+ });
+ }
+
let du = detect_parse_uint_enum::<T1, T2>(parts[0])?;
let (start, end) = parse_uint_subslice(&parts)?;
}
return 0;
}
+ DetectUintIndex::Count(du32) => {
+ if !eof {
+ match du32.mode {
+ DetectUintMode::DetectUintModeGt | DetectUintMode::DetectUintModeGte => {}
+ _ => {
+ return 0;
+ }
+ }
+ }
+ let mut nb = 0u32;
+ for response in subslice {
+ if get_value(response).is_some() {
+ nb += 1;
+ }
+ }
+ if detect_match_uint(du32, nb) {
+ return 1;
+ }
+ return 0;
+ }
DetectUintIndex::All => {
if !eof {
return 0;