rsyslog/tests/rscript_is_in_subnet.sh
Rainer Gerhards 236d5ec808
rainerscript: add is_in_subnet() built-in
Improve usability by providing a simple way to check if an IP is inside
a CIDR subnet directly in RainerScript. This reduces awkward workarounds
and makes common filtering and routing tasks easier to express.

Impact: New function; existing configurations are unaffected.

Before: No built-in to test membership of an IP in a CIDR subnet.
After:  is_in_subnet(ip, cidr) returns 1 if ip is in cidr, else 0.

Add is_in_subnet() as a built-in taking two args (IP string and CIDR).
Both IPv4 and IPv6 are supported. Inputs are parsed with inet_pton; the
CIDR mask is validated for range (0..32 / 0..128). Matching is done by
masking both the address and the network and comparing results. Invalid
inputs and family mismatches yield 0. The function returns a numeric
value. It is registered in the functions[] table and documented. Tests
cover IPv4/IPv6 basics, /0 and host masks, mismatches, and invalid
inputs. No HUP/state or OMODTX semantics are involved.

closes: https://github.com/rsyslog/rsyslog/issues/1391

With the help of AI Agents: Google Jules, Gemini (CLI),
    ChatGPT Codex (CLI)
2026-01-12 14:01:43 +01:00

37 lines
1.3 KiB
Bash
Executable File

#!/bin/bash
. ${srcdir:=.}/diag.sh init
generate_conf
add_conf '
module(load="../plugins/imtcp/.libs/imtcp")
input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
# Basic IPv4 tests
set $!res!v4_1 = is_in_subnet("192.168.1.5", "192.168.1.0/24");
set $!res!v4_2 = is_in_subnet("192.168.2.5", "192.168.1.0/24");
set $!res!v4_3 = is_in_subnet("192.168.1.1", "192.168.1.1/32");
set $!res!v4_4 = is_in_subnet("192.168.1.1", "0.0.0.0/0");
# Basic IPv6 tests
set $!res!v6_1 = is_in_subnet("2001:db8::1", "2001:db8::/32");
set $!res!v6_2 = is_in_subnet("2001:db9::1", "2001:db8::/32");
set $!res!v6_3 = is_in_subnet("::1", "::1/128");
set $!res!v6_4 = is_in_subnet("::1", "::/0");
# Mixed / Invalid tests
set $!res!inv_1 = is_in_subnet("192.168.1.1", "2001:db8::/32");
set $!res!inv_2 = is_in_subnet("invalid", "192.168.1.0/24");
set $!res!inv_3 = is_in_subnet("192.168.1.1", "invalid");
set $!res!inv_4 = is_in_subnet("192.168.1.1", "192.168.1.0/33"); # Invalid mask
template(name="outfmt" type="string" string="%!res%\n")
local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="outfmt")
'
startup
tcpflood -m1 -y
shutdown_when_empty
wait_shutdown
export EXPECTED='{ "v4_1": 1, "v4_2": 0, "v4_3": 1, "v4_4": 1, "v6_1": 1, "v6_2": 0, "v6_3": 1, "v6_4": 1, "inv_1": 0, "inv_2": 0, "inv_3": 0, "inv_4": 0 }'
cmp_exact
exit_test