HEAD
====
+Changes
+- remove unmaintained RAWSNAT/RAWDNAT code
v2.3 (2013-06-18)
endif
obj-${build_IPMARK} += xt_IPMARK.o
obj-${build_LOGMARK} += xt_LOGMARK.o
-obj-${build_RAWNAT} += xt_RAWNAT.o iptable_rawpost.o
-ifneq (${CONFIG_IP6_NF_IPTABLES},)
-obj-${build_RAWNAT} += ip6table_rawpost.o
-endif
obj-${build_SYSRQ} += xt_SYSRQ.o
obj-${build_TARPIT} += xt_TARPIT.o
obj-${build_condition} += xt_condition.o
obj-${build_ECHO} += libxt_ECHO.so
obj-${build_IPMARK} += libxt_IPMARK.so
obj-${build_LOGMARK} += libxt_LOGMARK.so
-obj-${build_RAWNAT} += libxt_RAWDNAT.so libxt_RAWSNAT.so
obj-${build_SYSRQ} += libxt_SYSRQ.so
obj-${build_TARPIT} += libxt_TARPIT.so
obj-${build_condition} += libxt_condition.so
+++ /dev/null
-#ifndef XTA_COMPAT_RAWPOST_H
-#define XTA_COMPAT_RAWPOST_H 1
-
-typedef struct sk_buff sk_buff_t;
-
-#endif /* XTA_COMPAT_RAWPOST_H */
+++ /dev/null
-/*
- * rawpost table for ip6_tables
- * written by Jan Engelhardt, 2008 - 2009
- * placed in the Public Domain
- */
-#include <linux/module.h>
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <net/ip.h>
-#include "compat_xtables.h"
-#include "compat_rawpost.h"
-
-enum {
- RAWPOST_VALID_HOOKS = 1 << NF_INET_POST_ROUTING,
-};
-
-static struct {
- struct ip6t_replace repl;
- struct ip6t_standard entries[1];
- struct ip6t_error term;
-} rawpost6_initial __initdata = {
- .repl = {
- .name = "rawpost",
- .valid_hooks = RAWPOST_VALID_HOOKS,
- .num_entries = 2,
- .size = sizeof(struct ip6t_standard) +
- sizeof(struct ip6t_error),
- .hook_entry = {
- [NF_INET_POST_ROUTING] = 0,
- },
- .underflow = {
- [NF_INET_POST_ROUTING] = 0,
- },
- },
- .entries = {
- IP6T_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
- },
- .term = IP6T_ERROR_INIT, /* ERROR */
-};
-
-static struct xt_table *rawpost6_ptable;
-
-static struct xt_table rawpost6_itable = {
- .name = "rawpost",
- .af = NFPROTO_IPV6,
- .valid_hooks = RAWPOST_VALID_HOOKS,
- .me = THIS_MODULE,
-};
-
-static unsigned int rawpost6_hook_fn(unsigned int hook, sk_buff_t *skb,
- const struct net_device *in, const struct net_device *out,
- int (*okfn)(struct sk_buff *))
-{
- return ip6t_do_table(skb, hook, in, out, rawpost6_ptable);
-}
-
-static struct nf_hook_ops rawpost6_hook_ops __read_mostly = {
- .hook = rawpost6_hook_fn,
- .pf = NFPROTO_IPV6,
- .hooknum = NF_INET_POST_ROUTING,
- .priority = NF_IP6_PRI_LAST,
- .owner = THIS_MODULE,
-};
-
-static int __init rawpost6_table_init(void)
-{
- int ret;
-
- rawpost6_ptable = ip6t_register_table(&init_net, &rawpost6_itable,
- &rawpost6_initial.repl);
- if (IS_ERR(rawpost6_ptable))
- return PTR_ERR(rawpost6_ptable);
-
- ret = nf_register_hook(&rawpost6_hook_ops);
- if (ret < 0)
- goto out;
-
- return ret;
-
- out:
- ip6t_unregister_table(rawpost6_ptable);
- return ret;
-}
-
-static void __exit rawpost6_table_exit(void)
-{
- nf_unregister_hook(&rawpost6_hook_ops);
- ip6t_unregister_table(rawpost6_ptable);
-}
-
-module_init(rawpost6_table_init);
-module_exit(rawpost6_table_exit);
-MODULE_AUTHOR("Jan Engelhardt ");
-MODULE_LICENSE("GPL");
+++ /dev/null
-/*
- * rawpost table for ip_tables
- * written by Jan Engelhardt, 2008 - 2009
- * placed in the Public Domain
- */
-#include <linux/module.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/version.h>
-#include <net/ip.h>
-#include "compat_xtables.h"
-#include "compat_rawpost.h"
-
-enum {
- RAWPOST_VALID_HOOKS = 1 << NF_INET_POST_ROUTING,
-};
-
-static struct {
- struct ipt_replace repl;
- struct ipt_standard entries[1];
- struct ipt_error term;
-} rawpost4_initial __initdata = {
- .repl = {
- .name = "rawpost",
- .valid_hooks = RAWPOST_VALID_HOOKS,
- .num_entries = 2,
- .size = sizeof(struct ipt_standard) +
- sizeof(struct ipt_error),
- .hook_entry = {
- [NF_INET_POST_ROUTING] = 0,
- },
- .underflow = {
- [NF_INET_POST_ROUTING] = 0,
- },
- },
- .entries = {
- IPT_STANDARD_INIT(NF_ACCEPT), /* POST_ROUTING */
- },
- .term = IPT_ERROR_INIT, /* ERROR */
-};
-
-static struct xt_table *rawpost4_ptable;
-
-static struct xt_table rawpost4_itable = {
- .name = "rawpost",
- .af = NFPROTO_IPV4,
- .valid_hooks = RAWPOST_VALID_HOOKS,
- .me = THIS_MODULE,
-};
-
-static unsigned int rawpost4_hook_fn(unsigned int hook, sk_buff_t *skb,
- const struct net_device *in, const struct net_device *out,
- int (*okfn)(struct sk_buff *))
-{
- return ipt_do_table(skb, hook, in, out, rawpost4_ptable);
-}
-
-static struct nf_hook_ops rawpost4_hook_ops __read_mostly = {
- .hook = rawpost4_hook_fn,
- .pf = NFPROTO_IPV4,
- .hooknum = NF_INET_POST_ROUTING,
- .priority = NF_IP_PRI_LAST,
- .owner = THIS_MODULE,
-};
-
-static int __init rawpost4_table_init(void)
-{
- int ret;
-
- rawpost4_ptable = ipt_register_table(&init_net, &rawpost4_itable,
- &rawpost4_initial.repl);
- if (IS_ERR(rawpost4_ptable))
- return PTR_ERR(rawpost4_ptable);
-
- ret = nf_register_hook(&rawpost4_hook_ops);
- if (ret < 0)
- goto out;
-
- return ret;
-
- out:
- ipt_unregister_table(rawpost4_ptable);
- return ret;
-}
-
-static void __exit rawpost4_table_exit(void)
-{
- nf_unregister_hook(&rawpost4_hook_ops);
- ipt_unregister_table(rawpost4_ptable);
-}
-
-module_init(rawpost4_table_init);
-module_exit(rawpost4_table_exit);
-MODULE_DESCRIPTION("Xtables: rawpost table for use with RAWNAT");
-MODULE_AUTHOR("Jan Engelhardt ");
-MODULE_LICENSE("GPL");
+++ /dev/null
-/*
- * "RAWNAT" target extension for iptables
- * Copyright © Jan Engelhardt, 2008 - 2009
- *
- * 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_RAWNAT.h"
-#include "compat_user.h"
-
-enum {
- FLAGS_TO = 1 << 0,
-};
-
-static const struct option rawdnat_tg_opts[] = {
- {.name = "to-destination", .has_arg = true, .val = 't'},
- {},
-};
-
-static void rawdnat_tg_help(void)
-{
- printf(
-"RAWDNAT target options:\n"
-" --to-destination addr[/mask] Address or network to map to\n"
-);
-}
-
-static int
-rawdnat_tg4_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **target)
-{
- struct xt_rawnat_tginfo *info = (void *)(*target)->data;
- struct in_addr *a;
- unsigned int mask;
- char *end;
-
- switch (c) {
- case 't':
- info->mask = 32;
- end = strchr(optarg, '/');
- if (end != NULL) {
- *end++ = '\0';
- if (!xtables_strtoui(end, NULL, &mask, 0, 32))
- xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
- "--to-destination", optarg);
- info->mask = mask;
- }
- a = xtables_numeric_to_ipaddr(optarg);
- if (a == NULL)
- xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
- "--to-destination", optarg);
- memcpy(&info->addr.in, a, sizeof(*a));
- *flags |= FLAGS_TO;
- return true;
- }
- return false;
-}
-
-static int
-rawdnat_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **target)
-{
- struct xt_rawnat_tginfo *info = (void *)(*target)->data;
- struct in6_addr *a;
- unsigned int mask;
- char *end;
-
- switch (c) {
- case 't':
- info->mask = 128;
- end = strchr(optarg, '/');
- if (end != NULL) {
- *end++ = '\0';
- if (!xtables_strtoui(end, NULL, &mask, 0, 128))
- xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
- "--to-destination", optarg);
- info->mask = mask;
- }
- a = xtables_numeric_to_ip6addr(optarg);
- if (a == NULL)
- xtables_param_act(XTF_BAD_VALUE, "RAWDNAT",
- "--to-destination", optarg);
- memcpy(&info->addr.in6, a, sizeof(*a));
- *flags |= FLAGS_TO;
- return true;
- }
- return false;
-}
-
-static void rawdnat_tg_check(unsigned int flags)
-{
- if (!(flags & FLAGS_TO))
- xtables_error(PARAMETER_PROBLEM, "RAWDNAT: "
- "\"--to-destination\" is required.");
-}
-
-static void
-rawdnat_tg4_save(const void *entry, const struct xt_entry_target *target)
-{
- const struct xt_rawnat_tginfo *info = (const void *)target->data;
-
- printf(" --to-destination %s/%u ",
- xtables_ipaddr_to_numeric(&info->addr.in),
- info->mask);
-}
-
-static void
-rawdnat_tg4_print(const void *entry, const struct xt_entry_target *target,
- int numeric)
-{
- printf(" -j RAWDNAT");
- rawdnat_tg4_save(entry, target);
-}
-
-static void
-rawdnat_tg6_save(const void *entry, const struct xt_entry_target *target)
-{
- const struct xt_rawnat_tginfo *info = (const void *)target->data;
-
- printf(" --to-destination %s/%u ",
- xtables_ip6addr_to_numeric(&info->addr.in6),
- info->mask);
-}
-
-static void
-rawdnat_tg6_print(const void *entry, const struct xt_entry_target *target,
- int numeric)
-{
- printf(" -j RAWDNAT");
- rawdnat_tg6_save(entry, target);
-}
-
-static struct xtables_target rawdnat_tg_reg[] = {
- {
- .version = XTABLES_VERSION,
- .name = "RAWDNAT",
- .revision = 0,
- .family = NFPROTO_IPV4,
- .size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
- .help = rawdnat_tg_help,
- .parse = rawdnat_tg4_parse,
- .final_check = rawdnat_tg_check,
- .print = rawdnat_tg4_print,
- .save = rawdnat_tg4_save,
- .extra_opts = rawdnat_tg_opts,
- },
- {
- .version = XTABLES_VERSION,
- .name = "RAWDNAT",
- .revision = 0,
- .family = NFPROTO_IPV6,
- .size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
- .help = rawdnat_tg_help,
- .parse = rawdnat_tg6_parse,
- .final_check = rawdnat_tg_check,
- .print = rawdnat_tg6_print,
- .save = rawdnat_tg6_save,
- .extra_opts = rawdnat_tg_opts,
- },
-};
-
-static void _init(void)
-{
- xtables_register_targets(rawdnat_tg_reg,
- sizeof(rawdnat_tg_reg) / sizeof(*rawdnat_tg_reg));
-}
+++ /dev/null
-.PP
-The \fBRAWDNAT\fR target will rewrite the destination address in the IP header,
-much like the \fBNETMAP\fR target.
-.TP
-\fB\-\-to\-destination\fR \fIaddr\fR[\fB/\fR\fImask\fR]
-Network address to map to. The resulting address will be constructed the
-following way: All "one" bits in the \fImask\fR are filled in from the new
-\fIaddress\fR. All bits that are zero in the mask are filled in from the
-original address.
-.PP
-See the \fBRAWSNAT\fR help entry for examples and constraints.
+++ /dev/null
-/*
- * "RAWNAT" target extension for iptables
- * Copyright © Jan Engelhardt, 2008 - 2009
- *
- * 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_RAWNAT.h"
-#include "compat_user.h"
-
-enum {
- FLAGS_TO = 1 << 0,
-};
-
-static const struct option rawsnat_tg_opts[] = {
- {.name = "to-source", .has_arg = true, .val = 't'},
- {},
-};
-
-static void rawsnat_tg_help(void)
-{
- printf(
-"RAWSNAT target options:\n"
-" --to-source addr[/mask] Address or network to map to\n"
-);
-}
-
-static int
-rawsnat_tg4_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **target)
-{
- struct xt_rawnat_tginfo *info = (void *)(*target)->data;
- struct in_addr *a;
- unsigned int mask;
- char *end;
-
- switch (c) {
- case 't':
- info->mask = 32;
- end = strchr(optarg, '/');
- if (end != NULL) {
- *end++ = '\0';
- if (!xtables_strtoui(end, NULL, &mask, 0, 32))
- xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
- "--to-source", optarg);
- info->mask = mask;
- }
- a = xtables_numeric_to_ipaddr(optarg);
- if (a == NULL)
- xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
- "--to-source", optarg);
- memcpy(&info->addr.in, a, sizeof(*a));
- *flags |= FLAGS_TO;
- return true;
- }
- return false;
-}
-
-static int
-rawsnat_tg6_parse(int c, char **argv, int invert, unsigned int *flags,
- const void *entry, struct xt_entry_target **target)
-{
- struct xt_rawnat_tginfo *info = (void *)(*target)->data;
- struct in6_addr *a;
- unsigned int mask;
- char *end;
-
- switch (c) {
- case 't':
- info->mask = 128;
- end = strchr(optarg, '/');
- if (end != NULL) {
- *end++ = '\0';
- if (!xtables_strtoui(end, NULL, &mask, 0, 128))
- xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
- "--to-source", optarg);
- info->mask = mask;
- }
- a = xtables_numeric_to_ip6addr(optarg);
- if (a == NULL)
- xtables_param_act(XTF_BAD_VALUE, "RAWSNAT",
- "--to-source", optarg);
- memcpy(&info->addr.in6, a, sizeof(*a));
- *flags |= FLAGS_TO;
- return true;
- }
- return false;
-}
-
-static void rawsnat_tg_check(unsigned int flags)
-{
- if (!(flags & FLAGS_TO))
- xtables_error(PARAMETER_PROBLEM, "RAWSNAT: "
- "\"--to-source\" is required.");
-}
-
-static void
-rawsnat_tg4_save(const void *entry, const struct xt_entry_target *target)
-{
- const struct xt_rawnat_tginfo *info = (const void *)target->data;
-
- printf(" --to-source %s/%u ",
- xtables_ipaddr_to_numeric(&info->addr.in),
- info->mask);
-}
-
-static void
-rawsnat_tg6_save(const void *entry, const struct xt_entry_target *target)
-{
- const struct xt_rawnat_tginfo *info = (const void *)target->data;
-
- printf(" --to-source %s/%u ",
- xtables_ip6addr_to_numeric(&info->addr.in6),
- info->mask);
-}
-
-static void
-rawsnat_tg4_print(const void *entry, const struct xt_entry_target *target,
- int numeric)
-{
- printf(" -j RAWSNAT");
- rawsnat_tg4_save(entry, target);
-}
-
-static void
-rawsnat_tg6_print(const void *entry, const struct xt_entry_target *target,
- int numeric)
-{
- printf(" -j RAWSNAT");
- rawsnat_tg6_save(entry, target);
-}
-
-static struct xtables_target rawsnat_tg_reg[] = {
- {
- .version = XTABLES_VERSION,
- .name = "RAWSNAT",
- .revision = 0,
- .family = NFPROTO_IPV4,
- .size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
- .help = rawsnat_tg_help,
- .parse = rawsnat_tg4_parse,
- .final_check = rawsnat_tg_check,
- .print = rawsnat_tg4_print,
- .save = rawsnat_tg4_save,
- .extra_opts = rawsnat_tg_opts,
- },
- {
- .version = XTABLES_VERSION,
- .name = "RAWSNAT",
- .revision = 0,
- .family = NFPROTO_IPV6,
- .size = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
- .userspacesize = XT_ALIGN(sizeof(struct xt_rawnat_tginfo)),
- .help = rawsnat_tg_help,
- .parse = rawsnat_tg6_parse,
- .final_check = rawsnat_tg_check,
- .print = rawsnat_tg6_print,
- .save = rawsnat_tg6_save,
- .extra_opts = rawsnat_tg_opts,
- },
-};
-
-static void _init(void)
-{
- xtables_register_targets(rawsnat_tg_reg,
- sizeof(rawsnat_tg_reg) / sizeof(*rawsnat_tg_reg));
-}
+++ /dev/null
-.PP
-The \fBRAWSNAT\fR and \fBRAWDNAT\fP targets provide stateless network address
-translation.
-.PP
-The \fBRAWSNAT\fR target will rewrite the source address in the IP header, much
-like the \fBNETMAP\fP target. \fBRAWSNAT\fP (and \fBRAWDNAT\fP) may only be
-used in the \fBraw\fP or \fBrawpost\fP tables, but can be used in all chains,
-which makes it possible to change the source address either when the packet
-enters the machine or when it leaves it. The reason for this table constraint
-is that RAWNAT must happen outside of connection tracking.
-.TP
-\fB\-\-to\-source\fR \fIaddr\fR[\fB/\fR\fImask\fR]
-Network address to map to. The resulting address will be constructed the
-following way: All "one" bits in the \fImask\fR are filled in from the new
-\fIaddress\fR. All bits that are zero in the mask are filled in from the
-original address.
-.PP
-As an example, changing the destination for packets forwarded from an internal
-LAN to the internet:
-.IP
-\-t raw \-A PREROUTING \-i lan0 \-d 212.201.100.135 \-j RAWDNAT \-\-to\-destination 199.181.132.250;
-\-t rawpost \-A POSTROUTING \-o lan0 \-s 199.181.132.250 \-j RAWSNAT \-\-to\-source 212.201.100.135;
-.PP
-Note that changing addresses may influence the route selection! Specifically,
-it statically NATs packets, not connections, like the normal DNAT/SNAT targets
-would do. Also note that it can transform already-NATed connections \(em as
-said, it is completely external to Netfilter's connection tracking/NAT.
-.PP
-If the machine itself generates packets that are to be rawnat-ed, you need a
-rule in the OUTPUT chain instead, just like you would with the stateful NAT
-targets.
-.PP
-It may be necessary that in doing so, you also need an extra RAWSNAT rule, to
-override the automatic source address selection that the routing code does
-before passing packets to iptables. If the connecting socket has not been
-explicitly bound to an address, as is the common mode of operation, the address
-that will be chosen is the primary address of the device through which the
-packet would be routed with its initial destination address - the address as
-seen before any RAWNAT takes place.
+++ /dev/null
-/*
- * "RAWNAT" target extension for Xtables - untracked NAT
- * Copyright © Jan Engelhardt, 2008 - 2009
- *
- * 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 <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-#include <linux/version.h>
-#include <linux/netfilter.h>
-#include <linux/netfilter/nf_conntrack_common.h>
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <net/ip.h>
-#include <net/ipv6.h>
-#include "compat_xtables.h"
-#include "xt_RAWNAT.h"
-#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
-# define WITH_IPV6 1
-#endif
-
-static inline __be32
-remask(__be32 addr, __be32 repl, unsigned int shift)
-{
- uint32_t mask = (shift == 32) ? 0 : (~(uint32_t)0 >> shift);
- return htonl((ntohl(addr) & mask) | (ntohl(repl) & ~mask));
-}
-
-#ifdef WITH_IPV6
-static void
-rawnat_ipv6_mask(__be32 *addr, const __be32 *repl, unsigned int mask)
-{
- switch (mask) {
- case 0:
- break;
- case 1 ... 31:
- addr[0] = remask(addr[0], repl[0], mask);
- break;
- case 32:
- addr[0] = repl[0];
- break;
- case 33 ... 63:
- addr[0] = repl[0];
- addr[1] = remask(addr[1], repl[1], mask - 32);
- break;
- case 64:
- addr[0] = repl[0];
- addr[1] = repl[1];
- break;
- case 65 ... 95:
- addr[0] = repl[0];
- addr[1] = repl[1];
- addr[2] = remask(addr[2], repl[2], mask - 64);
- case 96:
- addr[0] = repl[0];
- addr[1] = repl[1];
- addr[2] = repl[2];
- break;
- case 97 ... 127:
- addr[0] = repl[0];
- addr[1] = repl[1];
- addr[2] = repl[2];
- addr[3] = remask(addr[3], repl[3], mask - 96);
- break;
- case 128:
- addr[0] = repl[0];
- addr[1] = repl[1];
- addr[2] = repl[2];
- addr[3] = repl[3];
- break;
- }
-}
-#endif
-
-static void rawnat4_update_l4(struct sk_buff *skb, __be32 oldip, __be32 newip)
-{
- struct iphdr *iph = ip_hdr(skb);
- void *transport_hdr = (void *)iph + ip_hdrlen(skb);
- struct tcphdr *tcph;
- struct udphdr *udph;
- bool cond;
-
- switch (iph->protocol) {
- case IPPROTO_TCP:
- tcph = transport_hdr;
- inet_proto_csum_replace4(&tcph->check, skb, oldip, newip, true);
- break;
- case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
- udph = transport_hdr;
- cond = udph->check != 0;
- cond |= skb->ip_summed == CHECKSUM_PARTIAL;
- if (cond) {
- inet_proto_csum_replace4(&udph->check, skb,
- oldip, newip, true);
- if (udph->check == 0)
- udph->check = CSUM_MANGLED_0;
- }
- break;
- }
-}
-
-static unsigned int rawnat4_writable_part(const struct iphdr *iph)
-{
- unsigned int wlen = iph->ihl * 4;
-
- switch (iph->protocol) {
- case IPPROTO_TCP:
- wlen += sizeof(struct tcphdr);
- break;
- case IPPROTO_UDP:
- wlen += sizeof(struct udphdr);
- break;
- }
- return wlen;
-}
-
-static unsigned int
-rawsnat_tg4(struct sk_buff **pskb, const struct xt_action_param *par)
-{
- const struct xt_rawnat_tginfo *info = par->targinfo;
- struct iphdr *iph;
- __be32 new_addr;
-
- iph = ip_hdr(*pskb);
- new_addr = remask(iph->saddr, info->addr.ip, info->mask);
- if (iph->saddr == new_addr)
- return XT_CONTINUE;
-
- if (!skb_make_writable(pskb, rawnat4_writable_part(iph)))
- return NF_DROP;
-
- iph = ip_hdr(*pskb);
- csum_replace4(&iph->check, iph->saddr, new_addr);
- rawnat4_update_l4(*pskb, iph->saddr, new_addr);
- iph->saddr = new_addr;
- return XT_CONTINUE;
-}
-
-static unsigned int
-rawdnat_tg4(struct sk_buff **pskb, const struct xt_action_param *par)
-{
- const struct xt_rawnat_tginfo *info = par->targinfo;
- struct iphdr *iph;
- __be32 new_addr;
-
- iph = ip_hdr(*pskb);
- new_addr = remask(iph->daddr, info->addr.ip, info->mask);
- if (iph->daddr == new_addr)
- return XT_CONTINUE;
-
- if (!skb_make_writable(pskb, rawnat4_writable_part(iph)))
- return NF_DROP;
-
- iph = ip_hdr(*pskb);
- csum_replace4(&iph->check, iph->daddr, new_addr);
- rawnat4_update_l4(*pskb, iph->daddr, new_addr);
- iph->daddr = new_addr;
- return XT_CONTINUE;
-}
-
-#ifdef WITH_IPV6
-static bool rawnat6_prepare_l4(struct sk_buff **pskb, unsigned int *l4offset,
- unsigned int *l4proto)
-{
- static const unsigned int types[] =
- {IPPROTO_TCP, IPPROTO_UDP, IPPROTO_UDPLITE};
- unsigned int i;
- int err;
-
- *l4proto = NEXTHDR_MAX;
-
- for (i = 0; i < ARRAY_SIZE(types); ++i) {
- err = ipv6_find_hdr(*pskb, l4offset, types[i], NULL, NULL);
- if (err >= 0) {
- *l4proto = types[i];
- break;
- }
- if (err != -ENOENT)
- return false;
- }
-
- switch (*l4proto) {
- case IPPROTO_TCP:
- if (!skb_make_writable(pskb, *l4offset + sizeof(struct tcphdr)))
- return false;
- break;
- case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
- if (!skb_make_writable(pskb, *l4offset + sizeof(struct udphdr)))
- return false;
- break;
- }
-
- return true;
-}
-
-static void rawnat6_update_l4(struct sk_buff *skb, unsigned int l4proto,
- unsigned int l4offset, const struct in6_addr *oldip,
- const struct in6_addr *newip)
-{
- const struct ipv6hdr *iph = ipv6_hdr(skb);
- struct tcphdr *tcph;
- struct udphdr *udph;
- unsigned int i;
- bool cond;
-
- switch (l4proto) {
- case IPPROTO_TCP:
- tcph = (void *)iph + l4offset;
- for (i = 0; i < 4; ++i)
- inet_proto_csum_replace4(&tcph->check, skb,
- oldip->s6_addr32[i], newip->s6_addr32[i], true);
- break;
- case IPPROTO_UDP:
- case IPPROTO_UDPLITE:
- udph = (void *)iph + l4offset;
- cond = udph->check;
- cond |= skb->ip_summed == CHECKSUM_PARTIAL;
- if (cond) {
- for (i = 0; i < 4; ++i)
- inet_proto_csum_replace4(&udph->check, skb,
- oldip->s6_addr32[i],
- newip->s6_addr32[i], true);
- if (udph->check == 0)
- udph->check = CSUM_MANGLED_0;
- }
- break;
- }
-}
-
-static unsigned int
-rawsnat_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
-{
- const struct xt_rawnat_tginfo *info = par->targinfo;
- unsigned int l4offset = 0, l4proto;
- struct ipv6hdr *iph;
- struct in6_addr new_addr;
-
- iph = ipv6_hdr(*pskb);
- memcpy(&new_addr, &iph->saddr, sizeof(new_addr));
- rawnat_ipv6_mask(new_addr.s6_addr32, info->addr.ip6, info->mask);
- if (ipv6_addr_cmp(&iph->saddr, &new_addr) == 0)
- return XT_CONTINUE;
- if (!rawnat6_prepare_l4(pskb, &l4offset, &l4proto))
- return NF_DROP;
- iph = ipv6_hdr(*pskb);
- rawnat6_update_l4(*pskb, l4proto, l4offset, &iph->saddr, &new_addr);
- memcpy(&iph->saddr, &new_addr, sizeof(new_addr));
- return XT_CONTINUE;
-}
-
-static unsigned int
-rawdnat_tg6(struct sk_buff **pskb, const struct xt_action_param *par)
-{
- const struct xt_rawnat_tginfo *info = par->targinfo;
- unsigned int l4offset = 0, l4proto;
- struct ipv6hdr *iph;
- struct in6_addr new_addr;
-
- iph = ipv6_hdr(*pskb);
- memcpy(&new_addr, &iph->daddr, sizeof(new_addr));
- rawnat_ipv6_mask(new_addr.s6_addr32, info->addr.ip6, info->mask);
- if (ipv6_addr_cmp(&iph->daddr, &new_addr) == 0)
- return XT_CONTINUE;
- if (!rawnat6_prepare_l4(pskb, &l4offset, &l4proto))
- return NF_DROP;
- iph = ipv6_hdr(*pskb);
- rawnat6_update_l4(*pskb, l4proto, l4offset, &iph->daddr, &new_addr);
- memcpy(&iph->daddr, &new_addr, sizeof(new_addr));
- return XT_CONTINUE;
-}
-#endif
-
-static int rawnat_tg_check(const struct xt_tgchk_param *par)
-{
- if (strcmp(par->table, "raw") == 0 ||
- strcmp(par->table, "rawpost") == 0)
- return 0;
-
- printk(KERN_ERR KBUILD_MODNAME " may only be used in the \"raw\" or "
- "\"rawpost\" table.\n");
- return -EINVAL;
-}
-
-static struct xt_target rawnat_tg_reg[] __read_mostly = {
- {
- .name = "RAWSNAT",
- .revision = 0,
- .family = NFPROTO_IPV4,
- .target = rawsnat_tg4,
- .targetsize = sizeof(struct xt_rawnat_tginfo),
- .checkentry = rawnat_tg_check,
- .me = THIS_MODULE,
- },
-#ifdef WITH_IPV6
- {
- .name = "RAWSNAT",
- .revision = 0,
- .family = NFPROTO_IPV6,
- .target = rawsnat_tg6,
- .targetsize = sizeof(struct xt_rawnat_tginfo),
- .checkentry = rawnat_tg_check,
- .me = THIS_MODULE,
- },
-#endif
- {
- .name = "RAWDNAT",
- .revision = 0,
- .family = NFPROTO_IPV4,
- .target = rawdnat_tg4,
- .targetsize = sizeof(struct xt_rawnat_tginfo),
- .checkentry = rawnat_tg_check,
- .me = THIS_MODULE,
- },
-#ifdef WITH_IPV6
- {
- .name = "RAWDNAT",
- .revision = 0,
- .family = NFPROTO_IPV6,
- .target = rawdnat_tg6,
- .targetsize = sizeof(struct xt_rawnat_tginfo),
- .checkentry = rawnat_tg_check,
- .me = THIS_MODULE,
- },
-#endif
-};
-
-static int __init rawnat_tg_init(void)
-{
- return xt_register_targets(rawnat_tg_reg, ARRAY_SIZE(rawnat_tg_reg));
-}
-
-static void __exit rawnat_tg_exit(void)
-{
- xt_unregister_targets(rawnat_tg_reg, ARRAY_SIZE(rawnat_tg_reg));
-}
-
-module_init(rawnat_tg_init);
-module_exit(rawnat_tg_exit);
-MODULE_AUTHOR("Jan Engelhardt ");
-MODULE_DESCRIPTION("Xtables: conntrack-less raw NAT");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("ipt_RAWSNAT");
-MODULE_ALIAS("ipt_RAWDNAT");
-MODULE_ALIAS("ip6t_RAWSNAT");
-MODULE_ALIAS("ip6t_RAWDNAT");
+++ /dev/null
-#ifndef _LINUX_NETFILTER_XT_TARGET_RAWNAT
-#define _LINUX_NETFILTER_XT_TARGET_RAWNAT 1
-
-struct xt_rawnat_tginfo {
- union nf_inet_addr addr;
- __u8 mask;
-};
-
-#endif /* _LINUX_NETFILTER_XT_TARGET_RAWNAT */
build_ECHO=m
build_IPMARK=m
build_LOGMARK=m
-build_RAWNAT=m
build_SYSRQ=m
build_TARPIT=m
build_condition=m