/*
 * 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;
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_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");


struct recent_entry {
	struct list_head	list;
	struct list_head	lru_list;
	u_int32_t		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(u_int32_t addr)
{
	if (!hash_rnd_initted) {
		get_random_bytes(&hash_rnd, 4);
		hash_rnd_initted = 1;
	}
	return jhash_1word(addr, hash_rnd) & (ip_list_hash_size - 1);
}

static struct recent_entry *
recent_entry_lookup(const struct recent_table *table, u_int32_t 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, u_int32_t 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;
	u_int32_t 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 matchsize, 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->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,
		   unsigned int matchsize)
{
	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;
	u_int32_t 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);
