filter: add --ctstate flag + case-insensitive states + CSV support
Rule parser now accepts iptables-style: ACCEPT input -p tcp --ctstate ESTABLISHED,RELATED DROP forward state NEW Both 'state' and '--ctstate' keywords work. States are case- insensitive: NEW/New/new, ESTABLISHED/Established/established, RELATED/Related/related, INVALID/Invalid/invalid. Comma-separated lists (e.g. 'ESTABLISHED,RELATED') use the FIRST recognized state only — FilterRule stores a single StateMatch field. Docstring updated with new examples. All 31 tests pass.
This commit is contained in:
@@ -11,13 +11,14 @@
|
||||
//!
|
||||
//! ```text
|
||||
//! ACTION CHAIN [-i IFACE] [-o IFACE] [-p PROTO] [-s ADDR[/LEN]] [-d ADDR[/LEN]]
|
||||
//! [--sport PORT] [--dport PORT]
|
||||
//! [--sport PORT] [--dport PORT] [state STATE|--ctstate STATE[,STATE...]]
|
||||
//! ```
|
||||
//!
|
||||
//! Examples:
|
||||
//! - `ACCEPT input -p tcp --dport 80`
|
||||
//! - `DROP input -s 10.0.0.0/8`
|
||||
//! - `ACCEPT output -d 192.168.1.0/24 --sport 1024`
|
||||
//! - `ACCEPT input -p tcp --ctstate ESTABLISHED,RELATED`
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
@@ -355,13 +356,17 @@ pub fn parse_rule(line: &str) -> core::result::Result<FilterRule, ParseError> {
|
||||
let value = tokens.next().ok_or(ParseError::Msg("missing --dport value"))?;
|
||||
rule.dst_port = Some(parse_port(value)?);
|
||||
}
|
||||
"state" => {
|
||||
"state" | "--ctstate" => {
|
||||
let value = tokens.next().ok_or(ParseError::Msg("missing state value"))?;
|
||||
rule.state_match = Some(match value {
|
||||
"new" => StateMatch::New,
|
||||
"established" => StateMatch::Established,
|
||||
"related" => StateMatch::Related,
|
||||
"invalid" => StateMatch::Invalid,
|
||||
// Accept comma-separated list (e.g. "ESTABLISHED,RELATED"),
|
||||
// using the FIRST recognized state. The FilterRule struct
|
||||
// supports a single state_match field.
|
||||
let first = value.split(',').next().unwrap_or(value);
|
||||
rule.state_match = Some(match first {
|
||||
"new" | "NEW" => StateMatch::New,
|
||||
"established" | "ESTABLISHED" => StateMatch::Established,
|
||||
"related" | "RELATED" => StateMatch::Related,
|
||||
"invalid" | "INVALID" => StateMatch::Invalid,
|
||||
_ => return Err(ParseError::Msg("unknown state value")),
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user