summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
author/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=rusty/emailAddress=rusty@netfilter.org </C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=rusty/emailAddress=rusty@netfilter.org>2005-01-03 03:48:40 +0000
committer/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=rusty/emailAddress=rusty@netfilter.org </C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=rusty/emailAddress=rusty@netfilter.org>2005-01-03 03:48:40 +0000
commite67b632ed614f4cda423623bc6c57cbacf5ba182 (patch)
tree58c303308741dab836833dc15cade877a6bf6939 /extensions
parente19568f2da27ef8936e1a125f4fdb1559283b04e (diff)
Extension revision number support (if kernel supports the getsockopts).
Enhance MARK match with second revision. Committed in anticipation of the kernel patch being applied.
Diffstat (limited to 'extensions')
-rw-r--r--extensions/libipt_MARK.c140
1 files changed, 126 insertions, 14 deletions
diff --git a/extensions/libipt_MARK.c b/extensions/libipt_MARK.c
index bc3dd42..457f6ad 100644
--- a/extensions/libipt_MARK.c
+++ b/extensions/libipt_MARK.c
@@ -16,12 +16,16 @@ help(void)
printf(
"MARK target v%s options:\n"
" --set-mark value Set nfmark value\n"
+" --and-mark value Binary AND the nfmark with value\n"
+" --or-mark value Binary OR the nfmark with value\n"
"\n",
IPTABLES_VERSION);
}
static struct option opts[] = {
{ "set-mark", 1, 0, '1' },
+ { "and-mark", 1, 0, '2' },
+ { "or-mark", 1, 0, '3' },
{ 0 }
};
@@ -34,9 +38,9 @@ init(struct ipt_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 ipt_entry *entry,
- struct ipt_entry_target **target)
+parse_v0(int c, char **argv, int invert, unsigned int *flags,
+ const struct ipt_entry *entry,
+ struct ipt_entry_target **target)
{
struct ipt_mark_target_info *markinfo
= (struct ipt_mark_target_info *)(*target)->data;
@@ -56,7 +60,12 @@ parse(int c, char **argv, int invert, unsigned int *flags,
"MARK target: Can't specify --set-mark twice");
*flags = 1;
break;
-
+ case '2':
+ exit_error(PARAMETER_PROBLEM,
+ "MARK target: kernel too old for --and-mark");
+ case '3':
+ exit_error(PARAMETER_PROBLEM,
+ "MARK target: kernel too old for --or-mark");
default:
return 0;
}
@@ -69,7 +78,47 @@ final_check(unsigned int flags)
{
if (!flags)
exit_error(PARAMETER_PROBLEM,
- "MARK target: Parameter --set-mark is required");
+ "MARK target: Parameter --set/and/or-mark"
+ " is required");
+}
+
+/* Function which parses command options; returns true if it
+ ate an option */
+static int
+parse_v1(int c, char **argv, int invert, unsigned int *flags,
+ const struct ipt_entry *entry,
+ struct ipt_entry_target **target)
+{
+ struct ipt_mark_target_info_v1 *markinfo
+ = (struct ipt_mark_target_info_v1 *)(*target)->data;
+
+ switch (c) {
+ case '1':
+ markinfo->mode = IPT_MARK_SET;
+ break;
+ case '2':
+ markinfo->mode = IPT_MARK_AND;
+ break;
+ case '3':
+ markinfo->mode = IPT_MARK_OR;
+ break;
+ default:
+ return 0;
+ }
+
+#ifdef KERNEL_64_USERSPACE_32
+ if (string_to_number_ll(optarg, 0, 0, &markinfo->mark))
+#else
+ if (string_to_number_l(optarg, 0, 0, &markinfo->mark))
+#endif
+ exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
+
+ if (*flags)
+ exit_error(PARAMETER_PROBLEM,
+ "MARK target: Can't specify --set-mark twice");
+
+ *flags = 1;
+ return 1;
}
#ifdef KERNEL_64_USERSPACE_32
@@ -88,9 +137,9 @@ print_mark(unsigned long mark)
/* Prints out the targinfo. */
static void
-print(const struct ipt_ip *ip,
- const struct ipt_entry_target *target,
- int numeric)
+print_v0(const struct ipt_ip *ip,
+ const struct ipt_entry_target *target,
+ int numeric)
{
const struct ipt_mark_target_info *markinfo =
(const struct ipt_mark_target_info *)target->data;
@@ -100,7 +149,7 @@ print(const struct ipt_ip *ip,
/* Saves the union ipt_targinfo in parsable form to stdout. */
static void
-save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+save_v0(const struct ipt_ip *ip, const struct ipt_entry_target *target)
{
const struct ipt_mark_target_info *markinfo =
(const struct ipt_mark_target_info *)target->data;
@@ -109,23 +158,86 @@ save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
print_mark(markinfo->mark);
}
+/* Prints out the targinfo. */
+static void
+print_v1(const struct ipt_ip *ip,
+ const struct ipt_entry_target *target,
+ int numeric)
+{
+ const struct ipt_mark_target_info_v1 *markinfo =
+ (const struct ipt_mark_target_info_v1 *)target->data;
+
+ switch (markinfo->mode) {
+ case IPT_MARK_SET:
+ printf("MARK set ");
+ break;
+ case IPT_MARK_AND:
+ printf("MARK and ");
+ break;
+ case IPT_MARK_OR:
+ printf("MARK or ");
+ break;
+ }
+ print_mark(markinfo->mark);
+}
+
+/* Saves the union ipt_targinfo in parsable form to stdout. */
+static void
+save_v1(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+{
+ const struct ipt_mark_target_info_v1 *markinfo =
+ (const struct ipt_mark_target_info_v1 *)target->data;
+
+ switch (markinfo->mode) {
+ case IPT_MARK_SET:
+ printf("--set-mark ");
+ break;
+ case IPT_MARK_AND:
+ printf("--and-mark ");
+ break;
+ case IPT_MARK_OR:
+ printf("--or-mark ");
+ break;
+ }
+ print_mark(markinfo->mark);
+}
+
static
-struct iptables_target mark = {
+struct iptables_target mark_v0 = {
.next = NULL,
.name = "MARK",
.version = IPTABLES_VERSION,
+ .revision = 0,
.size = IPT_ALIGN(sizeof(struct ipt_mark_target_info)),
.userspacesize = IPT_ALIGN(sizeof(struct ipt_mark_target_info)),
.help = &help,
.init = &init,
- .parse = &parse,
+ .parse = &parse_v0,
+ .final_check = &final_check,
+ .print = &print_v0,
+ .save = &save_v0,
+ .extra_opts = opts
+};
+
+static
+struct iptables_target mark_v1 = {
+ .next = NULL,
+ .name = "MARK",
+ .version = IPTABLES_VERSION,
+ .revision = 1,
+ .size = IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)),
+ .userspacesize = IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1)),
+ .help = &help,
+ .init = &init,
+ .parse = &parse_v1,
.final_check = &final_check,
- .print = &print,
- .save = &save,
+ .print = &print_v1,
+ .save = &save_v1,
.extra_opts = opts
};
void _init(void)
{
- register_target(&mark);
+ register_target(&mark_v0);
+ register_target(&mark_v1);
}