/* Same.  Just like SNAT, only try to make the connections
 * 	  between client A and server B always have the same source ip.
 *
 * (C) 2000 Paul `Rusty' Russell
 * (C) 2001 Martin Josefsson
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/timer.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netdevice.h>
#include <linux/if.h>
#include <linux/inetdevice.h>
#include <net/protocol.h>
#include <net/checksum.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter/x_tables.h>
#include <net/netfilter/nf_nat_rule.h>
#include <linux/netfilter_ipv4/ipt_SAME.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Martin Josefsson <gandalf@wlug.westbo.se>");
MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip");

static bool
same_check(const char *tablename,
	      const void *e,
	      const struct xt_target *target,
	      void *targinfo,
	      unsigned int hook_mask)
{
	unsigned int count, countess, rangeip, index = 0;
	struct ipt_same_info *mr = targinfo;

	mr->ipnum = 0;

	if (mr->rangesize < 1) {
		pr_debug("same_check: need at least one dest range.\n");
		return false;
	}
	if (mr->rangesize > IPT_SAME_MAX_RANGE) {
		pr_debug("same_check: too many ranges specified, maximum "
			 "is %u ranges\n", IPT_SAME_MAX_RANGE);
		return false;
	}
	for (count = 0; count < mr->rangesize; count++) {
		if (ntohl(mr->range[count].min_ip) >
				ntohl(mr->range[count].max_ip)) {
			pr_debug("same_check: min_ip is larger than max_ip in "
				 "range `%u.%u.%u.%u-%u.%u.%u.%u'.\n",
				 NIPQUAD(mr->range[count].min_ip),
				 NIPQUAD(mr->range[count].max_ip));
			return false;
		}
		if (!(mr->range[count].flags & IP_NAT_RANGE_MAP_IPS)) {
			pr_debug("same_check: bad MAP_IPS.\n");
			return false;
		}
		rangeip = (ntohl(mr->range[count].max_ip) -
					ntohl(mr->range[count].min_ip) + 1);
		mr->ipnum += rangeip;

		pr_debug("same_check: range %u, ipnum = %u\n", count, rangeip);
	}
	pr_debug("same_check: total ipaddresses = %u\n", mr->ipnum);

	mr->iparray = kmalloc((sizeof(u_int32_t) * mr->ipnum), GFP_KERNEL);
	if (!mr->iparray) {
		pr_debug("same_check: Couldn't allocate %Zu bytes "
			 "for %u ipaddresses!\n",
			 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
		return false;
	}
	pr_debug("same_check: Allocated %Zu bytes for %u ipaddresses.\n",
		 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);

	for (count = 0; count < mr->rangesize; count++) {
		for (countess = ntohl(mr->range[count].min_ip);
				countess <= ntohl(mr->range[count].max_ip);
					countess++) {
			mr->iparray[index] = countess;
			pr_debug("same_check: Added ipaddress `%u.%u.%u.%u' "
				 "in index %u.\n", HIPQUAD(countess), index);
			index++;
		}
	}
	return true;
}

static void
same_destroy(const struct xt_target *target, void *targinfo)
{
	struct ipt_same_info *mr = targinfo;

	kfree(mr->iparray);

	pr_debug("same_destroy: Deallocated %Zu bytes for %u ipaddresses.\n",
		 (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
}

static unsigned int
same_target(struct sk_buff *skb,
		const struct net_device *in,
		const struct net_device *out,
		unsigned int hooknum,
		const struct xt_target *target,
		const void *targinfo)
{
	struct nf_conn *ct;
	enum ip_conntrack_info ctinfo;
	u_int32_t tmpip, aindex;
	__be32 new_ip;
	const struct ipt_same_info *same = targinfo;
	struct nf_nat_range newrange;
	const struct nf_conntrack_tuple *t;

	NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING ||
			hooknum == NF_INET_POST_ROUTING);
	ct = nf_ct_get(skb, &ctinfo);

	t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;

	/* Base new source on real src ip and optionally dst ip,
	   giving some hope for consistency across reboots.
	   Here we calculate the index in same->iparray which
	   holds the ipaddress we should use */

	tmpip = ntohl(t->src.u3.ip);

	if (!(same->info & IPT_SAME_NODST))
		tmpip += ntohl(t->dst.u3.ip);
	aindex = tmpip % same->ipnum;

	new_ip = htonl(same->iparray[aindex]);

	pr_debug("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, "
		 "new src=%u.%u.%u.%u\n",
		 NIPQUAD(t->src.u3.ip), NIPQUAD(t->dst.u3.ip), NIPQUAD(new_ip));

	/* Transfer from original range. */
	newrange = ((struct nf_nat_range)
		{ same->range[0].flags, new_ip, new_ip,
		  /* FIXME: Use ports from correct range! */
		  same->range[0].min, same->range[0].max });

	/* Hand modified range to generic setup. */
	return nf_nat_setup_info(ct, &newrange, hooknum);
}

static struct xt_target same_reg __read_mostly = {
	.name		= "SAME",
	.family		= AF_INET,
	.target		= same_target,
	.targetsize	= sizeof(struct ipt_same_info),
	.table		= "nat",
	.hooks		= (1 << NF_INET_PRE_ROUTING) |
			  (1 << NF_INET_POST_ROUTING),
	.checkentry	= same_check,
	.destroy	= same_destroy,
	.me		= THIS_MODULE,
};

static int __init ipt_same_init(void)
{
	return xt_register_target(&same_reg);
}

static void __exit ipt_same_fini(void)
{
	xt_unregister_target(&same_reg);
}

module_init(ipt_same_init);
module_exit(ipt_same_fini);

