/*
 * Copyright (c) 2003+ Evgeniy Polyakov <zbr@ioremap.net>
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <linux/module.h>
#include <linux/kernel.h>

#include <linux/if.h>
#include <linux/inetdevice.h>
#include <linux/ip.h>
#include <linux/list.h>
#include <linux/rculist.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/tcp.h>

#include <net/ip.h>
#include <net/tcp.h>

#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/x_tables.h>
#include <net/netfilter/nf_log.h>
#include <linux/netfilter/xt_osf.h>

struct xt_osf_finger {
	struct rcu_head			rcu_head;
	struct list_head		finger_entry;
	struct xt_osf_user_finger	finger;
};

enum osf_fmatch_states {
	/* Packet does not match the fingerprint */
	FMATCH_WRONG = 0,
	/* Packet matches the fingerprint */
	FMATCH_OK,
	/* Options do not match the fingerprint, but header does */
	FMATCH_OPT_WRONG,
};

/*
 * Indexed by dont-fragment bit.
 * It is the only constant value in the fingerprint.
 */
static struct list_head xt_osf_fingers[2];

static const struct nla_policy xt_osf_policy[OSF_ATTR_MAX + 1] = {
	[OSF_ATTR_FINGER]	= { .len = sizeof(struct xt_osf_user_finger) },
};

static void xt_osf_finger_free_rcu(struct rcu_head *rcu_head)
{
	struct xt_osf_finger *f = container_of(rcu_head, struct xt_osf_finger, rcu_head);

	kfree(f);
}

static int xt_osf_add_callback(struct sock *ctnl, struct sk_buff *skb,
			       const struct nlmsghdr *nlh,
			       const struct nlattr * const osf_attrs[])
{
	struct xt_osf_user_finger *f;
	struct xt_osf_finger *kf = NULL, *sf;
	int err = 0;

	if (!osf_attrs[OSF_ATTR_FINGER])
		return -EINVAL;

	if (!(nlh->nlmsg_flags & NLM_F_CREATE))
		return -EINVAL;

	f = nla_data(osf_attrs[OSF_ATTR_FINGER]);

	kf = kmalloc(sizeof(struct xt_osf_finger), GFP_KERNEL);
	if (!kf)
		return -ENOMEM;

	memcpy(&kf->finger, f, sizeof(struct xt_osf_user_finger));

	list_for_each_entry(sf, &xt_osf_fingers[!!f->df], finger_entry) {
		if (memcmp(&sf->finger, f, sizeof(struct xt_osf_user_finger)))
			continue;

		kfree(kf);
		kf = NULL;

		if (nlh->nlmsg_flags & NLM_F_EXCL)
			err = -EEXIST;
		break;
	}

	/*
	 * We are protected by nfnl mutex.
	 */
	if (kf)
		list_add_tail_rcu(&kf->finger_entry, &xt_osf_fingers[!!f->df]);

	return err;
}

static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb,
				  const struct nlmsghdr *nlh,
				  const struct nlattr * const osf_attrs[])
{
	struct xt_osf_user_finger *f;
	struct xt_osf_finger *sf;
	int err = -ENOENT;

	if (!osf_attrs[OSF_ATTR_FINGER])
		return -EINVAL;

	f = nla_data(osf_attrs[OSF_ATTR_FINGER]);

	list_for_each_entry(sf, &xt_osf_fingers[!!f->df], finger_entry) {
		if (memcmp(&sf->finger, f, sizeof(struct xt_osf_user_finger)))
			continue;

		/*
		 * We are protected by nfnl mutex.
		 */
		list_del_rcu(&sf->finger_entry);
		call_rcu(&sf->rcu_head, xt_osf_finger_free_rcu);

		err = 0;
		break;
	}

	return err;
}

static const struct nfnl_callback xt_osf_nfnetlink_callbacks[OSF_MSG_MAX] = {
	[OSF_MSG_ADD]	= {
		.call		= xt_osf_add_callback,
		.attr_count	= OSF_ATTR_MAX,
		.policy		= xt_osf_policy,
	},
	[OSF_MSG_REMOVE]	= {
		.call		= xt_osf_remove_callback,
		.attr_count	= OSF_ATTR_MAX,
		.policy		= xt_osf_policy,
	},
};

static const struct nfnetlink_subsystem xt_osf_nfnetlink = {
	.name			= "osf",
	.subsys_id		= NFNL_SUBSYS_OSF,
	.cb_count		= OSF_MSG_MAX,
	.cb			= xt_osf_nfnetlink_callbacks,
};

static inline int xt_osf_ttl(const struct sk_buff *skb, const struct xt_osf_info *info,
			    unsigned char f_ttl)
{
	const struct iphdr *ip = ip_hdr(skb);

	if (info->flags & XT_OSF_TTL) {
		if (info->ttl == XT_OSF_TTL_TRUE)
			return ip->ttl == f_ttl;
		if (info->ttl == XT_OSF_TTL_NOCHECK)
			return 1;
		else if (ip->ttl <= f_ttl)
			return 1;
		else {
			struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
			int ret = 0;

			for_ifa(in_dev) {
				if (inet_ifa_match(ip->saddr, ifa)) {
					ret = (ip->ttl == f_ttl);
					break;
				}
			}
			endfor_ifa(in_dev);

			return ret;
		}
	}

	return ip->ttl == f_ttl;
}

static bool xt_osf_match_packet(const struct sk_buff *skb,
		const struct xt_match_param *p)
{
	const struct xt_osf_info *info = p->matchinfo;
	const struct iphdr *ip = ip_hdr(skb);
	const struct tcphdr *tcp;
	struct tcphdr _tcph;
	int fmatch = FMATCH_WRONG, fcount = 0;
	unsigned int optsize = 0, check_WSS = 0;
	u16 window, totlen, mss = 0;
	bool df;
	const unsigned char *optp = NULL, *_optp = NULL;
	unsigned char opts[MAX_IPOPTLEN];
	const struct xt_osf_finger *kf;
	const struct xt_osf_user_finger *f;

	if (!info)
		return false;

	tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), &_tcph);
	if (!tcp)
		return false;

	if (!tcp->syn)
		return false;

	totlen = ntohs(ip->tot_len);
	df = ntohs(ip->frag_off) & IP_DF;
	window = ntohs(tcp->window);

	if (tcp->doff * 4 > sizeof(struct tcphdr)) {
		optsize = tcp->doff * 4 - sizeof(struct tcphdr);

		_optp = optp = skb_header_pointer(skb, ip_hdrlen(skb) +
				sizeof(struct tcphdr), optsize, opts);
	}

	rcu_read_lock();
	list_for_each_entry_rcu(kf, &xt_osf_fingers[df], finger_entry) {
		f = &kf->finger;

		if (!(info->flags & XT_OSF_LOG) && strcmp(info->genre, f->genre))
			continue;

		optp = _optp;
		fmatch = FMATCH_WRONG;

		if (totlen == f->ss && xt_osf_ttl(skb, info, f->ttl)) {
			int foptsize, optnum;

			/*
			 * Should not happen if userspace parser was written correctly.
			 */
			if (f->wss.wc >= OSF_WSS_MAX)
				continue;

			/* Check options */

			foptsize = 0;
			for (optnum = 0; optnum < f->opt_num; ++optnum)
				foptsize += f->opt[optnum].length;

			if (foptsize > MAX_IPOPTLEN ||
				optsize > MAX_IPOPTLEN ||
				optsize != foptsize)
				continue;

			check_WSS = f->wss.wc;

			for (optnum = 0; optnum < f->opt_num; ++optnum) {
				if (f->opt[optnum].kind == (*optp)) {
					__u32 len = f->opt[optnum].length;
					const __u8 *optend = optp + len;
					int loop_cont = 0;

					fmatch = FMATCH_OK;

					switch (*optp) {
					case OSFOPT_MSS:
						mss = optp[3];
						mss <<= 8;
						mss |= optp[2];

						mss = ntohs(mss);
						break;
					case OSFOPT_TS:
						loop_cont = 1;
						break;
					}

					optp = optend;
				} else
					fmatch = FMATCH_OPT_WRONG;

				if (fmatch != FMATCH_OK)
					break;
			}

			if (fmatch != FMATCH_OPT_WRONG) {
				fmatch = FMATCH_WRONG;

				switch (check_WSS) {
				case OSF_WSS_PLAIN:
					if (f->wss.val == 0 || window == f->wss.val)
						fmatch = FMATCH_OK;
					break;
				case OSF_WSS_MSS:
					/*
					 * Some smart modems decrease mangle MSS to 
					 * SMART_MSS_2, so we check standard, decreased
					 * and the one provided in the fingerprint MSS
					 * values.
					 */
#define SMART_MSS_1	1460
#define SMART_MSS_2	1448
					if (window == f->wss.val * mss ||
					    window == f->wss.val * SMART_MSS_1 ||
					    window == f->wss.val * SMART_MSS_2)
						fmatch = FMATCH_OK;
					break;
				case OSF_WSS_MTU:
					if (window == f->wss.val * (mss + 40) ||
					    window == f->wss.val * (SMART_MSS_1 + 40) ||
					    window == f->wss.val * (SMART_MSS_2 + 40))
						fmatch = FMATCH_OK;
					break;
				case OSF_WSS_MODULO:
					if ((window % f->wss.val) == 0)
						fmatch = FMATCH_OK;
					break;
				}
			}

			if (fmatch != FMATCH_OK)
				continue;

			fcount++;

			if (info->flags & XT_OSF_LOG)
				nf_log_packet(p->family, p->hooknum, skb,
					p->in, p->out, NULL,
					"%s [%s:%s] : %pi4:%d -> %pi4:%d hops=%d\n",
					f->genre, f->version, f->subtype,
					&ip->saddr, ntohs(tcp->source),
					&ip->daddr, ntohs(tcp->dest),
					f->ttl - ip->ttl);

			if ((info->flags & XT_OSF_LOG) &&
			    info->loglevel == XT_OSF_LOGLEVEL_FIRST)
				break;
		}
	}
	rcu_read_unlock();

	if (!fcount && (info->flags & XT_OSF_LOG))
		nf_log_packet(p->family, p->hooknum, skb, p->in, p->out, NULL,
			"Remote OS is not known: %pi4:%u -> %pi4:%u\n",
				&ip->saddr, ntohs(tcp->source),
				&ip->daddr, ntohs(tcp->dest));

	if (fcount)
		fmatch = FMATCH_OK;

	return fmatch == FMATCH_OK;
}

static struct xt_match xt_osf_match = {
	.name 		= "osf",
	.revision	= 0,
	.family		= NFPROTO_IPV4,
	.proto		= IPPROTO_TCP,
	.hooks      	= (1 << NF_INET_LOCAL_IN) |
				(1 << NF_INET_PRE_ROUTING) |
				(1 << NF_INET_FORWARD),
	.match 		= xt_osf_match_packet,
	.matchsize	= sizeof(struct xt_osf_info),
	.me		= THIS_MODULE,
};

static int __init xt_osf_init(void)
{
	int err = -EINVAL;
	int i;

	for (i=0; i<ARRAY_SIZE(xt_osf_fingers); ++i)
		INIT_LIST_HEAD(&xt_osf_fingers[i]);

	err = nfnetlink_subsys_register(&xt_osf_nfnetlink);
	if (err < 0) {
		printk(KERN_ERR "Failed (%d) to register OSF nsfnetlink helper.\n", err);
		goto err_out_exit;
	}

	err = xt_register_match(&xt_osf_match);
	if (err) {
		printk(KERN_ERR "Failed (%d) to register OS fingerprint "
				"matching module.\n", err);
		goto err_out_remove;
	}

	return 0;

err_out_remove:
	nfnetlink_subsys_unregister(&xt_osf_nfnetlink);
err_out_exit:
	return err;
}

static void __exit xt_osf_fini(void)
{
	struct xt_osf_finger *f;
	int i;

	nfnetlink_subsys_unregister(&xt_osf_nfnetlink);
	xt_unregister_match(&xt_osf_match);

	rcu_read_lock();
	for (i=0; i<ARRAY_SIZE(xt_osf_fingers); ++i) {

		list_for_each_entry_rcu(f, &xt_osf_fingers[i], finger_entry) {
			list_del_rcu(&f->finger_entry);
			call_rcu(&f->rcu_head, xt_osf_finger_free_rcu);
		}
	}
	rcu_read_unlock();

	rcu_barrier();
}

module_init(xt_osf_init);
module_exit(xt_osf_fini);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
MODULE_DESCRIPTION("Passive OS fingerprint matching.");
MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_OSF);
