summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'extensions')
-rw-r--r--extensions/libxt_CONNMARK.c2
-rw-r--r--extensions/libxt_SYNPROXY.man64
-rw-r--r--extensions/libxt_connmark.c2
-rw-r--r--extensions/libxt_mangle.c388
-rw-r--r--extensions/libxt_osf.c2
-rw-r--r--extensions/libxt_set.man2
6 files changed, 456 insertions, 4 deletions
diff --git a/extensions/libxt_CONNMARK.c b/extensions/libxt_CONNMARK.c
index 5d5351e3..42cf2079 100644
--- a/extensions/libxt_CONNMARK.c
+++ b/extensions/libxt_CONNMARK.c
@@ -17,7 +17,7 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdbool.h>
#include <stdint.h>
diff --git a/extensions/libxt_SYNPROXY.man b/extensions/libxt_SYNPROXY.man
new file mode 100644
index 00000000..25325fc2
--- /dev/null
+++ b/extensions/libxt_SYNPROXY.man
@@ -0,0 +1,64 @@
+This target will process TCP three-way-handshake parallel in netfilter
+context to protect either local or backend system. This target requires
+connection tracking because sequence numbers need to be translated.
+.TP
+\fB\-\-mss\fP \fImaximum segment size\fP
+Maximum segment size announced to clients. This must match the backend.
+.TP
+\fB\-\-wscale\fP \fIwindow scale\fP
+Window scale announced to clients. This must match the backend.
+.TP
+\fB\-\-sack\-perm\fP
+Pass client selective acknowledgement option to backend (will be disabled
+if not present).
+.TP
+\fB\-\-timestamps\fP
+Pass client timestamp option to backend (will be disabled if not present,
+also needed for selective acknowledgement and window scaling).
+.PP
+Example:
+.PP
+Determine tcp options used by backend, from an external system
+.IP
+tcpdump -pni eth0 -c 1 'tcp[tcpflags] == (tcp-syn|tcp-ack)'
+.br
+ port 80 &
+.br
+telnet 192.0.2.42 80
+.br
+18:57:24.693307 IP 192.0.2.42.80 > 192.0.2.43.48757:
+.br
+ Flags [S.], seq 360414582, ack 788841994, win 14480,
+.br
+ options [mss 1460,sackOK,
+.br
+ TS val 1409056151 ecr 9690221,
+.br
+ nop,wscale 9],
+.br
+ length 0
+.PP
+Switch tcp_loose mode off, so conntrack will mark out\-of\-flow
+packets as state INVALID.
+.IP
+echo 0 > /proc/sys/net/netfilter/nf_conntrack_tcp_loose
+.PP
+Make SYN packets untracked
+.IP
+iptables \-t raw \-A PREROUTING \-i eth0 \-p tcp \-\-dport 80
+ \-\-syn \-j CT \-\-notrack
+.PP
+Catch UNTRACKED (SYN packets) and INVALID (3WHS ACK packets) states
+and send them to SYNPROXY. This rule will respond to SYN packets with
+SYN+ACK syncookies, create ESTABLISHED for valid client response (3WHS ACK
+packets) and drop incorrect cookies. Flags combinations not expected
+during 3WHS will not match and continue (e.g. SYN+FIN, SYN+ACK).
+.IP
+iptables \-A INPUT \-i eth0 \-p tcp \-\-dport 80
+ \-m state \-\-state UNTRACKED,INVALID \-j SYNPROXY
+ \-\-sack\-perm \-\-timestamp \-\-mss 1460 \-\-wscale 9
+.PP
+Drop invalid packets, this will be out\-of\-flow packets that were not
+matched by SYNPROXY.
+.IP
+iptables \-A INPUT \-i eth0 \-p tcp \-\-dport 80 \-m state \-\-state INVALID \-j DROP
diff --git a/extensions/libxt_connmark.c b/extensions/libxt_connmark.c
index 6f1d5323..95477dea 100644
--- a/extensions/libxt_connmark.c
+++ b/extensions/libxt_connmark.c
@@ -17,7 +17,7 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdbool.h>
#include <stdint.h>
diff --git a/extensions/libxt_mangle.c b/extensions/libxt_mangle.c
new file mode 100644
index 00000000..4b20feb3
--- /dev/null
+++ b/extensions/libxt_mangle.c
@@ -0,0 +1,388 @@
+/*
+ * 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.
+ *
+ * Authors:
+ * Libarptc code from: Bart De Schuymer <bdschuym@pandora.be>
+ * Port to libxtables: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
+ */
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <getopt.h>
+#include <errno.h>
+#include <netinet/ether.h>
+
+#include <xtables.h>
+#include <linux/netfilter_arp/arpt_mangle.h>
+
+static void mangle_help(void)
+{
+ printf(
+"mangle target options:\n"
+"--mangle-ip-s IP address\n"
+"--mangle-ip-d IP address\n"
+"--mangle-mac-s MAC address\n"
+"--mangle-mac-d MAC address\n"
+"--mangle-target target (DROP, CONTINUE or ACCEPT -- default is ACCEPT)\n"
+ );
+}
+
+enum {
+ MANGLE_IPS = 0,
+ MANGLE_IPT = 1,
+ MANGLE_DEVS = 2,
+ MANGLE_DEVT = 3,
+ MANGLE_TARGET = 4,
+};
+
+static const struct xt_option_entry mangle_opts[] = {
+ { .name = "mangle-ip-s", .id = MANGLE_IPS, .type = XTTYPE_STRING },
+ { .name = "mangle-ip-d", .id = MANGLE_IPT, .type = XTTYPE_STRING },
+ { .name = "mangle-mac-s", .id = MANGLE_DEVS, .type = XTTYPE_STRING },
+ { .name = "mangle-mac-d", .id = MANGLE_DEVT, .type = XTTYPE_STRING },
+ { .name = "mangle-target", .id = MANGLE_TARGET,
+ .type = XTTYPE_STRING },
+ XTOPT_TABLEEND,
+};
+
+
+static struct in_addr *network_to_addr(const char *name)
+{
+ struct netent *net;
+ static struct in_addr addr;
+
+ if ((net = getnetbyname(name)) != NULL) {
+ if (net->n_addrtype != AF_INET)
+ return (struct in_addr *) NULL;
+ addr.s_addr = htonl((unsigned long) net->n_net);
+ return &addr;
+ }
+
+ return (struct in_addr *) NULL;
+}
+
+static void inaddrcpy(struct in_addr *dst, struct in_addr *src)
+{
+ dst->s_addr = src->s_addr;
+}
+
+static struct in_addr *host_to_addr(const char *name, unsigned int *naddr)
+{
+ struct hostent *host;
+ struct in_addr *addr;
+ unsigned int i;
+
+ *naddr = 0;
+ if ((host = gethostbyname(name)) != NULL) {
+ if (host->h_addrtype != AF_INET ||
+ host->h_length != sizeof(struct in_addr))
+ return (struct in_addr *) NULL;
+
+ while (host->h_addr_list[*naddr] != (char *) NULL)
+ (*naddr)++;
+ addr = xtables_calloc(*naddr, sizeof(struct in_addr));
+ for (i = 0; i < *naddr; i++)
+ inaddrcpy(&(addr[i]),
+ (struct in_addr *) host->h_addr_list[i]);
+ return addr;
+ }
+
+ return (struct in_addr *) NULL;
+}
+
+static int string_to_number(const char *s, unsigned int min,
+ unsigned int max, unsigned int *ret)
+{
+ long number;
+ char *end;
+
+ /* Handle hex, octal, etc. */
+ errno = 0;
+ number = strtol(s, &end, 0);
+ if (*end == '\0' && end != s) {
+ /* we parsed a number, let's see if we want this */
+ if (errno != ERANGE && min <= number && number <= max) {
+ *ret = number;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static struct in_addr *dotted_to_addr(const char *dotted)
+{
+ static struct in_addr addr;
+ unsigned char *addrp;
+ char *p, *q;
+ unsigned int onebyte;
+ int i;
+ char buf[20];
+
+ /* copy dotted string, because we need to modify it */
+ strncpy(buf, dotted, sizeof(buf) - 1);
+ addrp = (unsigned char *) &(addr.s_addr);
+
+ p = buf;
+ for (i = 0; i < 3; i++) {
+ if ((q = strchr(p, '.')) == NULL)
+ return (struct in_addr *) NULL;
+
+ *q = '\0';
+ if (string_to_number(p, 0, 255, &onebyte) == -1)
+ return (struct in_addr *) NULL;
+
+ addrp[i] = (unsigned char) onebyte;
+ p = q + 1;
+ }
+
+ /* we've checked 3 bytes, now we check the last one */
+ if (string_to_number(p, 0, 255, &onebyte) == -1)
+ return (struct in_addr *) NULL;
+
+ addrp[3] = (unsigned char) onebyte;
+
+ return &addr;
+}
+
+static struct in_addr *parse_hostnetwork(const char *name,
+ unsigned int *naddrs)
+{
+ struct in_addr *addrp, *addrptmp;
+
+ if ((addrptmp = dotted_to_addr(name)) != NULL ||
+ (addrptmp = network_to_addr(name)) != NULL) {
+ addrp = xtables_malloc(sizeof(struct in_addr));
+ inaddrcpy(addrp, addrptmp);
+ *naddrs = 1;
+ return addrp;
+ }
+ if ((addrp = host_to_addr(name, naddrs)) != NULL)
+ return addrp;
+
+ xtables_error(PARAMETER_PROBLEM, "host/network `%s' not found", name);
+}
+
+static void mangle_parse(struct xt_option_call *cb)
+{
+ const struct arpt_entry *e = cb->xt_entry;
+ struct arpt_mangle *mangle = cb->data;
+ struct in_addr *ipaddr;
+ struct ether_addr *macaddr;
+
+ /* mangle target is by default "ACCEPT". Setting it here,
+ * since original arpt_mangle.c init() no longer exists*/
+ mangle->target = NF_ACCEPT;
+
+ xtables_option_parse(cb);
+ switch (cb->entry->id) {
+ case MANGLE_IPS:
+/*
+ if (e->arp.arpln_mask == 0)
+ xtables_error(PARAMETER_PROBLEM, "no pln defined");
+
+ if (e->arp.invflags & ARPT_INV_ARPPLN)
+ xtables_error(PARAMETER_PROBLEM,
+ "! pln not allowed for --mangle-ip-s");
+*/
+/*
+ if (e->arp.arpln != 4)
+ xtables_error(PARAMETER_PROBLEM, "only pln=4 supported");
+*/
+ {
+ unsigned int nr;
+ ipaddr = parse_hostnetwork(cb->arg, &nr);
+ }
+ mangle->u_s.src_ip.s_addr = ipaddr->s_addr;
+ free(ipaddr);
+ mangle->flags |= ARPT_MANGLE_SIP;
+ break;
+ case MANGLE_IPT:
+/*
+ if (e->arp.arpln_mask == 0)
+ xtables_error(PARAMETER_PROBLEM, "no pln defined");
+
+ if (e->arp.invflags & ARPT_INV_ARPPLN)
+ xtables_error(PARAMETER_PROBLEM,
+ "! pln not allowed for --mangle-ip-d");
+*/
+/*
+ if (e->arp.arpln != 4)
+ xtables_error(PARAMETER_PROBLEM, "only pln=4 supported");
+*/
+ {
+ unsigned int nr;
+ ipaddr = parse_hostnetwork(cb->arg, &nr);
+ }
+ mangle->u_t.tgt_ip.s_addr = ipaddr->s_addr;
+ free(ipaddr);
+ mangle->flags |= ARPT_MANGLE_TIP;
+ break;
+ case MANGLE_DEVS:
+ if (e->arp.arhln_mask == 0)
+ xtables_error(PARAMETER_PROBLEM,
+ "no --h-length defined");
+ if (e->arp.invflags & ARPT_INV_ARPHLN)
+ xtables_error(PARAMETER_PROBLEM,
+ "! --h-length not allowed for "
+ "--mangle-mac-s");
+ if (e->arp.arhln != 6)
+ xtables_error(PARAMETER_PROBLEM,
+ "only --h-length 6 supported");
+ macaddr = ether_aton(cb->arg);
+ if (macaddr == NULL)
+ xtables_error(PARAMETER_PROBLEM, "invalid source MAC");
+ memcpy(mangle->src_devaddr, macaddr, e->arp.arhln);
+ mangle->flags |= ARPT_MANGLE_SDEV;
+ break;
+ case MANGLE_DEVT:
+ if (e->arp.arhln_mask == 0)
+ xtables_error(PARAMETER_PROBLEM,
+ "no --h-length defined");
+ if (e->arp.invflags & ARPT_INV_ARPHLN)
+ xtables_error(PARAMETER_PROBLEM,
+ "! hln not allowed for --mangle-mac-d");
+ if (e->arp.arhln != 6)
+ xtables_error(PARAMETER_PROBLEM,
+ "only --h-length 6 supported");
+ macaddr = ether_aton(cb->arg);
+ if (macaddr == NULL)
+ xtables_error(PARAMETER_PROBLEM, "invalid target MAC");
+ memcpy(mangle->tgt_devaddr, macaddr, e->arp.arhln);
+ mangle->flags |= ARPT_MANGLE_TDEV;
+ break;
+ case MANGLE_TARGET:
+ if (!strcmp(cb->arg, "DROP"))
+ mangle->target = NF_DROP;
+ else if (!strcmp(cb->arg, "ACCEPT"))
+ mangle->target = NF_ACCEPT;
+ else if (!strcmp(cb->arg, "CONTINUE"))
+ mangle->target = ARPT_CONTINUE;
+ else
+ xtables_error(PARAMETER_PROBLEM,
+ "bad target for --mangle-target");
+ break;
+ }
+}
+
+static void mangle_fcheck(struct xt_fcheck_call *cb)
+{
+}
+
+static char *addr_to_dotted(const struct in_addr *addrp)
+{
+ static char buf[20];
+ const unsigned char *bytep;
+
+ bytep = (const unsigned char *) &(addrp->s_addr);
+ sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
+ return buf;
+}
+
+static char *addr_to_host(const struct in_addr *addr)
+{
+ struct hostent *host;
+
+ if ((host = gethostbyaddr((char *) addr,
+ sizeof(struct in_addr), AF_INET)) != NULL)
+ return (char *) host->h_name;
+
+ return (char *) NULL;
+}
+
+static char *addr_to_network(const struct in_addr *addr)
+{
+ struct netent *net;
+
+ if ((net = getnetbyaddr((long) ntohl(addr->s_addr), AF_INET)) != NULL)
+ return (char *) net->n_name;
+
+ return (char *) NULL;
+}
+
+static char *addr_to_anyname(const struct in_addr *addr)
+{
+ char *name;
+
+ if ((name = addr_to_host(addr)) != NULL ||
+ (name = addr_to_network(addr)) != NULL)
+ return name;
+
+ return addr_to_dotted(addr);
+}
+
+static void print_mac(const unsigned char *mac, int l)
+{
+ int j;
+
+ for (j = 0; j < l; j++)
+ printf("%02x%s", mac[j],
+ (j==l-1) ? "" : ":");
+}
+
+static void mangle_print(const void *ip, const struct xt_entry_target *target,
+ int numeric)
+{
+ const struct arpt_mangle *m = (const void *)target;
+ char buf[100];
+
+ if (m->flags & ARPT_MANGLE_SIP) {
+ if (numeric)
+ sprintf(buf, "%s", addr_to_dotted(&(m->u_s.src_ip)));
+ else
+ sprintf(buf, "%s", addr_to_anyname(&(m->u_s.src_ip)));
+ printf("--mangle-ip-s %s ", buf);
+ }
+ if (m->flags & ARPT_MANGLE_SDEV) {
+ printf("--mangle-mac-s ");
+ print_mac((unsigned char *)m->src_devaddr, 6);
+ printf(" ");
+ }
+ if (m->flags & ARPT_MANGLE_TIP) {
+ if (numeric)
+ sprintf(buf, "%s", addr_to_dotted(&(m->u_t.tgt_ip)));
+ else
+ sprintf(buf, "%s", addr_to_anyname(&(m->u_t.tgt_ip)));
+ printf("--mangle-ip-d %s ", buf);
+ }
+ if (m->flags & ARPT_MANGLE_TDEV) {
+ printf("--mangle-mac-d ");
+ print_mac((unsigned char *)m->tgt_devaddr, 6);
+ printf(" ");
+ }
+ if (m->target != NF_ACCEPT) {
+ printf("--mangle-target ");
+ if (m->target == NF_DROP)
+ printf("DROP ");
+ else
+ printf("CONTINUE ");
+ }
+}
+
+static void mangle_save(const void *ip, const struct xt_entry_target *target)
+{
+}
+
+static struct xtables_target mangle_tg_reg = {
+ .family = NFPROTO_ARP,
+ .name = "mangle",
+ .version = XTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct arpt_mangle)),
+ .userspacesize = XT_ALIGN(sizeof(struct arpt_mangle)),
+ .help = mangle_help,
+ .x6_parse = mangle_parse,
+ .x6_fcheck = mangle_fcheck,
+ .print = mangle_print,
+ .save = mangle_save,
+ .x6_options = mangle_opts,
+};
+
+void _init(void)
+{
+ xtables_register_target(&mangle_tg_reg);
+}
diff --git a/extensions/libxt_osf.c b/extensions/libxt_osf.c
index 52dba474..496b4805 100644
--- a/extensions/libxt_osf.c
+++ b/extensions/libxt_osf.c
@@ -14,7 +14,7 @@
*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
diff --git a/extensions/libxt_set.man b/extensions/libxt_set.man
index 7012ef2e..dbc1586b 100644
--- a/extensions/libxt_set.man
+++ b/extensions/libxt_set.man
@@ -43,7 +43,7 @@ packet counter of the element is less than the given value as well.
If the packet is matched an element in the set, match only if the
packet counter of the element is greater than the given value as well.
.TP
-[\fB!\fP] \fB\-bytes\-eq\fP \fIvalue\fP
+[\fB!\fP] \fB\-\-bytes\-eq\fP \fIvalue\fP
If the packet is matched an element in the set, match only if the
byte counter of the element matches the given value too.
.TP