summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extensions/Makefile2
-rw-r--r--extensions/libip6t_CONNMARK.c220
-rw-r--r--extensions/libip6t_connmark.c151
-rw-r--r--extensions/libip6t_state.c163
4 files changed, 535 insertions, 1 deletions
diff --git a/extensions/Makefile b/extensions/Makefile
index f2fdc939..a751b298 100644
--- a/extensions/Makefile
+++ b/extensions/Makefile
@@ -6,7 +6,7 @@
# package (HW)
#
PF_EXT_SLIB:=ah addrtype comment connlimit connmark conntrack dscp ecn esp hashlimit helper icmp iprange length limit mac mark multiport owner physdev pkttype realm rpc sctp standard state tcp tcpmss tos ttl udp unclean CLASSIFY CONNMARK DNAT DSCP ECN LOG MARK MASQUERADE MIRROR NETMAP NFQUEUE NOTRACK REDIRECT REJECT SAME SNAT TARPIT TCPMSS TOS TRACE TTL ULOG
-PF6_EXT_SLIB:=eui64 hl icmpv6 length limit mac mark multiport owner physdev standard tcp udp HL LOG NFQUEUE MARK TRACE
+PF6_EXT_SLIB:=connmark eui64 hl icmpv6 length limit mac mark multiport owner physdev standard state tcp udp CONNMARK HL LOG NFQUEUE MARK TRACE
# Optionals
PF_EXT_SLIB_OPTS:=$(foreach T,$(wildcard extensions/.*-test),$(shell KERNEL_DIR=$(KERNEL_DIR) $(T)))
diff --git a/extensions/libip6t_CONNMARK.c b/extensions/libip6t_CONNMARK.c
new file mode 100644
index 00000000..9506f262
--- /dev/null
+++ b/extensions/libip6t_CONNMARK.c
@@ -0,0 +1,220 @@
+/* Shared library add-on to iptables to add CONNMARK target support.
+ *
+ * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
+ * by Henrik Nordstrom <hno@marasystems.com>
+ *
+ * Version 1.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <ip6tables.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include "../include/linux/netfilter_ipv4/ipt_CONNMARK.h"
+
+#if 0
+struct markinfo {
+ struct ipt_entry_target t;
+ struct ipt_connmark_target_info mark;
+};
+#endif
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+ printf(
+"CONNMARK target v%s options:\n"
+" --set-mark value[/mask] Set conntrack mark value\n"
+" --save-mark [--mask mask] Save the packet nfmark in the connection\n"
+" --restore-mark [--mask mask] Restore saved nfmark value\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+ { "set-mark", 1, 0, '1' },
+ { "save-mark", 0, 0, '2' },
+ { "restore-mark", 0, 0, '3' },
+ { "mask", 1, 0, '4' },
+ { 0 }
+};
+
+/* Initialize the target. */
+static void
+init(struct ip6t_entry_target *t, unsigned int *nfcache)
+{
+}
+
+/* Function which parses command options; returns true if it
+ ate an option */
+static int
+parse(int c, char **argv, int invert, unsigned int *flags,
+ const struct ip6t_entry *entry,
+ struct ip6t_entry_target **target)
+{
+ struct ipt_connmark_target_info *markinfo
+ = (struct ipt_connmark_target_info *)(*target)->data;
+
+ markinfo->mask = 0xffffffffUL;
+
+ switch (c) {
+ char *end;
+ case '1':
+ markinfo->mode = IPT_CONNMARK_SET;
+
+ markinfo->mark = strtoul(optarg, &end, 0);
+ if (*end == '/' && end[1] != '\0')
+ markinfo->mask = strtoul(end+1, &end, 0);
+
+ if (*end != '\0' || end == optarg)
+ exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
+ if (*flags)
+ exit_error(PARAMETER_PROBLEM,
+ "CONNMARK target: Can't specify --set-mark twice");
+ *flags = 1;
+ break;
+ case '2':
+ markinfo->mode = IPT_CONNMARK_SAVE;
+ if (*flags)
+ exit_error(PARAMETER_PROBLEM,
+ "CONNMARK target: Can't specify --save-mark twice");
+ *flags = 1;
+ break;
+ case '3':
+ markinfo->mode = IPT_CONNMARK_RESTORE;
+ if (*flags)
+ exit_error(PARAMETER_PROBLEM,
+ "CONNMARK target: Can't specify --restore-mark twice");
+ *flags = 1;
+ break;
+ case '4':
+ if (!*flags)
+ exit_error(PARAMETER_PROBLEM,
+ "CONNMARK target: Can't specify --mask without a operation");
+ markinfo->mask = strtoul(optarg, &end, 0);
+
+ if (*end != '\0' || end == optarg)
+ exit_error(PARAMETER_PROBLEM, "Bad MASK value `%s'", optarg);
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+static void
+final_check(unsigned int flags)
+{
+ if (!flags)
+ exit_error(PARAMETER_PROBLEM,
+ "CONNMARK target: No operation specified");
+}
+
+static void
+print_mark(unsigned long mark)
+{
+ printf("0x%lx", mark);
+}
+
+static void
+print_mask(const char *text, unsigned long mask)
+{
+ if (mask != 0xffffffffUL)
+ printf("%s0x%lx", text, mask);
+}
+
+
+/* Prints out the target info. */
+static void
+print(const struct ip6t_ip6 *ip,
+ const struct ip6t_entry_target *target,
+ int numeric)
+{
+ const struct ipt_connmark_target_info *markinfo =
+ (const struct ipt_connmark_target_info *)target->data;
+ switch (markinfo->mode) {
+ case IPT_CONNMARK_SET:
+ printf("CONNMARK set ");
+ print_mark(markinfo->mark);
+ print_mask("/", markinfo->mask);
+ printf(" ");
+ break;
+ case IPT_CONNMARK_SAVE:
+ printf("CONNMARK save ");
+ print_mask("mask ", markinfo->mask);
+ printf(" ");
+ break;
+ case IPT_CONNMARK_RESTORE:
+ printf("CONNMARK restore ");
+ print_mask("mask ", markinfo->mask);
+ break;
+ default:
+ printf("ERROR: UNKNOWN CONNMARK MODE ");
+ break;
+ }
+}
+
+/* Saves the target into in parsable form to stdout. */
+static void
+save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target)
+{
+ const struct ipt_connmark_target_info *markinfo =
+ (const struct ipt_connmark_target_info *)target->data;
+
+ switch (markinfo->mode) {
+ case IPT_CONNMARK_SET:
+ printf("--set-mark ");
+ print_mark(markinfo->mark);
+ print_mask("/", markinfo->mask);
+ printf(" ");
+ break;
+ case IPT_CONNMARK_SAVE:
+ printf("--save-mark ");
+ print_mask("--mask ", markinfo->mask);
+ break;
+ case IPT_CONNMARK_RESTORE:
+ printf("--restore-mark ");
+ print_mask("--mask ", markinfo->mask);
+ break;
+ default:
+ printf("ERROR: UNKNOWN CONNMARK MODE ");
+ break;
+ }
+}
+
+static struct ip6tables_target connmark_target = {
+ .name = "CONNMARK",
+ .version = IPTABLES_VERSION,
+ .size = IP6T_ALIGN(sizeof(struct ipt_connmark_target_info)),
+ .userspacesize = IP6T_ALIGN(sizeof(struct ipt_connmark_target_info)),
+ .help = &help,
+ .init = &init,
+ .parse = &parse,
+ .final_check = &final_check,
+ .print = &print,
+ .save = &save,
+ .extra_opts = opts
+};
+
+void _init(void)
+{
+ register_target6(&connmark_target);
+}
diff --git a/extensions/libip6t_connmark.c b/extensions/libip6t_connmark.c
new file mode 100644
index 00000000..419da304
--- /dev/null
+++ b/extensions/libip6t_connmark.c
@@ -0,0 +1,151 @@
+/* Shared library add-on to iptables to add connmark matching support.
+ *
+ * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
+ * by Henrik Nordstrom <hno@marasystems.com>
+ *
+ * Version 1.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <ip6tables.h>
+#include "../include/linux/netfilter_ipv4/ipt_connmark.h"
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+ printf(
+"CONNMARK match v%s options:\n"
+"[!] --mark value[/mask] Match nfmark value with optional mask\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+ { "mark", 1, 0, '1' },
+ {0}
+};
+
+/* Initialize the match. */
+static void
+init(struct ip6t_entry_match *m, unsigned int *nfcache)
+{
+ /* Can't cache this. */
+ *nfcache |= NFC_UNKNOWN;
+}
+
+/* Function which parses command options; returns true if it
+ ate an option */
+static int
+parse(int c, char **argv, int invert, unsigned int *flags,
+ const struct ip6t_entry *entry,
+ unsigned int *nfcache,
+ struct ip6t_entry_match **match)
+{
+ struct ipt_connmark_info *markinfo = (struct ipt_connmark_info *)(*match)->data;
+
+ switch (c) {
+ char *end;
+ case '1':
+ check_inverse(optarg, &invert, &optind, 0);
+
+ markinfo->mark = strtoul(optarg, &end, 0);
+ markinfo->mask = 0xffffffffUL;
+
+ if (*end == '/')
+ markinfo->mask = strtoul(end+1, &end, 0);
+
+ if (*end != '\0' || end == optarg)
+ exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
+ if (invert)
+ markinfo->invert = 1;
+ *flags = 1;
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+static void
+print_mark(unsigned long mark, unsigned long mask, int numeric)
+{
+ if(mask != 0xffffffffUL)
+ printf("0x%lx/0x%lx ", mark, mask);
+ else
+ printf("0x%lx ", mark);
+}
+
+/* Final check; must have specified --mark. */
+static void
+final_check(unsigned int flags)
+{
+ if (!flags)
+ exit_error(PARAMETER_PROBLEM,
+ "MARK match: You must specify `--mark'");
+}
+
+/* Prints out the matchinfo. */
+static void
+print(const struct ip6t_ip6 *ip,
+ const struct ip6t_entry_match *match,
+ int numeric)
+{
+ struct ipt_connmark_info *info = (struct ipt_connmark_info *)match->data;
+
+ printf("CONNMARK match ");
+ if (info->invert)
+ printf("!");
+ print_mark(info->mark, info->mask, numeric);
+}
+
+/* Saves the matchinfo in parsable form to stdout. */
+static void
+save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
+{
+ struct ipt_connmark_info *info = (struct ipt_connmark_info *)match->data;
+
+ if (info->invert)
+ printf("! ");
+
+ printf("--mark ");
+ print_mark(info->mark, info->mask, 0);
+}
+
+static struct ip6tables_match connmark_match = {
+ .name = "connmark",
+ .version = IPTABLES_VERSION,
+ .size = IP6T_ALIGN(sizeof(struct ipt_connmark_info)),
+ .userspacesize = IP6T_ALIGN(sizeof(struct ipt_connmark_info)),
+ .help = &help,
+ .init = &init,
+ .parse = &parse,
+ .final_check = &final_check,
+ .print = &print,
+ .save = &save,
+ .extra_opts = opts
+};
+
+void _init(void)
+{
+ register_match6(&connmark_match);
+}
diff --git a/extensions/libip6t_state.c b/extensions/libip6t_state.c
new file mode 100644
index 00000000..84fd1a43
--- /dev/null
+++ b/extensions/libip6t_state.c
@@ -0,0 +1,163 @@
+/* Ugly hack to make state matching for ipv6 work before iptables-1.4.x is finished */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <ip6tables.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ipt_state.h>
+
+#ifndef IPT_STATE_UNTRACKED
+#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
+#endif
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+ printf(
+"state v%s options:\n"
+" [!] --state [INVALID|ESTABLISHED|NEW|RELATED|UNTRACKED][,...]\n"
+" State(s) to match\n"
+"\n", IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+ { "state", 1, 0, '1' },
+ {0}
+};
+
+static int
+parse_state(const char *state, size_t strlen, struct ipt_state_info *sinfo)
+{
+ if (strncasecmp(state, "INVALID", strlen) == 0)
+ sinfo->statemask |= IPT_STATE_INVALID;
+ else if (strncasecmp(state, "NEW", strlen) == 0)
+ sinfo->statemask |= IPT_STATE_BIT(IP_CT_NEW);
+ else if (strncasecmp(state, "ESTABLISHED", strlen) == 0)
+ sinfo->statemask |= IPT_STATE_BIT(IP_CT_ESTABLISHED);
+ else if (strncasecmp(state, "RELATED", strlen) == 0)
+ sinfo->statemask |= IPT_STATE_BIT(IP_CT_RELATED);
+ else if (strncasecmp(state, "UNTRACKED", strlen) == 0)
+ sinfo->statemask |= IPT_STATE_UNTRACKED;
+ else
+ return 0;
+ return 1;
+}
+
+static void
+parse_states(const char *arg, struct ipt_state_info *sinfo)
+{
+ const char *comma;
+
+ while ((comma = strchr(arg, ',')) != NULL) {
+ if (comma == arg || !parse_state(arg, comma-arg, sinfo))
+ exit_error(PARAMETER_PROBLEM, "Bad state `%s'", arg);
+ arg = comma+1;
+ }
+
+ if (strlen(arg) == 0 || !parse_state(arg, strlen(arg), sinfo))
+ exit_error(PARAMETER_PROBLEM, "Bad state `%s'", arg);
+}
+
+/* Function which parses command options; returns true if it
+ ate an option */
+static int
+parse(int c, char **argv, int invert, unsigned int *flags,
+ const struct ip6t_entry *entry,
+ unsigned int *nfcache,
+ struct ip6t_entry_match **match)
+{
+ struct ipt_state_info *sinfo = (struct ipt_state_info *)(*match)->data;
+
+ switch (c) {
+ case '1':
+ check_inverse(optarg, &invert, &optind, 0);
+
+ parse_states(argv[optind-1], sinfo);
+ if (invert)
+ sinfo->statemask = ~sinfo->statemask;
+ *flags = 1;
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Final check; must have specified --state. */
+static void final_check(unsigned int flags)
+{
+ if (!flags)
+ exit_error(PARAMETER_PROBLEM, "You must specify `--state'");
+}
+
+static void print_state(unsigned int statemask)
+{
+ const char *sep = "";
+
+ if (statemask & IPT_STATE_INVALID) {
+ printf("%sINVALID", sep);
+ sep = ",";
+ }
+ if (statemask & IPT_STATE_BIT(IP_CT_NEW)) {
+ printf("%sNEW", sep);
+ sep = ",";
+ }
+ if (statemask & IPT_STATE_BIT(IP_CT_RELATED)) {
+ printf("%sRELATED", sep);
+ sep = ",";
+ }
+ if (statemask & IPT_STATE_BIT(IP_CT_ESTABLISHED)) {
+ printf("%sESTABLISHED", sep);
+ sep = ",";
+ }
+ if (statemask & IPT_STATE_UNTRACKED) {
+ printf("%sUNTRACKED", sep);
+ sep = ",";
+ }
+ printf(" ");
+}
+
+/* Prints out the matchinfo. */
+static void
+print(const struct ip6t_ip6 *ip,
+ const struct ip6t_entry_match *match,
+ int numeric)
+{
+ struct ipt_state_info *sinfo = (struct ipt_state_info *)match->data;
+
+ printf("state ");
+ print_state(sinfo->statemask);
+}
+
+/* Saves the matchinfo in parsable form to stdout. */
+static void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
+{
+ struct ipt_state_info *sinfo = (struct ipt_state_info *)match->data;
+
+ printf("--state ");
+ print_state(sinfo->statemask);
+}
+
+static struct ip6tables_match state = {
+ .next = NULL,
+ .name = "state",
+ .version = IPTABLES_VERSION,
+ .size = IP6T_ALIGN(sizeof(struct ipt_state_info)),
+ .userspacesize = IP6T_ALIGN(sizeof(struct ipt_state_info)),
+ .help = &help,
+ .parse = &parse,
+ .final_check = &final_check,
+ .print = &print,
+ .save = &save,
+ .extra_opts = opts
+};
+
+void _init(void)
+{
+ register_match6(&state);
+}