/* 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_IP_PRE_ROUTING ||
			hooknum == NF_IP_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_IP_PRE_ROUTING | 1 << NF_IP_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);

