summaryrefslogtreecommitdiffstats
path: root/iptables/xshared.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2020-11-16 17:20:57 +0100
committerPhil Sutter <phil@nwl.cc>2021-05-17 15:07:02 +0200
commit9dc50b5b8e4416219c700331c6e301d840f6e55d (patch)
tree44d2ae242c7a2659200cfd5330e0f492e0517d0f /iptables/xshared.c
parent3664249f520308e8d9ce6238374f08ac96aedbb6 (diff)
xshared: Merge invflags handling code
Join invflags handling between iptables, ip6tables, xtables and arptables. Ebtables still has its own code which differs quite a bit. In order to use a shared set_option() routine, iptables and ip6tables need to provide a local 'invflags' variable which is 16bits wide. Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'iptables/xshared.c')
-rw-r--r--iptables/xshared.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/iptables/xshared.c b/iptables/xshared.c
index afd7a9d6..a3f473ea 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -853,3 +853,46 @@ char opt2char(int option)
return *ptr;
}
+
+static const int inverse_for_options[NUMBER_OF_OPT] =
+{
+/* -n */ 0,
+/* -s */ IPT_INV_SRCIP,
+/* -d */ IPT_INV_DSTIP,
+/* -p */ XT_INV_PROTO,
+/* -j */ 0,
+/* -v */ 0,
+/* -x */ 0,
+/* -i */ IPT_INV_VIA_IN,
+/* -o */ IPT_INV_VIA_OUT,
+/*--line*/ 0,
+/* -c */ 0,
+/* -f */ IPT_INV_FRAG,
+/* 2 */ IPT_INV_SRCDEVADDR,
+/* 3 */ IPT_INV_TGTDEVADDR,
+/* -l */ IPT_INV_ARPHLN,
+/* 4 */ IPT_INV_ARPOP,
+/* 5 */ IPT_INV_ARPHRD,
+/* 6 */ IPT_INV_PROTO,
+};
+
+void
+set_option(unsigned int *options, unsigned int option, u_int16_t *invflg,
+ bool invert)
+{
+ if (*options & option)
+ xtables_error(PARAMETER_PROBLEM, "multiple -%c flags not allowed",
+ opt2char(option));
+ *options |= option;
+
+ if (invert) {
+ unsigned int i;
+ for (i = 0; 1 << i != option; i++);
+
+ if (!inverse_for_options[i])
+ xtables_error(PARAMETER_PROBLEM,
+ "cannot have ! before -%c",
+ opt2char(option));
+ *invflg |= inverse_for_options[i];
+ }
+}