/*
 * Copyright (c) 2006 Patrick McHardy <kaber@trash.net>
 *
 * 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.
 *
 * This is a replacement of the old ipt_recent module, which carried the
 * following copyright notice:
 *
 * Author: Stephen Frost <sfrost@snowman.net>
 * Copyright 2002-2003, Stephen Frost, 2.5.x port by laforge@netfilter.org
 */
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/list.h>
#include <linux/random.h>
#include <linux/jhash.h>
#include <linux/bitops.h>
#include <linux/skbuff.h>
#include <linux/inet.h>

#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv4/ipt_recent.h>

MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_DESCRIPTION("IP tables recently seen matching module");
MODULE_LICENSE("GPL");

static unsigned int ip_list_tot = 100;
static unsigned int ip_pkt_list_tot = 20;
static unsigned int ip_list_hash_size = 0;
static unsigned int ip_list_perms = 0644;
static unsigned int ip_list_uid = 0;
static unsigned int ip_list_gid = 0;
module_param(ip_list_tot, uint, 0400);
module_param(ip_pkt_list_tot, uint, 0400);
module_param(ip_list_hash_size, uint, 0400);
module_param(ip_list_perms, uint, 0400);
module_param(ip_list_uid, uint, 0400);
module_param(ip_list_gid, uint, 0400);
MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list");
MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP to remember (max. 255)");
MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs");
MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/ipt_recent/* files");
MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/ipt_recent/* files");
MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/ipt_recent/* files");

struct recent_entry {
	struct list_head	list;
	struct list_head	lru_list;
	__be32			addr;
	u_int8_t		ttl;
	u_int8_t		index;
	u_int16_t		nstamps;
	unsigned long		stamps[0];
};

struct recent_table {
	struct list_head	list;
	char			name[IPT_RECENT_NAME_LEN];
#ifdef CONFIG_PROC_FS
	struct proc_dir_entry	*proc;
#endif
	unsigned int		refcnt;
	unsigned int		entries;
	struct list_head	lru_list;
	struct list_head	iphash[0];
};

static LIST_HEAD(tables);
static DEFINE_SPINLOCK(recent_lock);
static DEFINE_MUTEX(recent_mutex);

#ifdef CONFIG_PROC_FS
static struct proc_dir_entry	*proc_dir;
static struct file_operations	recent_fops;
#endif

static u_int32_t hash_rnd;
static int hash_rnd_initted;

static unsigned int recent_entry_hash(__be32 addr)
{
	if (!hash_rnd_initted) {
		get_random_bytes(&hash_rnd, 4);
		hash_rnd_initted = 1;
	}
	return jhash_1word((__force u32)addr, hash_rnd) & (ip_list_hash_size - 1);
}

static struct recent_entry *
recent_entry_lookup(const struct recent_table *table, __be32 addr, u_int8_t ttl)
{
	struct recent_entry *e;
	unsigned int h;

	h = recent_entry_hash(addr);
	list_for_each_entry(e, &table->iphash[h], list)
		if (e->addr == addr && (ttl == e->ttl || !ttl || !e->ttl))
			return e;
	return NULL;
}

static void recent_entry_remove(struct recent_table *t, struct recent_entry *e)
{
	list_del(&e->list);
	list_del(&e->lru_list);
	kfree(e);
	t->entries--;
}

static struct recent_entry *
recent_entry_init(struct recent_table *t, __be32 addr, u_int8_t ttl)
{
	struct recent_entry *e;

	if (t->entries >= ip_list_tot) {
		e = list_entry(t->lru_list.next, struct recent_entry, lru_list);
		recent_entry_remove(t, e);
	}
	e = kmalloc(sizeof(*e) + sizeof(e->stamps[0]) * ip_pkt_list_tot,
		    GFP_ATOMIC);
	if (e == NULL)
		return NULL;
	e->addr      = addr;
	e->ttl       = ttl;
	e->stamps[0] = jiffies;
	e->nstamps   = 1;
	e->index     = 1;
	list_add_tail(&e->list, &t->iphash[recent_entry_hash(addr)]);
	list_add_tail(&e->lru_list, &t->lru_list);
	t->entries++;
	return e;
}

static void recent_entry_update(struct recent_table *t, struct recent_entry *e)
{
	e->stamps[e->index++] = jiffies;
	if (e->index > e->nstamps)
		e->nstamps = e->index;
	e->index %= ip_pkt_list_tot;
	list_move_tail(&e->lru_list, &t->lru_list);
}

static struct recent_table *recent_table_lookup(const char *name)
{
	struct recent_table *t;

	list_for_each_entry(t, &tables, list)
		if (!strcmp(t->name, name))
			return t;
	return NULL;
}

static void recent_table_flush(struct recent_table *t)
{
	struct recent_entry *e, *next;
	unsigned int i;

	for (i = 0; i < ip_list_hash_size; i++) {
		list_for_each_entry_safe(e, next, &t->iphash[i], list)
			recent_entry_remove(t, e);
	}
}

static int
ipt_recent_match(const struct sk_buff *skb,
		 const struct net_device *in, const struct net_device *out,
		 const struct xt_match *match, const void *matchinfo,
		 int offset, unsigned int protoff, int *hotdrop)
{
	const struct ipt_recent_info *info = matchinfo;
	struct recent_table *t;
	struct recent_entry *e;
	__be32 addr;
	u_int8_t ttl;
	int ret = info->invert;

	if (info->side == IPT_RECENT_DEST)
		addr = skb->nh.iph->daddr;
	else
		addr = skb->nh.iph->saddr;

	ttl = skb->nh.iph->ttl;
	/* use TTL as seen before forwarding */
	if (out && !skb->sk)
		ttl++;

	spin_lock_bh(&recent_lock);
	t = recent_table_lookup(info->name);
	e = recent_entry_lookup(t, addr,
				info->check_set & IPT_RECENT_TTL ? ttl : 0);
	if (e == NULL) {
		if (!(info->check_set & IPT_RECENT_SET))
			goto out;
		e = recent_entry_init(t, addr, ttl);
		if (e == NULL)
			*hotdrop = 1;
		ret ^= 1;
		goto out;
	}

	if (info->check_set & IPT_RECENT_SET)
		ret ^= 1;
	else if (info->check_set & IPT_RECENT_REMOVE) {
		recent_entry_remove(t, e);
		ret ^= 1;
	} else if (info->check_set & (IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) {
		unsigned long t = jiffies - info->seconds * HZ;
		unsigned int i, hits = 0;

		for (i = 0; i < e->nstamps; i++) {
			if (info->seconds && time_after(t, e->stamps[i]))
				continue;
			if (++hits >= info->hit_count) {
				ret ^= 1;
				break;
			}
		}
	}

	if (info->check_set & IPT_RECENT_SET ||
	    (info->check_set & IPT_RECENT_UPDATE && ret)) {
		recent_entry_update(t, e);
		e->ttl = ttl;
	}
out:
	spin_unlock_bh(&recent_lock);
	return ret;
}

static int
ipt_recent_checkentry(const char *tablename, const void *ip,
		      const struct xt_match *match, void *matchinfo,
		      unsigned int hook_mask)
{
	const struct ipt_recent_info *info = matchinfo;
	struct recent_table *t;
	unsigned i;
	int ret = 0;

	if (hweight8(info->check_set &
		     (IPT_RECENT_SET | IPT_RECENT_REMOVE |
		      IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) != 1)
		return 0;
	if ((info->check_set & (IPT_RECENT_SET | IPT_RECENT_REMOVE)) &&
	    (info->seconds || info->hit_count))
		return 0;
	if (info->name[0] == '\0' ||
	    strnlen(info->name, IPT_RECENT_NAME_LEN) == IPT_RECENT_NAME_LEN)
		return 0;

	mutex_lock(&recent_mutex);
	t = recent_table_lookup(info->name);
	if (t != NULL) {
		t->refcnt++;
		ret = 1;
		goto out;
	}

	t = kzalloc(sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size,
		    GFP_KERNEL);
	if (t == NULL)
		goto out;
	t->refcnt = 1;
	strcpy(t->name, info->name);
	INIT_LIST_HEAD(&t->lru_list);
	for (i = 0; i < ip_list_hash_size; i++)
		INIT_LIST_HEAD(&t->iphash[i]);
#ifdef CONFIG_PROC_FS
	t->proc = create_proc_entry(t->name, ip_list_perms, proc_dir);
	if (t->proc == NULL) {
		kfree(t);
		goto out;
	}
	t->proc->proc_fops = &recent_fops;
	t->proc->uid       = ip_list_uid;
	t->proc->gid       = ip_list_gid;
	t->proc->data      = t;
#endif
	spin_lock_bh(&recent_lock);
	list_add_tail(&t->list, &tables);
	spin_unlock_bh(&recent_lock);
	ret = 1;
out:
	mutex_unlock(&recent_mutex);
	return ret;
}

static void
ipt_recent_destroy(const struct xt_match *match, void *matchinfo)
{
	const struct ipt_recent_info *info = matchinfo;
	struct recent_table *t;

	mutex_lock(&recent_mutex);
	t = recent_table_lookup(info->name);
	if (--t->refcnt == 0) {
		spin_lock_bh(&recent_lock);
		list_del(&t->list);
		spin_unlock_bh(&recent_lock);
		recent_table_flush(t);
#ifdef CONFIG_PROC_FS
		remove_proc_entry(t->name, proc_dir);
#endif
		kfree(t);
	}
	mutex_unlock(&recent_mutex);
}

#ifdef CONFIG_PROC_FS
struct recent_iter_state {
	struct recent_table	*table;
	unsigned int		bucket;
};

static void *recent_seq_start(struct seq_file *seq, loff_t *pos)
{
	struct recent_iter_state *st = seq->private;
	struct recent_table *t = st->table;
	struct recent_entry *e;
	loff_t p = *pos;

	spin_lock_bh(&recent_lock);

	for (st->bucket = 0; st->bucket < ip_list_hash_size; st->bucket++) {
		list_for_each_entry(e, &t->iphash[st->bucket], list) {
			if (p-- == 0)
				return e;
		}
	}
	return NULL;
}

static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct recent_iter_state *st = seq->private;
	struct recent_table *t = st->table;
	struct recent_entry *e = v;
	struct list_head *head = e->list.next;

	while (head == &t->iphash[st->bucket]) {
		if (++st->bucket >= ip_list_hash_size)
			return NULL;
		head = t->iphash[st->bucket].next;
	}
	(*pos)++;
	return list_entry(head, struct recent_entry, list);
}

static void recent_seq_stop(struct seq_file *s, void *v)
{
	spin_unlock_bh(&recent_lock);
}

static int recent_seq_show(struct seq_file *seq, void *v)
{
	struct recent_entry *e = v;
	unsigned int i;

	i = (e->index - 1) % ip_pkt_list_tot;
	seq_printf(seq, "src=%u.%u.%u.%u ttl: %u last_seen: %lu oldest_pkt: %u",
		   NIPQUAD(e->addr), e->ttl, e->stamps[i], e->index);
	for (i = 0; i < e->nstamps; i++)
		seq_printf(seq, "%s %lu", i ? "," : "", e->stamps[i]);
	seq_printf(seq, "\n");
	return 0;
}

static struct seq_operations recent_seq_ops = {
	.start		= recent_seq_start,
	.next		= recent_seq_next,
	.stop		= recent_seq_stop,
	.show		= recent_seq_show,
};

static int recent_seq_open(struct inode *inode, struct file *file)
{
	struct proc_dir_entry *pde = PDE(inode);
	struct seq_file *seq;
	struct recent_iter_state *st;
	int ret;

	st = kzalloc(sizeof(*st), GFP_KERNEL);
	if (st == NULL)
		return -ENOMEM;
	ret = seq_open(file, &recent_seq_ops);
	if (ret)
		kfree(st);
	st->table    = pde->data;
	seq          = file->private_data;
	seq->private = st;
	return ret;
}

static ssize_t recent_proc_write(struct file *file, const char __user *input,
				 size_t size, loff_t *loff)
{
	struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode);
	struct recent_table *t = pde->data;
	struct recent_entry *e;
	char buf[sizeof("+255.255.255.255")], *c = buf;
	__be32 addr;
	int add;

	if (size > sizeof(buf))
		size = sizeof(buf);
	if (copy_from_user(buf, input, size))
		return -EFAULT;
	while (isspace(*c))
		c++;

	if (size - (c - buf) < 5)
		return c - buf;
	if (!strncmp(c, "clear", 5)) {
		c += 5;
		spin_lock_bh(&recent_lock);
		recent_table_flush(t);
		spin_unlock_bh(&recent_lock);
		return c - buf;
	}

	switch (*c) {
	case '-':
		add = 0;
		c++;
		break;
	case '+':
		c++;
	default:
		add = 1;
		break;
	}
	addr = in_aton(c);

	spin_lock_bh(&recent_lock);
	e = recent_entry_lookup(t, addr, 0);
	if (e == NULL) {
		if (add)
			recent_entry_init(t, addr, 0);
	} else {
		if (add)
			recent_entry_update(t, e);
		else
			recent_entry_remove(t, e);
	}
	spin_unlock_bh(&recent_lock);
	return size;
}

static struct file_operations recent_fops = {
	.open		= recent_seq_open,
	.read		= seq_read,
	.write		= recent_proc_write,
	.release	= seq_release_private,
	.owner		= THIS_MODULE,
};
#endif /* CONFIG_PROC_FS */

static struct ipt_match recent_match = {
	.name		= "recent",
	.match		= ipt_recent_match,
	.matchsize	= sizeof(struct ipt_recent_info),
	.checkentry	= ipt_recent_checkentry,
	.destroy	= ipt_recent_destroy,
	.me		= THIS_MODULE,
};

static int __init ipt_recent_init(void)
{
	int err;

	if (!ip_list_tot || !ip_pkt_list_tot || ip_pkt_list_tot > 255)
		return -EINVAL;
	ip_list_hash_size = 1 << fls(ip_list_tot);

	err = ipt_register_match(&recent_match);
#ifdef CONFIG_PROC_FS
	if (err)
		return err;
	proc_dir = proc_mkdir("ipt_recent", proc_net);
	if (proc_dir == NULL) {
		ipt_unregister_match(&recent_match);
		err = -ENOMEM;
	}
#endif
	return err;
}

static void __exit ipt_recent_exit(void)
{
	BUG_ON(!list_empty(&tables));
	ipt_unregister_match(&recent_match);
#ifdef CONFIG_PROC_FS
	remove_proc_entry("ipt_recent", proc_net);
#endif
}

module_init(ipt_recent_init);
module_exit(ipt_recent_exit);
