summaryrefslogtreecommitdiffstats
path: root/libiptc
diff options
context:
space:
mode:
authorStefan Tomanek <stefan.tomanek@wertarbyte.de>2011-03-08 22:42:51 +0100
committerJan Engelhardt <jengelh@medozas.de>2011-03-08 23:12:05 +0100
commitd59b9db031abee37a9aa9776662dd15370faabf4 (patch)
tree47481f2b5f1afbc122f494beca1375de661c1160 /libiptc
parent9cc4f24e72f87ca191c2e723e7cd293f6477481c (diff)
iptables: add -C to check for existing rules
It is often useful to check whether a specific rule is already present in a chain without actually modifying the iptables config. Services like fail2ban usually employ techniques like grepping through the output of "iptables -L" which is quite error prone. This patch adds a new operation -C to the iptables command which mostly works like -D; it can detect and indicate the existence of the specified rule by modifying the exit code. The new operation TC_CHECK_ENTRY uses the same code as the -D operation, whose functions got a dry-run parameter appended. Signed-off-by: Stefan Tomanek <stefan.tomanek@wertarbyte.de> Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Diffstat (limited to 'libiptc')
-rw-r--r--libiptc/libip4tc.c1
-rw-r--r--libiptc/libip6tc.c1
-rw-r--r--libiptc/libiptc.c30
3 files changed, 26 insertions, 6 deletions
diff --git a/libiptc/libip4tc.c b/libiptc/libip4tc.c
index c1d78e2b..e2d2a5ee 100644
--- a/libiptc/libip4tc.c
+++ b/libiptc/libip4tc.c
@@ -76,6 +76,7 @@ typedef unsigned int socklen_t;
#define TC_INSERT_ENTRY iptc_insert_entry
#define TC_REPLACE_ENTRY iptc_replace_entry
#define TC_APPEND_ENTRY iptc_append_entry
+#define TC_CHECK_ENTRY iptc_check_entry
#define TC_DELETE_ENTRY iptc_delete_entry
#define TC_DELETE_NUM_ENTRY iptc_delete_num_entry
#define TC_FLUSH_ENTRIES iptc_flush_entries
diff --git a/libiptc/libip6tc.c b/libiptc/libip6tc.c
index 27fe4c4e..c1508cd5 100644
--- a/libiptc/libip6tc.c
+++ b/libiptc/libip6tc.c
@@ -71,6 +71,7 @@ typedef unsigned int socklen_t;
#define TC_INSERT_ENTRY ip6tc_insert_entry
#define TC_REPLACE_ENTRY ip6tc_replace_entry
#define TC_APPEND_ENTRY ip6tc_append_entry
+#define TC_CHECK_ENTRY ip6tc_check_entry
#define TC_DELETE_ENTRY ip6tc_delete_entry
#define TC_DELETE_NUM_ENTRY ip6tc_delete_num_entry
#define TC_FLUSH_ENTRIES ip6tc_flush_entries
diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
index 7a9c7428..d3b1c517 100644
--- a/libiptc/libiptc.c
+++ b/libiptc/libiptc.c
@@ -31,6 +31,7 @@
*/
#include <sys/types.h>
#include <sys/socket.h>
+#include <stdbool.h>
#include <xtables.h>
#include "linux_list.h"
@@ -1956,12 +1957,11 @@ is_same(const STRUCT_ENTRY *a,
const STRUCT_ENTRY *b,
unsigned char *matchmask);
-/* Delete the first rule in `chain' which matches `fw'. */
-int
-TC_DELETE_ENTRY(const IPT_CHAINLABEL chain,
- const STRUCT_ENTRY *origfw,
- unsigned char *matchmask,
- struct xtc_handle *handle)
+
+/* find the first rule in `chain' which matches `fw' and remove it unless dry_run is set */
+static int delete_entry(const IPT_CHAINLABEL chain, const STRUCT_ENTRY *origfw,
+ unsigned char *matchmask, struct xtc_handle *handle,
+ bool dry_run)
{
struct chain_head *c;
struct rule_head *r, *i;
@@ -2005,6 +2005,10 @@ TC_DELETE_ENTRY(const IPT_CHAINLABEL chain,
if (!target_same(r, i, mask))
continue;
+ /* if we are just doing a dry run, we simply skip the rest */
+ if (dry_run)
+ return 1;
+
/* If we are about to delete the rule that is the
* current iterator, move rule iterator back. next
* pointer will then point to real next node */
@@ -2027,6 +2031,20 @@ TC_DELETE_ENTRY(const IPT_CHAINLABEL chain,
return 0;
}
+/* check whether a specified rule is present */
+int TC_CHECK_ENTRY(const IPT_CHAINLABEL chain, const STRUCT_ENTRY *origfw,
+ unsigned char *matchmask, struct xtc_handle *handle)
+{
+ /* do a dry-run delete to find out whether a matching rule exists */
+ return delete_entry(chain, origfw, matchmask, handle, true);
+}
+
+/* Delete the first rule in `chain' which matches `fw'. */
+int TC_DELETE_ENTRY(const IPT_CHAINLABEL chain, const STRUCT_ENTRY *origfw,
+ unsigned char *matchmask, struct xtc_handle *handle)
+{
+ return delete_entry(chain, origfw, matchmask, handle, false);
+}
/* Delete the rule in position `rulenum' in `chain'. */
int