summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorStephane Ouellette <ouellettes@videotron.ca>2002-11-02 15:00:15 +0000
committerHarald Welte <laforge@gnumonks.org>2002-11-02 15:00:15 +0000
commitd57b0609ef00da33bcbc4a7b718a88b141f06c28 (patch)
tree567cf45bbbd7ef64645d4de3d923c3165b6ca5ee /extensions
parent68ec9c729976699f2472258f13c0476afcc5c7d3 (diff)
add condition patch (Stephane Ouelle)
Diffstat (limited to 'extensions')
-rwxr-xr-xextensions/.condition-test3
-rw-r--r--extensions/libipt_condition.c96
2 files changed, 99 insertions, 0 deletions
diff --git a/extensions/.condition-test b/extensions/.condition-test
new file mode 100755
index 00000000..20f3bc78
--- /dev/null
+++ b/extensions/.condition-test
@@ -0,0 +1,3 @@
+#!/bin/sh
+# True if condition is applied.
+[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_condition.h ] && echo condition
diff --git a/extensions/libipt_condition.c b/extensions/libipt_condition.c
new file mode 100644
index 00000000..351c1aa4
--- /dev/null
+++ b/extensions/libipt_condition.c
@@ -0,0 +1,96 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <iptables.h>
+
+#include<linux/netfilter_ipv4/ip_tables.h>
+#include<linux/netfilter_ipv4/ipt_condition.h>
+
+
+static void help(void)
+{
+ printf("condition match v%s options:\n"
+ "--condition [!] filename Match on boolean value stored in /proc file"
+ "\n", IPTABLES_VERSION);
+}
+
+static struct option opts[] = { { "condition", 1, 0, 'X' }, { 0 } };
+
+static void init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+ *nfcache |= NFC_UNKNOWN;
+}
+
+static int parse(int c, char **argv, int invert, unsigned int *flags,
+ const struct ipt_entry *entry, unsigned int *nfcache,
+ struct ipt_entry_match **match)
+{
+ struct condition_info *info = (struct condition_info*)(*match)->data;
+
+ check_inverse(optarg, &invert, &optind, 0);
+
+ if(*flags)
+ exit_error(PARAMETER_PROBLEM, "Can't specify multiple conditions");
+
+ if(c == 'X')
+ {
+ if(strlen(argv[optind-1]) < VARIABLE_NAME_LEN)
+ strcpy(info->name, argv[optind-1]);
+ else
+ exit_error(PARAMETER_PROBLEM, "File name too long");
+
+ info->invert = invert;
+ *flags = 1;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static void final_check(unsigned int flags)
+{
+ if(!flags)
+ exit_error(PARAMETER_PROBLEM, "Condition match: must specify --condition");
+}
+
+
+static void print(const struct ipt_ip *ip,
+ const struct ipt_entry_match *match, int numeric)
+{
+ const struct condition_info *info = (const struct condition_info*)match->data;
+
+ printf("condition %s%s ", (info->invert) ? "!" : "", info->name);
+}
+
+
+static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+{
+ const struct condition_info *info = (const struct condition_info*)match->data;
+
+ printf("--condition %s%s ", (info->invert) ? "! " : "", info->name);
+}
+
+
+static struct iptables_match condition = {
+ NULL,
+ "condition",
+ IPTABLES_VERSION,
+ IPT_ALIGN(sizeof(struct condition_info)),
+ IPT_ALIGN(sizeof(struct condition_info)),
+ &help,
+ &init,
+ &parse,
+ &final_check,
+ &print,
+ &save,
+ opts
+};
+
+
+void _init(void)
+{
+ register_match(&condition);
+}
+