summaryrefslogtreecommitdiff
path: root/release/src/linux/linux/net/ipv4/netfilter/ip_nat_proto_esp.c
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2015-01-03 12:04:58 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2015-01-03 12:04:58 +0100
commit008d0be72b2f160382c6e880765e96b64a050c65 (patch)
tree36f48a98a3815a408e2ce1693dd182af90f80305 /release/src/linux/linux/net/ipv4/netfilter/ip_nat_proto_esp.c
parent611becfb8726c60cb060368541ad98191d4532f5 (diff)
downloadtomato-008d0be72b2f160382c6e880765e96b64a050c65.tar.gz
tomato-008d0be72b2f160382c6e880765e96b64a050c65.tar.bz2
imported original firmware WRT54GL_v4.30.11_11_US
Diffstat (limited to 'release/src/linux/linux/net/ipv4/netfilter/ip_nat_proto_esp.c')
-rwxr-xr-xrelease/src/linux/linux/net/ipv4/netfilter/ip_nat_proto_esp.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/release/src/linux/linux/net/ipv4/netfilter/ip_nat_proto_esp.c b/release/src/linux/linux/net/ipv4/netfilter/ip_nat_proto_esp.c
new file mode 100755
index 00000000..a985539e
--- /dev/null
+++ b/release/src/linux/linux/net/ipv4/netfilter/ip_nat_proto_esp.c
@@ -0,0 +1,220 @@
+/*
+ * ip_nat_proto_esp.c - Version 0.1
+ *
+ * NAT protocol helper module for ESP.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter_ipv4/ip_nat_rule.h>
+#include <linux/netfilter_ipv4/ip_nat_protocol.h>
+#include <linux/netfilter_ipv4/ip_conntrack_proto_esp.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
+MODULE_DESCRIPTION("Netfilter NAT protocol helper module for ESP");
+
+#if 0
+//#define DEBUGP(format, args...) printk(KERN_DEBUG __FILE__ ":" __FUNCTION__": " format, ## args)
+#define DEBUGP printk
+#define DUMP_TUPLE_ESP(x) printk("%u.%u.%u.%u:0x%x -> %u.%u.%u.%u:0x%x\n", \
+ NIPQUAD((x)->src.ip), ntohl((x)->src.u.esp.spi), \
+ NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.esp.spi))
+#else
+#define DUMP_TUPLE_ESP(x)
+#define DEBUGP(x, args...)
+#endif
+
+/* is key in given range between min and max */
+static int
+esp_in_range(const struct ip_conntrack_tuple *tuple,
+ enum ip_nat_manip_type maniptype,
+ const union ip_conntrack_manip_proto *min,
+ const union ip_conntrack_manip_proto *max)
+{
+ unsigned int spi;
+ DEBUGP("esp_in_range entry.\n");
+ return 0;
+ if (maniptype == IP_NAT_MANIP_SRC)
+ spi = tuple->src.u.esp.spi;
+ else
+ spi = tuple->dst.u.esp.spi;
+
+ DUMP_TUPLE_ESP(tuple);
+
+ return (ntohl(spi) >= ntohl(min->esp.spi) &&
+ ntohl(spi) <= ntohl(max->esp.spi));
+
+}
+
+/* generate unique tuple ... */
+static int
+esp_unique_tuple(struct ip_conntrack_tuple *tuple,
+ const struct ip_nat_range *range,
+ enum ip_nat_manip_type maniptype,
+ const struct ip_conntrack *conntrack)
+{
+ u_int32_t min, i, range_size;
+ u_int32_t key = 0, *spi = NULL;
+ DEBUGP("esp_unique_tuple entry.\n");
+ return 1;
+ DUMP_TUPLE_ESP(tuple);
+
+ if (maniptype == IP_NAT_MANIP_SRC)
+ spi = &tuple->src.u.esp.spi;
+ else
+ spi = &tuple->dst.u.esp.spi;
+
+ /*range is to do fast search*/
+ if (! (range->flags & IP_NAT_RANGE_PROTO_SPECIFIED))
+ {
+ DEBUGP("NATing ESP (ct = %p)\n",conntrack);
+ min = 1;
+ range_size = 0xffffffff;
+ }
+ else
+ {
+ min = ntohl(range->min.esp.spi);
+ range_size = ntohl(range->max.esp.spi) - min + 1;
+ }
+
+ DEBUGP("min = %u, range_size = %u\n", min, range_size);
+
+ for (i = 0; i < range_size; i++, key++) {
+ *spi = htonl(min + key % range_size);
+ if (!ip_nat_used_tuple(tuple, conntrack))
+ return 1;
+ }
+
+ DEBUGP("%p: no NAT mapping\n", conntrack);
+
+ return 0;
+}
+
+/* manipulate a ESP packet according to maniptype */
+static void
+esp_manip_pkt(struct iphdr *iph, size_t len,
+ const struct ip_conntrack_manip *manip,
+ enum ip_nat_manip_type maniptype)
+{
+ struct esp_hdr *esph = (struct esp_hdr *)((u_int32_t *)iph+iph->ihl);
+ u_int32_t *old_ip;
+ u_int32_t *old_spi =NULL;
+ u_int32_t sip = 0, dip =0,ret = 0;
+ DEBUGP("\n@@@@ %s @@@@\n", __FUNCTION__);
+
+
+ DEBUGP("dir =[%d] manip [%u.%u.%u.%u] spi[%x].\n "
+ "ip_header sip[%u.%u.%u.%u]dip[%u.%u.%u.%u].\n"
+ "spi[0x%x] seq[%u].\n",
+ maniptype,NIPQUAD(manip->ip),ntohl(manip->u.esp.spi),
+ NIPQUAD(iph->saddr),NIPQUAD(iph->daddr),ntohl(esph->spi),ntohl(esph->seq));
+
+ /*keep data to tuple struct*/
+ if (maniptype == IP_NAT_MANIP_SRC)
+ {
+ /* Get rid of dst ip / spi */
+ old_ip = &iph->daddr; //here orignal ip header
+ old_spi =&esph->spi;
+ }
+ else
+ {
+ ret = esp_packet_in(iph,&sip,&dip);
+ if (ret == NF_ACCEPT)
+ {
+ DEBUGP("found !! sip[%u.%u.%u.%u]dip[%u.%u.%u.%u]\n",
+ NIPQUAD(sip),NIPQUAD(dip));
+ old_ip = &dip; //here orignal ip header
+ old_spi = &esph->spi;
+ }
+ else
+ {
+ DEBUGP("Not found !! sip[%u.%u.%u.%u]dip[%u.%u.%u.%u]\n",
+ NIPQUAD(sip),NIPQUAD(dip));
+ /* Get rid of dst ip / spi */
+ old_ip = &iph->daddr; //here orignal ip header
+ old_spi = &esph->spi;
+ }
+ }
+
+}
+
+/* print out a nat tuple */
+static unsigned int
+esp_print(char *buffer,
+ const struct ip_conntrack_tuple *match,
+ const struct ip_conntrack_tuple *mask)
+{
+ unsigned int len = 0;
+ DEBUGP("esp_print entry.\n");
+ DEBUGP("match.....\n");
+ DUMP_TUPLE_ESP(match);
+ DEBUGP("mask.....\n");
+ DUMP_TUPLE_ESP(mask);
+ DEBUGP("end.....\n\n");
+ return 0;
+ if (mask->dst.u.esp.spi)
+ len += sprintf(buffer + len, "dst spi=[0x%x]",
+ ntohl(match->dst.u.esp.spi));
+
+ if (mask->src.u.esp.spi)
+ len += sprintf(buffer + len, "src spi=0x%x ",
+ ntohl(match->src.u.esp.spi));
+
+ return len;
+}
+
+/* print a range of keys */
+static unsigned int
+esp_print_range(char *buffer, const struct ip_nat_range *range)
+{
+ DEBUGP("esp_print_range entry.\n");
+ return 0;
+ if (range->min.esp.spi != 0
+ || range->max.esp.spi != 0xFFFFFFFF)
+ {
+ if (range->min.esp.spi == range->max.esp.spi)
+ return sprintf(buffer, "ESP SPI 0x%x ",
+ ntohl(range->min.esp.spi));
+ else
+ return sprintf(buffer, "ESP SPI 0x%u-0x%u ",
+ ntohl(range->min.esp.spi),
+ ntohl(range->max.esp.spi));
+ } else
+ return 0;
+}
+
+/* nat helper struct */
+static struct ip_nat_protocol esp =
+{
+ { NULL, NULL },
+ "ESP",
+ IPPROTO_ESP,
+ esp_manip_pkt,
+ esp_in_range,
+ esp_unique_tuple,
+ esp_print,
+ esp_print_range
+};
+
+static int __init init(void)
+{
+
+ if (ip_nat_protocol_register(&esp))
+ return -EIO;
+
+ DEBUGP("init IP_nat_proto_esp register.\n");
+ return 0;
+}
+
+static void __exit fini(void)
+{
+ DEBUGP("uninit IP_nat_proto_esp register.\n");
+ ip_nat_protocol_unregister(&esp);
+}
+
+module_init(init);
+module_exit(fini);
+