diff --git a/doc/userguide/rules/flow-keywords.rst b/doc/userguide/rules/flow-keywords.rst index 6f3995e66d..234b53fced 100644 --- a/doc/userguide/rules/flow-keywords.rst +++ b/doc/userguide/rules/flow-keywords.rst @@ -336,6 +336,8 @@ following directions: * either +* both + Syntax:: flow.pkts:,[op] @@ -369,6 +371,8 @@ following directions: * either +* both + Syntax:: flow.bytes:,[op] diff --git a/rust/src/detect/flow.rs b/rust/src/detect/flow.rs index 53e01af06e..186dfe30c2 100644 --- a/rust/src/detect/flow.rs +++ b/rust/src/detect/flow.rs @@ -29,6 +29,7 @@ pub enum DetectFlowDir { DETECT_FLOW_TOSERVER = 1, DETECT_FLOW_TOCLIENT = 2, DETECT_FLOW_TOEITHER = 3, + DETECT_FLOW_TOBOTH = 4, } #[derive(Debug, PartialEq)] @@ -52,6 +53,7 @@ fn detect_parse_flow_direction(i: &str) -> IResult<&str, DetectFlowDir> { value(DetectFlowDir::DETECT_FLOW_TOSERVER, tag("toserver")), value(DetectFlowDir::DETECT_FLOW_TOCLIENT, tag("toclient")), value(DetectFlowDir::DETECT_FLOW_TOEITHER, tag("either")), + value(DetectFlowDir::DETECT_FLOW_TOBOTH, tag("both")), )) .parse(i)?; return Ok((i, fd)); diff --git a/src/detect-flow-pkts.c b/src/detect-flow-pkts.c index ea3c007a11..6b51f62258 100644 --- a/src/detect-flow-pkts.c +++ b/src/detect-flow-pkts.c @@ -40,6 +40,11 @@ static int DetectFlowPktsMatch( return 1; } return DetectU32Match(p->flow->todstpktcnt, &df->pkt_data); + } else if (df->dir == DETECT_FLOW_TOBOTH) { + if (DetectU32Match(p->flow->tosrcpktcnt, &df->pkt_data) && + DetectU32Match(p->flow->todstpktcnt, &df->pkt_data)) { + return 1; + } } return 0; } @@ -209,6 +214,11 @@ static int DetectFlowBytesMatch( return 1; } return DetectU64Match(p->flow->todstbytecnt, &df->byte_data); + } else if (df->dir == DETECT_FLOW_TOBOTH) { + if (DetectU64Match(p->flow->tosrcbytecnt, &df->byte_data) && + DetectU64Match(p->flow->todstbytecnt, &df->byte_data)) { + return 1; + } } return 0; }