diff mbox

new xtables-addons implementation of XOR target

Message ID CADb65V65-OHkHCpoqmXZgqq=h3c7sRuEdzfNbRY5TeirfP2OPQ@mail.gmail.com
State Not Applicable
Headers show

Commit Message

Andrew Smith Jan. 18, 2014, 10:25 a.m. UTC
This is slightly updated from an earlier post that didn't seem to make
the mailing list (fixed man pages).

I had a requirement for some proof of concept work I was performing to
have a very simple layer 3 obfuscation so it was useful to me and
perhaps others to have the XOR target available. Tunnelling wasn't an
option since I needed to preserve some multicast discovery without
changing the component that was multicasting.

I've reimplemented the target for xtables and corrected some potential
buffer overrun code that I spotted. Diffs are included for the 2.4 and
the 1.47.1 tags so that 2.6.x Kernel owners can use the target as well
as 3.x Kernel owners.

This has been tested with FC20 and with CentOS 6.5.

RedHat/CentOS on a 2.6.32 Kernel requires another tweak of course to
compat_xtables.c as unlike other 2.6.32 Kernels RedHat/CentOS require
the fragflg parameter to ipv6_find_hdr in xtnu_ipv6_find_hdr but I
guess that's a localising patch that anybody building for
RedHat/CentOS should introduce themselves as part of their .SPEC for
creating an RPM.

In my POC scenario I needed to use CentOS 6.5 but created the 2.4
version as well with minor changes from **pskb to *pskb and tested so
that there would be a target compatible with the project latest
version.

man xtables-addons has also been enhanced with a proper explanation of
the target and in particularly the --block-size parameter that always
lacked adequate explanation.


Firstly the diff from the 2.4 tag..

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Jan Engelhardt Jan. 18, 2014, 11:28 a.m. UTC | #1
On Saturday 2014-01-18 11:25, Andrew Smith wrote:
>
>I had a requirement for some proof of concept work I was performing to
>have a very simple layer 3 obfuscation so it was useful to me and 
>perhaps others

If you can give more details, others could actually ascertain this 
usefulness.
1.47 is basically unmaintained but you can send pull requests,
which seems also preferable given Gmail corrupts everybody's patches.

>+{
>+ printf(
>+ "XOR target options:\n"
>+ "    --key <string>\n"
>+ "    --block-size <size>\n"
>+ );
>+}
>+
>+static int
>+xor_parse(int c, char **argv, int invert, unsigned int *flags,
>+                  const void *entry, struct xt_entry_target **target)
>+{
>+ struct xt_xor_info *info = (void *)(*target)->data;
>+        unsigned long v;
>+
>+ switch (c) {
>+ case 'k':
>+                if (strlen(optarg) > sizeof(info->key))
>+ xtables_error(PARAMETER_PROBLEM, "XOR: Maximum key size is
>%zu",sizeof(info->key));
>+ strncpy(info->key, optarg, sizeof(info->key));
>+                *flags |= FLAGS_KEY;
>+ return true;
>+        case 'b':
>+ if (!xtables_strtoul(optarg, NULL, &v, 1, 5))
>+ xtables_param_act(XTF_BAD_VALUE, "XOR",
>+ "--block-size", optarg);
>+                info->block_size = v;
>+                *flags |= FLAGS_BLOCK;
>+                return true;
>+ }
>+ return false;
>+}
>+static void xor_check(unsigned int flags)
>+{
>+ if (!(flags & FLAGS_KEY))
>+ xtables_error(PARAMETER_PROBLEM, "XOR: "
>+ "\"--key\" is required.");
>+ if (!(flags & FLAGS_BLOCK))
>+ xtables_error(PARAMETER_PROBLEM, "XOR: "
>+ "\"--block-size\" is required.");
>+}
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/extensions/Kbuild b/extensions/Kbuild
index c05d5c0..b6c6cff 100644
--- a/extensions/Kbuild
+++ b/extensions/Kbuild
@@ -10,6 +10,7 @@  obj-${build_CHAOS}       += xt_CHAOS.o
 obj-${build_DELUDE}      += xt_DELUDE.o
 obj-${build_DHCPMAC}     += xt_DHCPMAC.o
 obj-${build_DNETMAP}     += xt_DNETMAP.o
+obj-${build_XOR}     += xt_XOR.o
 ifeq (${VERSION},3)
 obj-${build_ECHO}        += xt_ECHO.o
 endif
diff --git a/extensions/Mbuild b/extensions/Mbuild
index 1176948..2fdcdc0 100644
--- a/extensions/Mbuild
+++ b/extensions/Mbuild
@@ -5,6 +5,7 @@  obj-${build_CHAOS}       += libxt_CHAOS.so
 obj-${build_DELUDE}      += libxt_DELUDE.so
 obj-${build_DHCPMAC}     += libxt_DHCPMAC.so libxt_dhcpmac.so
 obj-${build_DNETMAP}     += libxt_DNETMAP.so
+obj-${build_XOR} += libxt_XOR.so
 obj-${build_ECHO}        += libxt_ECHO.so
 obj-${build_IPMARK}      += libxt_IPMARK.so
 obj-${build_LOGMARK}     += libxt_LOGMARK.so
diff --git a/extensions/libxt_XOR.c b/extensions/libxt_XOR.c
new file mode 100644
index 0000000..a029547
--- /dev/null
+++ b/extensions/libxt_XOR.c
@@ -0,0 +1,110 @@ 
+/*
+ * "XOR" target extension for xtables-addons
+ * Copyright © Andrew Smith, 2014
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License; either
+ * version 2 of the License, or any later version, as published by the
+ * Free Software Foundation.
+ */
+#include <netinet/in.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <xtables.h>
+#include <linux/netfilter.h>
+#include "xt_XOR.h"
+#include "compat_user.h"
+
+enum {
+ FLAGS_KEY = 1 << 0,
+        FLAGS_BLOCK = 1 << 1,
+};
+
+static const struct option xor_opts[] = {
+ {.name = "key", .has_arg = true, .val = 'k'},
+        {.name = "block-size", .has_arg = true, .val ='b'},
+ {},
+};
+
+static void xor_help(void)
+{
+ printf(
+ "XOR target options:\n"
+ "    --key <string>\n"
+ "    --block-size <size>\n"
+ );
+}
+
+static int
+xor_parse(int c, char **argv, int invert, unsigned int *flags,
+                  const void *entry, struct xt_entry_target **target)
+{
+ struct xt_xor_info *info = (void *)(*target)->data;
+        unsigned long v;
+
+ switch (c) {
+ case 'k':
+                if (strlen(optarg) > sizeof(info->key))
+ xtables_error(PARAMETER_PROBLEM, "XOR: Maximum key size is
%zu",sizeof(info->key));
+ strncpy(info->key, optarg, sizeof(info->key));
+                *flags |= FLAGS_KEY;
+ return true;
+        case 'b':
+ if (!xtables_strtoul(optarg, NULL, &v, 1, 5))
+ xtables_param_act(XTF_BAD_VALUE, "XOR",
+ "--block-size", optarg);
+                info->block_size = v;
+                *flags |= FLAGS_BLOCK;
+                return true;
+ }
+ return false;
+}
+static void xor_check(unsigned int flags)
+{
+ if (!(flags & FLAGS_KEY))
+ xtables_error(PARAMETER_PROBLEM, "XOR: "
+ "\"--key\" is required.");
+ if (!(flags & FLAGS_BLOCK))
+ xtables_error(PARAMETER_PROBLEM, "XOR: "
+ "\"--block-size\" is required.");
+}
+
+static void
+xor_print(const void *entry, const struct xt_entry_target *target,
+                  int numeric)
+{
+ const struct xt_xor_info *info = (const void *)target->data;
+ printf("  --key %s --block-size %d ",info->key, info->block_size);
+}
+
+static void
+xor_save(const void *entry, const struct xt_entry_target *target)
+{
+ const struct xt_xor_info *info = (const void *)target->data;
+ printf("  --key %s --block-size %d ",info->key, info->block_size);
+}
+
+static struct xtables_target xor_reg[] = {
+ {
+ .version       = XTABLES_VERSION,
+ .name          = "XOR",
+ .revision      = 0,
+ .family        = NFPROTO_IPV4,
+ .size          = XT_ALIGN(sizeof(struct xt_xor_info)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_xor_info)),
+ .help          = xor_help,
+ .parse         = xor_parse,
+ .final_check   = xor_check,
+ .print         = xor_print,
+ .save          = xor_save,
+ .extra_opts    = xor_opts,
+ },
+};
+
+static void _init(void)
+{
+ xtables_register_targets(xor_reg,
+ sizeof(xor_reg) / sizeof(*xor_reg));
+}
diff --git a/extensions/libxt_XOR.man b/extensions/libxt_XOR.man
new file mode 100644
index 0000000..9c44a73
--- /dev/null
+++ b/extensions/libxt_XOR.man
@@ -0,0 +1,47 @@ 
+The XOR target enables the user to encrypt TCP and UDP traffic using
a simple xor encryption.
+.PP
+Usage:
+.PP
+XOR takes two mandatory parameters
+.TP
+\fB\-\-key\fR \fIkeyvalue\fR
+where \fIkeyvalue\fR is a set of characters used in turn to xor with
packet payloads.
+.TP
+\fB\-\-block\-size\fR \fIblocksize\fR
+where \fIblocksize\fR indicates the run-count in the payload of bytes
to be encrypted before using the next character of the key.
+.PP
+Example use to use this target between hosts 1.2.3.5 and 1.2.3.4.
+.PP
+(on host A, 1.2.3.4)
+.br
+iptables \-t mangle \-A OUTPUT -d 1.2.3.5 \-j XOR \-\-key somekey
\-\-block\-size 3
+.br
+iptables \-t mangle \-A INPUT -s 1.2.3.4 \-j XOR \-\-key somekey
\-\-block\-size 3
+.PP
+iptables \-t mangle \-L
+.br
+Chain OUTPUT (policy ACCEPT)
+.br
+target     prot opt source               destination
+.br
+XOR        all  \-\-  anywhere             1.2.3.5            key:
somekey block\-size: 3
+.br
+XOR        all  \-\-  1.2.3.5              anywhere           key:
somekey block\-size: 3
+.PP
+(on host B, 1.2.3.5)
+.br
+iptables \-t mangle \-A OUTPUT \-d 1.2.3.4 \-j XOR \-\-key somekey
\-\-block\-size 3
+.br
+iptables \-t mangle \-A INPUT \-s 1.2.3.5 \-j XOR \-\-key somekey
\-\-block\-size 3
+.PP
+iptables \-t mangle \-L
+.br
+Chain OUTPUT (policy ACCEPT)
+.br
+target     prot opt source               destination
+.br
+XOR        all  \-\-  anywhere             1.2.3.4            key:
somekey block\-size: 3
+.br
+XOR        all  \-\-  1.2.3.4              anywhere           key:
somekey block\-size: 3
+.PP
+xtables\-addons implementation by Andrew Smith
<andrew.smith@appsense.com>, based upon the original module by Tim
Vandermeersch <Tim.Vandermeersch@pandora.be>
diff --git a/extensions/xt_XOR.c b/extensions/xt_XOR.c
new file mode 100644
index 0000000..d426ec3
--- /dev/null
+++ b/extensions/xt_XOR.c
@@ -0,0 +1,126 @@ 
+/* XOR target for xtables-addons
+ * original iptables implementation
+ * (C) 2000 by Tim Vandermeersch <Tim.Vandermeersch@pandora.be>
+ * Based on ipt_TTL.c
+ *
+ * xtables implementation
+ * (C) 2014 by Andrew Smith <andrew.smith@appsense.com>
+ * Version 1.1
+ *
+ * This software is distributed under the terms of GNU GPL
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <net/tcp.h>
+#include <net/checksum.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter/x_tables.h>
+#include "compat_xtables.h"
+#include "xt_XOR.h"
+
+MODULE_AUTHOR("Andrew Smith <andrew.smith@appsense.com>");
+MODULE_DESCRIPTION("IP tables XOR module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_XOR");
+
+static unsigned int
+xt_xor_target(struct sk_buff *pskb, const struct xt_action_param *par)
+{
+ const struct xt_xor_info *info = par->targinfo;
+ struct iphdr *iph;
+ /* To avoid warnings */
+ struct tcphdr *tcph = 0;
+ struct udphdr *udph = 0;
+ int i, j, k;
+ char *buf_pos;
+ int data_len;
+
+ iph = ip_hdr(pskb);
+ /* All of the packet please */
+ if (!skb_make_writable(pskb, ntohs(iph->tot_len)))
+ return NF_DROP;
+
+ /* Writable = new pointers */
+ iph = ip_hdr(pskb);
+ /* Beginning of the packet */
+ buf_pos = pskb->data;
+ /* Advance over the ip header */
+ buf_pos += iph->ihl*4;
+
+ /* Set up lengths and data positioning */
+ if (iph->protocol == IPPROTO_TCP) {
+ tcph = (struct tcphdr *) buf_pos;
+ buf_pos += tcph->doff*4;
+                data_len = ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4;
+ } else if (iph->protocol == IPPROTO_UDP) {
+ udph = (struct udphdr *) buf_pos;
+ buf_pos += sizeof(struct udphdr);
+   data_len = ntohs(udph->len)-8;
+ } else {
+ /* If for some reason we it's not UDP or TCP let another layer handle */
+ return XT_CONTINUE;
+ }
+ /* Apply the key */
+ for (i=0, j=0; i<data_len; ) {
+ for (k=0; k<=info->block_size && i<data_len; k++) {
+ buf_pos[i] ^= info->key[j];
+ i++;
+ }
+ j++;
+ if (info->key[j] == 0x00)
+ j = 0;
+ }
+ return XT_CONTINUE;
+}
+
+static int xt_xor_checkentry(const struct xt_tgchk_param *par)
+{
+ const struct xt_xor_info *info = par->targinfo;
+
+ if (strcmp(par->table, "mangle")) {
+ printk(KERN_WARNING "XOR: can only be called from"
+ "\"mangle\" table, not \"%s\"\n", par->table);
+ return -EINVAL;
+ }
+
+ if (!strcmp(info->key, "")) {
+ printk(KERN_WARNING "XOR: You must specify a key");
+ return -EINVAL;
+ }
+
+ if (info->block_size == 0) {
+ printk(KERN_WARNING "XOR: You must specify a block-size");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct xt_target xt_xor = {
+ .name = "XOR",
+ .revision = 0,
+ .family = NFPROTO_IPV4,
+ .table = "mangle",
+ .target = xt_xor_target,
+        .targetsize = sizeof(struct xt_xor_info),
+ .checkentry = xt_xor_checkentry,
+ .me = THIS_MODULE,
+};
+
+static int __init xor_tg_init(void)
+{
+ return xt_register_target(&xt_xor);
+}
+
+static void __exit xor_target_exit(void)
+{
+ xt_unregister_target(&xt_xor);
+}
+
+module_init(xor_tg_init);
+module_exit(xor_target_exit);
diff --git a/extensions/xt_XOR.h b/extensions/xt_XOR.h
new file mode 100644
index 0000000..ed0c38d
--- /dev/null
+++ b/extensions/xt_XOR.h
@@ -0,0 +1,9 @@ 
+#ifndef _XT_XOR_H
+#define _XT_XOR_H
+
+struct xt_xor_info {
+ char key[30];
+ u_int8_t block_size;
+};
+
+#endif /* _XT_XOR_H */
diff --git a/mconfig b/mconfig
index 74ccd03..3f359dd 100644
--- a/mconfig
+++ b/mconfig
@@ -4,6 +4,7 @@  build_ACCOUNT=m
 build_CHAOS=m
 build_DELUDE=m
 build_DHCPMAC=m
+build_XOR=m
 build_DNETMAP=m
 build_ECHO=m
 build_IPMARK=m



And the diff from the 1.47.1 tag..


diff --git a/extensions/Kbuild b/extensions/Kbuild
index 81a8b30..6749814 100644
--- a/extensions/Kbuild
+++ b/extensions/Kbuild
@@ -9,6 +9,7 @@  obj-${build_ACCOUNT}     += ACCOUNT/
 obj-${build_CHAOS}       += xt_CHAOS.o
 obj-${build_CHECKSUM}    += xt_CHECKSUM.o
 obj-${build_DELUDE}      += xt_DELUDE.o
+obj-${build_XOR}         += xt_XOR.o
 obj-${build_DHCPMAC}     += xt_DHCPMAC.o
 obj-${build_DNETMAP}     += xt_DNETMAP.o
 ifeq (${VERSION},3)
diff --git a/extensions/Mbuild b/extensions/Mbuild
index 1c76e34..ce9ca63 100644
--- a/extensions/Mbuild
+++ b/extensions/Mbuild
@@ -4,6 +4,7 @@  obj-${build_ACCOUNT}     += ACCOUNT/
 obj-${build_CHAOS}       += libxt_CHAOS.so
 obj-${build_CHECKSUM}    += libxt_CHECKSUM.so
 obj-${build_DELUDE}      += libxt_DELUDE.so
+obj-${build_XOR}         += libxt_XOR.so
 obj-${build_DHCPMAC}     += libxt_DHCPMAC.so libxt_dhcpmac.so
 obj-${build_DNETMAP}     += libxt_DNETMAP.so
 obj-${build_ECHO}        += libxt_ECHO.so
diff --git a/extensions/libxt_XOR.c b/extensions/libxt_XOR.c
new file mode 100644
index 0000000..a029547
--- /dev/null
+++ b/extensions/libxt_XOR.c
@@ -0,0 +1,110 @@ 
+/*
+ * "XOR" target extension for xtables-addons
+ * Copyright © Andrew Smith, 2014
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License; either
+ * version 2 of the License, or any later version, as published by the
+ * Free Software Foundation.
+ */
+#include <netinet/in.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <xtables.h>
+#include <linux/netfilter.h>
+#include "xt_XOR.h"
+#include "compat_user.h"
+
+enum {
+ FLAGS_KEY = 1 << 0,
+        FLAGS_BLOCK = 1 << 1,
+};
+
+static const struct option xor_opts[] = {
+ {.name = "key", .has_arg = true, .val = 'k'},
+        {.name = "block-size", .has_arg = true, .val ='b'},
+ {},
+};
+
+static void xor_help(void)
+{
+ printf(
+ "XOR target options:\n"
+ "    --key <string>\n"
+ "    --block-size <size>\n"
+ );
+}
+
+static int
+xor_parse(int c, char **argv, int invert, unsigned int *flags,
+                  const void *entry, struct xt_entry_target **target)
+{
+ struct xt_xor_info *info = (void *)(*target)->data;
+        unsigned long v;
+
+ switch (c) {
+ case 'k':
+                if (strlen(optarg) > sizeof(info->key))
+ xtables_error(PARAMETER_PROBLEM, "XOR: Maximum key size is
%zu",sizeof(info->key));
+ strncpy(info->key, optarg, sizeof(info->key));
+                *flags |= FLAGS_KEY;
+ return true;
+        case 'b':
+ if (!xtables_strtoul(optarg, NULL, &v, 1, 5))
+ xtables_param_act(XTF_BAD_VALUE, "XOR",
+ "--block-size", optarg);
+                info->block_size = v;
+                *flags |= FLAGS_BLOCK;
+                return true;
+ }
+ return false;
+}
+static void xor_check(unsigned int flags)
+{
+ if (!(flags & FLAGS_KEY))
+ xtables_error(PARAMETER_PROBLEM, "XOR: "
+ "\"--key\" is required.");
+ if (!(flags & FLAGS_BLOCK))
+ xtables_error(PARAMETER_PROBLEM, "XOR: "
+ "\"--block-size\" is required.");
+}
+
+static void
+xor_print(const void *entry, const struct xt_entry_target *target,
+                  int numeric)
+{
+ const struct xt_xor_info *info = (const void *)target->data;
+ printf("  --key %s --block-size %d ",info->key, info->block_size);
+}
+
+static void
+xor_save(const void *entry, const struct xt_entry_target *target)
+{
+ const struct xt_xor_info *info = (const void *)target->data;
+ printf("  --key %s --block-size %d ",info->key, info->block_size);
+}
+
+static struct xtables_target xor_reg[] = {
+ {
+ .version       = XTABLES_VERSION,
+ .name          = "XOR",
+ .revision      = 0,
+ .family        = NFPROTO_IPV4,
+ .size          = XT_ALIGN(sizeof(struct xt_xor_info)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_xor_info)),
+ .help          = xor_help,
+ .parse         = xor_parse,
+ .final_check   = xor_check,
+ .print         = xor_print,
+ .save          = xor_save,
+ .extra_opts    = xor_opts,
+ },
+};
+
+static void _init(void)
+{
+ xtables_register_targets(xor_reg,
+ sizeof(xor_reg) / sizeof(*xor_reg));
+}
diff --git a/extensions/libxt_XOR.man b/extensions/libxt_XOR.man
new file mode 100644
index 0000000..9c44a73
--- /dev/null
+++ b/extensions/libxt_XOR.man
@@ -0,0 +1,47 @@ 
+The XOR target enables the user to encrypt TCP and UDP traffic using
a simple xor encryption.
+.PP
+Usage:
+.PP
+XOR takes two mandatory parameters
+.TP
+\fB\-\-key\fR \fIkeyvalue\fR
+where \fIkeyvalue\fR is a set of characters used in turn to xor with
packet payloads.
+.TP
+\fB\-\-block\-size\fR \fIblocksize\fR
+where \fIblocksize\fR indicates the run-count in the payload of bytes
to be encrypted before using the next character of the key.
+.PP
+Example use to use this target between hosts 1.2.3.5 and 1.2.3.4.
+.PP
+(on host A, 1.2.3.4)
+.br
+iptables \-t mangle \-A OUTPUT -d 1.2.3.5 \-j XOR \-\-key somekey
\-\-block\-size 3
+.br
+iptables \-t mangle \-A INPUT -s 1.2.3.4 \-j XOR \-\-key somekey
\-\-block\-size 3
+.PP
+iptables \-t mangle \-L
+.br
+Chain OUTPUT (policy ACCEPT)
+.br
+target     prot opt source               destination
+.br
+XOR        all  \-\-  anywhere             1.2.3.5            key:
somekey block\-size: 3
+.br
+XOR        all  \-\-  1.2.3.5              anywhere           key:
somekey block\-size: 3
+.PP
+(on host B, 1.2.3.5)
+.br
+iptables \-t mangle \-A OUTPUT \-d 1.2.3.4 \-j XOR \-\-key somekey
\-\-block\-size 3
+.br
+iptables \-t mangle \-A INPUT \-s 1.2.3.5 \-j XOR \-\-key somekey
\-\-block\-size 3
+.PP
+iptables \-t mangle \-L
+.br
+Chain OUTPUT (policy ACCEPT)
+.br
+target     prot opt source               destination
+.br
+XOR        all  \-\-  anywhere             1.2.3.4            key:
somekey block\-size: 3
+.br
+XOR        all  \-\-  1.2.3.4              anywhere           key:
somekey block\-size: 3
+.PP
+xtables\-addons implementation by Andrew Smith
<andrew.smith@appsense.com>, based upon the original module by Tim
Vandermeersch <Tim.Vandermeersch@pandora.be>
diff --git a/extensions/xt_XOR.c b/extensions/xt_XOR.c
new file mode 100644
index 0000000..23e2502
--- /dev/null
+++ b/extensions/xt_XOR.c
@@ -0,0 +1,126 @@ 
+/* XOR target for xtables-addons
+ * original iptables implementation
+ * (C) 2000 by Tim Vandermeersch <Tim.Vandermeersch@pandora.be>
+ * Based on ipt_TTL.c
+ *
+ * xtables implementation
+ * (C) 2014 by Andrew Smith <andrew.smith@appsense.com>
+ * Version 1.1
+ *
+ * This software is distributed under the terms of GNU GPL
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <net/tcp.h>
+#include <net/checksum.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter/x_tables.h>
+#include "compat_xtables.h"
+#include "xt_XOR.h"
+
+MODULE_AUTHOR("Andrew Smith <andrew.smith@appsense.com>");
+MODULE_DESCRIPTION("IP tables XOR module");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_XOR");
+
+static unsigned int
+xt_xor_target(struct sk_buff **pskb, const struct xt_action_param *par)
+{
+ const struct xt_xor_info *info = par->targinfo;
+ struct iphdr *iph;
+ /* To avoid warnings */
+ struct tcphdr *tcph = 0;
+ struct udphdr *udph = 0;
+ int i, j, k;
+ char *buf_pos;
+ int data_len;
+
+ iph = ip_hdr(*pskb);
+ /* All of the packet please */
+ if (!skb_make_writable(pskb, ntohs(iph->tot_len)))
+ return NF_DROP;
+
+ /* Writable = new pointers */
+ iph = ip_hdr(*pskb);
+ /* Beginning of the packet */
+ buf_pos = (*pskb)->data;
+ /* Advance over the ip header */
+ buf_pos += iph->ihl*4;
+
+ /* Set up lengths and data positioning */
+ if (iph->protocol == IPPROTO_TCP) {
+ tcph = (struct tcphdr *) buf_pos;
+ buf_pos += tcph->doff*4;
+                data_len = ntohs(iph->tot_len) - iph->ihl*4 - tcph->doff*4;
+ } else if (iph->protocol == IPPROTO_UDP) {
+ udph = (struct udphdr *) buf_pos;
+ buf_pos += sizeof(struct udphdr);
+   data_len = ntohs(udph->len)-8;
+ } else {
+ /* If for some reason we it's not UDP or TCP let another layer handle */
+ return XT_CONTINUE;
+ }
+ /* Apply the key */
+ for (i=0, j=0; i<data_len; ) {
+ for (k=0; k<=info->block_size && i<data_len; k++) {
+ buf_pos[i] ^= info->key[j];
+ i++;
+ }
+ j++;
+ if (info->key[j] == 0x00)
+ j = 0;
+ }
+ return XT_CONTINUE;
+}
+
+static int xt_xor_checkentry(const struct xt_tgchk_param *par)
+{
+ const struct xt_xor_info *info = par->targinfo;
+
+ if (strcmp(par->table, "mangle")) {
+ printk(KERN_WARNING "XOR: can only be called from"
+ "\"mangle\" table, not \"%s\"\n", par->table);
+ return -EINVAL;
+ }
+
+ if (!strcmp(info->key, "")) {
+ printk(KERN_WARNING "XOR: You must specify a key");
+ return -EINVAL;
+ }
+
+ if (info->block_size == 0) {
+ printk(KERN_WARNING "XOR: You must specify a block-size");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct xt_target xt_xor = {
+ .name = "XOR",
+ .revision = 0,
+ .family = NFPROTO_IPV4,
+ .table = "mangle",
+ .target = xt_xor_target,
+        .targetsize = sizeof(struct xt_xor_info),
+ .checkentry = xt_xor_checkentry,
+ .me = THIS_MODULE,
+};
+
+static int __init xor_tg_init(void)
+{
+ return xt_register_target(&xt_xor);
+}
+
+static void __exit xor_target_exit(void)
+{
+ xt_unregister_target(&xt_xor);
+}
+
+module_init(xor_tg_init);
+module_exit(xor_target_exit);
diff --git a/extensions/xt_XOR.h b/extensions/xt_XOR.h
new file mode 100644
index 0000000..ed0c38d
--- /dev/null
+++ b/extensions/xt_XOR.h
@@ -0,0 +1,9 @@ 
+#ifndef _XT_XOR_H
+#define _XT_XOR_H
+
+struct xt_xor_info {
+ char key[30];
+ u_int8_t block_size;
+};
+
+#endif /* _XT_XOR_H */
diff --git a/mconfig b/mconfig
index 4fc664a..8f6b82c 100644
--- a/mconfig
+++ b/mconfig
@@ -4,6 +4,7 @@  build_ACCOUNT=m
 build_CHAOS=m
 build_CHECKSUM=
 build_DELUDE=m
+build_XOR=m
 build_DHCPMAC=m
 build_DNETMAP=m
 build_ECHO=m