/*
  Kernel module to match application layer (OSI layer 7) data in connections.

  http://l7-filter.sf.net

  (C) 2003-2009 Matthew Strait and Ethan Sommer.

  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.
  http://www.gnu.org/licenses/gpl.txt

  Based on ipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be>,
  xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait,
  Ethan Sommer, Justin Levandoski.
*/

#include <linux/spinlock.h>
#include <linux/version.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
#include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_acct.h>
#endif
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_layer7.h>
#include <linux/ctype.h>
#include <linux/proc_fs.h>

#include "regexp/regexp.c"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");
MODULE_DESCRIPTION("iptables application layer match module");
MODULE_ALIAS("ipt_layer7");
MODULE_VERSION("2.21");

static int maxdatalen = 2048; // this is the default
module_param(maxdatalen, int, 0444);
MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter");
#ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG
	#define DPRINTK(format,args...) printk(format,##args)
#else
	#define DPRINTK(format,args...)
#endif

/* Number of packets whose data we look at.
This can be modified through /proc/net/layer7_numpackets */
static int num_packets = 10;

static struct pattern_cache {
	char * regex_string;
	regexp * pattern;
	struct pattern_cache * next;
} * first_pattern_cache = NULL;

DEFINE_SPINLOCK(l7_lock);

static int total_acct_packets(struct nf_conn *ct)
{
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
	BUG_ON(ct == NULL);
	return (ct->counters[IP_CT_DIR_ORIGINAL].packets + ct->counters[IP_CT_DIR_REPLY].packets);
#else
	struct nf_conn_counter *acct;

	BUG_ON(ct == NULL);
	acct = nf_conn_acct_find(ct);
	if (!acct)
		return 0;
	return (acct[IP_CT_DIR_ORIGINAL].packets + acct[IP_CT_DIR_REPLY].packets);
#endif
}

#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
/* Converts an unfriendly string into a friendly one by
replacing unprintables with periods and all whitespace with " ". */
static char * friendly_print(unsigned char * s)
{
	char * f = kmalloc(strlen(s) + 1, GFP_ATOMIC);
	int i;

	if(!f) {
		if (net_ratelimit())
			printk(KERN_ERR "layer7: out of memory in "
					"friendly_print, bailing.\n");
		return NULL;
	}

	for(i = 0; i < strlen(s); i++){
		if(isprint(s[i]) && s[i] < 128)	f[i] = s[i];
		else if(isspace(s[i]))		f[i] = ' ';
		else 				f[i] = '.';
	}
	f[i] = '\0';
	return f;
}

static char dec2hex(int i)
{
	switch (i) {
		case 0 ... 9:
			return (i + '0');
			break;
		case 10 ... 15:
			return (i - 10 + 'a');
			break;
		default:
			if (net_ratelimit())
				printk("layer7: Problem in dec2hex\n");
			return '\0';
	}
}

static char * hex_print(unsigned char * s)
{
	char * g = kmalloc(strlen(s)*3 + 1, GFP_ATOMIC);
	int i;

	if(!g) {
	       if (net_ratelimit())
			printk(KERN_ERR "layer7: out of memory in hex_print, "
					"bailing.\n");
	       return NULL;
	}

	for(i = 0; i < strlen(s); i++) {
		g[i*3    ] = dec2hex(s[i]/16);
		g[i*3 + 1] = dec2hex(s[i]%16);
		g[i*3 + 2] = ' ';
	}
	g[i*3] = '\0';

	return g;
}
#endif // DEBUG

/* Use instead of regcomp.  As we expect to be seeing the same regexps over and
over again, it make sense to cache the results. */
static regexp * compile_and_cache(const char * regex_string, 
                                  const char * protocol)
{
	struct pattern_cache * node               = first_pattern_cache;
	struct pattern_cache * last_pattern_cache = first_pattern_cache;
	struct pattern_cache * tmp;
	unsigned int len;

	while (node != NULL) {
		if (!strcmp(node->regex_string, regex_string))
		return node->pattern;

		last_pattern_cache = node;/* points at the last non-NULL node */
		node = node->next;
	}

	/* If we reach the end of the list, then we have not yet cached
	   the pattern for this regex. Let's do that now.
	   Be paranoid about running out of memory to avoid list corruption. */
	tmp = kmalloc(sizeof(struct pattern_cache), GFP_ATOMIC);

	if(!tmp) {
		if (net_ratelimit())
			printk(KERN_ERR "layer7: out of memory in "
					"compile_and_cache, bailing.\n");
		return NULL;
	}

	tmp->regex_string  = kmalloc(strlen(regex_string) + 1, GFP_ATOMIC);
	tmp->pattern       = kmalloc(sizeof(struct regexp),    GFP_ATOMIC);
	tmp->next = NULL;

	if(!tmp->regex_string || !tmp->pattern) {
		if (net_ratelimit())
			printk(KERN_ERR "layer7: out of memory in "
					"compile_and_cache, bailing.\n");
		kfree(tmp->regex_string);
		kfree(tmp->pattern);
		kfree(tmp);
		return NULL;
	}

	/* Ok.  The new node is all ready now. */
	node = tmp;

	if(first_pattern_cache == NULL) /* list is empty */
		first_pattern_cache = node; /* make node the beginning */
	else
		last_pattern_cache->next = node; /* attach node to the end */

	/* copy the string and compile the regex */
	len = strlen(regex_string);
	DPRINTK("About to compile this: \"%s\"\n", regex_string);
	node->pattern = regcomp((char *)regex_string, &len);
	if ( !node->pattern ) {
		if (net_ratelimit())
			printk(KERN_ERR "layer7: Error compiling regexp "
					"\"%s\" (%s)\n", 
					regex_string, protocol);
		/* pattern is now cached as NULL, so we won't try again. */
	}

	strcpy(node->regex_string, regex_string);
	return node->pattern;
}

static int can_handle(const struct sk_buff *skb)
{
	if(!ip_hdr(skb)) /* not IP */
		return 0;
	if(ip_hdr(skb)->protocol != IPPROTO_TCP &&
	   ip_hdr(skb)->protocol != IPPROTO_UDP &&
	   ip_hdr(skb)->protocol != IPPROTO_ICMP)
		return 0;
	return 1;
}

/* Returns offset the into the skb->data that the application data starts */
static int app_data_offset(const struct sk_buff *skb)
{
	/* In case we are ported somewhere (ebtables?) where ip_hdr(skb)
	isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */
	int ip_hl = 4*ip_hdr(skb)->ihl;

	if( ip_hdr(skb)->protocol == IPPROTO_TCP ) {
		/* 12 == offset into TCP header for the header length field.
		Can't get this with skb->h.th->doff because the tcphdr
		struct doesn't get set when routing (this is confirmed to be
		true in Netfilter as well as QoS.) */
		int tcp_hl = 4*(skb->data[ip_hl + 12] >> 4);

		return ip_hl + tcp_hl;
	} else if( ip_hdr(skb)->protocol == IPPROTO_UDP  ) {
		return ip_hl + 8; /* UDP header is always 8 bytes */
	} else if( ip_hdr(skb)->protocol == IPPROTO_ICMP ) {
		return ip_hl + 8; /* ICMP header is 8 bytes */
	} else {
		if (net_ratelimit())
			printk(KERN_ERR "layer7: tried to handle unknown "
					"protocol!\n");
		return ip_hl + 8; /* something reasonable */
	}
}

/* handles whether there's a match when we aren't appending data anymore */
static int match_no_append(struct nf_conn * conntrack, 
                           struct nf_conn * master_conntrack, 
                           enum ip_conntrack_info ctinfo,
                           enum ip_conntrack_info master_ctinfo,
                           const struct xt_layer7_info * info)
{
	/* If we're in here, throw the app data away */
	if(master_conntrack->layer7.app_data != NULL) {

	#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
		if(!master_conntrack->layer7.app_proto) {
			char * f = 
			  friendly_print(master_conntrack->layer7.app_data);
			char * g = 
			  hex_print(master_conntrack->layer7.app_data);
			DPRINTK("\nl7-filter gave up after %d bytes "
				"(%d packets):\n%s\n",
				strlen(f), total_acct_packets(master_conntrack), f);
			kfree(f);
			DPRINTK("In hex: %s\n", g);
			kfree(g);
		}
	#endif

		kfree(master_conntrack->layer7.app_data);
		master_conntrack->layer7.app_data = NULL; /* don't free again */
	}

	if(master_conntrack->layer7.app_proto){
		/* Here child connections set their .app_proto (for /proc) */
		if(!conntrack->layer7.app_proto) {
			conntrack->layer7.app_proto = 
			  kmalloc(strlen(master_conntrack->layer7.app_proto)+1, 
			    GFP_ATOMIC);
			if(!conntrack->layer7.app_proto){
				if (net_ratelimit())
					printk(KERN_ERR "layer7: out of memory "
							"in match_no_append, "
							"bailing.\n");
				return 1;
			}
			strcpy(conntrack->layer7.app_proto, 
				master_conntrack->layer7.app_proto);
		}

		return (!strcmp(master_conntrack->layer7.app_proto, 
				info->protocol));
	}
	else {
		/* If not classified, set to "unknown" to distinguish from
		connections that are still being tested. */
		master_conntrack->layer7.app_proto = 
			kmalloc(strlen("unknown")+1, GFP_ATOMIC);
		if(!master_conntrack->layer7.app_proto){
			if (net_ratelimit())
				printk(KERN_ERR "layer7: out of memory in "
						"match_no_append, bailing.\n");
			return 1;
		}
		strcpy(master_conntrack->layer7.app_proto, "unknown");
		return 0;
	}
}

/* add the new app data to the conntrack.  Return number of bytes added. */
static int add_datastr(char *target, int offset, char *app_data, int len)
{
	int length = 0, i;
	if (!target) return 0;

	/* Strip nulls. Make everything lower case (our regex lib doesn't
	do case insensitivity).  Add it to the end of the current data. */
 	for(i = 0; i < maxdatalen-offset-1 && i < len; i++) {
		if(app_data[i] != '\0') {
			/* the kernel version of tolower mungs 'upper ascii' */
			target[length+offset] =
				isascii(app_data[i])? 
					tolower(app_data[i]) : app_data[i];
			length++;
		}
	}
	target[length+offset] = '\0';

	return length;
}

/* add the new app data to the conntrack.  Return number of bytes added. */
static int add_data(struct nf_conn * master_conntrack,
                    char * app_data, int appdatalen)
{
	int length;

	length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen);
	master_conntrack->layer7.app_data_len += length;

	return length;
}

/* taken from drivers/video/modedb.c */
static int my_atoi(const char *s)
{
	int val = 0;

	for (;; s++) {
		switch (*s) {
			case '0'...'9':
			val = 10*val+(*s-'0');
			break;
		default:
			return val;
		}
	}
}

/* write out num_packets to userland. */
static int layer7_read_proc(char* page, char ** start, off_t off, int count,
                            int* eof, void * data)
{
	if(num_packets > 99 && net_ratelimit())
		printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n");

	page[0] = num_packets/10 + '0';
	page[1] = num_packets%10 + '0';
	page[2] = '\n';
	page[3] = '\0';

	*eof=1;

	return 3;
}

/* Read in num_packets from userland */
static int layer7_write_proc(struct file* file, const char* buffer,
                             unsigned long count, void *data)
{
	char * foo = kmalloc(count, GFP_ATOMIC);

	if(!foo){
		if (net_ratelimit())
			printk(KERN_ERR "layer7: out of memory, bailing. "
					"num_packets unchanged.\n");
		return count;
	}

	if(copy_from_user(foo, buffer, count)) {
		return -EFAULT;
	}


	num_packets = my_atoi(foo);
	kfree (foo);

	/* This has an arbitrary limit to make the math easier. I'm lazy.
	But anyway, 99 is a LOT! If you want more, you're doing it wrong! */
	if(num_packets > 99) {
		printk(KERN_WARNING "layer7: num_packets can't be > 99.\n");
		num_packets = 99;
	} else if(num_packets < 1) {
		printk(KERN_WARNING "layer7: num_packets can't be < 1.\n");
		num_packets = 1;
	}

	return count;
}

static bool
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
match(const struct sk_buff *skbin, struct xt_action_param *par)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
match(const struct sk_buff *skbin, const struct xt_match_param *par)
#else
match(const struct sk_buff *skbin,
      const struct net_device *in,
      const struct net_device *out,
      const struct xt_match *match,
      const void *matchinfo,
      int offset,
      unsigned int protoff,
      bool *hotdrop)
#endif
{
	/* sidestep const without getting a compiler warning... */
	struct sk_buff * skb = (struct sk_buff *)skbin; 

	const struct xt_layer7_info * info = 
	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
		par->matchinfo;
	#else
		matchinfo;
	#endif

	enum ip_conntrack_info master_ctinfo, ctinfo;
	struct nf_conn *master_conntrack, *conntrack;
	unsigned char *app_data, *tmp_data;
	unsigned int pattern_result, appdatalen;
	regexp * comppattern;

	/* Be paranoid/incompetent - lock the entire match function. */
	spin_lock_bh(&l7_lock);

	if(!can_handle(skb)){
		DPRINTK("layer7: This is some protocol I can't handle.\n");
		spin_unlock_bh(&l7_lock);
		return info->invert;
	}

	/* Treat parent & all its children together as one connection, except
	for the purpose of setting conntrack->layer7.app_proto in the actual
	connection. This makes /proc/net/ip_conntrack more satisfying. */
	if(!(conntrack = nf_ct_get(skb, &ctinfo)) ||
	   !(master_conntrack=nf_ct_get(skb,&master_ctinfo))){
		DPRINTK("layer7: couldn't get conntrack.\n");
		spin_unlock_bh(&l7_lock);
		return info->invert;
	}

	/* Try to get a master conntrack (and its master etc) for FTP, etc. */
	while (master_ct(master_conntrack) != NULL)
		master_conntrack = master_ct(master_conntrack);

	/* if we've classified it or seen too many packets */
	if(!info->pkt && (total_acct_packets(master_conntrack) > num_packets ||
	   master_conntrack->layer7.app_proto)) {

		pattern_result = match_no_append(conntrack, master_conntrack, 
						 ctinfo, master_ctinfo, info);

		/* skb->cb[0] == seen. Don't do things twice if there are 
		multiple l7 rules. I'm not sure that using cb for this purpose 
		is correct, even though it says "put your private variables 
		there". But it doesn't look like it is being used for anything
		else in the skbs that make it here. */
		skb->cb[0] = 1; /* marking it seen here's probably irrelevant */

		spin_unlock_bh(&l7_lock);
		return (pattern_result ^ info->invert);
	}

	if(skb_is_nonlinear(skb)){
		if(skb_linearize(skb) != 0){
			if (net_ratelimit())
				printk(KERN_ERR "layer7: failed to linearize "
						"packet, bailing.\n");
			spin_unlock_bh(&l7_lock);
			return info->invert;
		}
	}

	/* now that the skb is linearized, it's safe to set these. */
	app_data = skb->data + app_data_offset(skb);
	appdatalen = skb_tail_pointer(skb) - app_data;

	/* the return value gets checked later, when we're ready to use it */
	comppattern = compile_and_cache(info->pattern, info->protocol);

	if (info->pkt) {
		tmp_data = kmalloc(maxdatalen, GFP_ATOMIC);
		if(!tmp_data){
			if (net_ratelimit())
				printk(KERN_ERR "layer7: out of memory in match, bailing.\n");
			return info->invert;
		}

		tmp_data[0] = '\0';
		add_datastr(tmp_data, 0, app_data, appdatalen);
		pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0);

		kfree(tmp_data);
		tmp_data = NULL;
		spin_unlock_bh(&l7_lock);

		return (pattern_result ^ info->invert);
	}

	/* On the first packet of a connection, allocate space for app data */
	if(total_acct_packets(master_conntrack) == 1 && !skb->cb[0] && 
	   !master_conntrack->layer7.app_data){
		master_conntrack->layer7.app_data = 
			kmalloc(maxdatalen, GFP_ATOMIC);
		if(!master_conntrack->layer7.app_data){
			if (net_ratelimit())
				printk(KERN_ERR "layer7: out of memory in "
						"match, bailing.\n");
			spin_unlock_bh(&l7_lock);
			return info->invert;
		}

		master_conntrack->layer7.app_data[0] = '\0';
	}

	/* Can be here, but unallocated, if numpackets is increased near
	the beginning of a connection */
	if(master_conntrack->layer7.app_data == NULL){
		spin_unlock_bh(&l7_lock);
		return info->invert; /* unmatched */
	}

	if(!skb->cb[0]){
		int newbytes;
		newbytes = add_data(master_conntrack, app_data, appdatalen);

		if(newbytes == 0) { /* didn't add any data */
			skb->cb[0] = 1;
			/* Didn't match before, not going to match now */
			spin_unlock_bh(&l7_lock);
			return info->invert;
		}
	}

	/* If looking for "unknown", then never match.  "Unknown" means that
	we've given up; we're still trying with these packets. */
	if(!strcmp(info->protocol, "unknown")) {
		pattern_result = 0;
	/* If looking for "unset", then always match. "Unset" means that we
	haven't yet classified the connection. */
	} else if(!strcmp(info->protocol, "unset")) {
		pattern_result = 2;
		DPRINTK("layer7: matched unset: not yet classified "
			"(%d/%d packets)\n",
                        total_acct_packets(master_conntrack), num_packets);
	/* If the regexp failed to compile, don't bother running it */
	} else if(comppattern && 
		  regexec(comppattern, master_conntrack->layer7.app_data)){
		DPRINTK("layer7: matched %s\n", info->protocol);
		pattern_result = 1;
	} else pattern_result = 0;

	if(pattern_result == 1) {
		master_conntrack->layer7.app_proto = 
			kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);
		if(!master_conntrack->layer7.app_proto){
			if (net_ratelimit())
				printk(KERN_ERR "layer7: out of memory in "
						"match, bailing.\n");
			spin_unlock_bh(&l7_lock);
			return (pattern_result ^ info->invert);
		}
		strcpy(master_conntrack->layer7.app_proto, info->protocol);
	} else if(pattern_result > 1) { /* cleanup from "unset" */
		pattern_result = 1;
	}

	/* mark the packet seen */
	skb->cb[0] = 1;

	spin_unlock_bh(&l7_lock);
	return (pattern_result ^ info->invert);
}

// load nf_conntrack_ipv4
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
static int
#else
static bool
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
check(const struct xt_mtchk_param *par)
{
        if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
                                    "proto=%d\n", par->match->family);
#else
check(const char *tablename, const void *inf,
		 const struct xt_match *match, void *matchinfo,
		 unsigned int hook_mask)
{
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
                                    "proto=%d\n", match->family);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
		return -EINVAL;
	}
	return 0;
#else
                return 0;
        }
	return 1;
#endif
}


#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
	static void destroy(const struct xt_mtdtor_param *par)
	{
		nf_ct_l3proto_module_put(par->match->family);
	}
#else
	static void destroy(const struct xt_match *match, void *matchinfo)
	{
		nf_ct_l3proto_module_put(match->family);
	}
#endif

static struct xt_match xt_layer7_match[] __read_mostly = {
{
	.name		= "layer7",
	.family		= AF_INET,
	.checkentry	= check,
	.match		= match,
	.destroy	= destroy,
	.matchsize	= sizeof(struct xt_layer7_info),
	.me		= THIS_MODULE
}
};

static void layer7_cleanup_proc(void)
{
	remove_proc_entry("layer7_numpackets", init_net.proc_net);
}

/* register the proc file */
static void layer7_init_proc(void)
{
	struct proc_dir_entry* entry;
	entry = create_proc_entry("layer7_numpackets", 0644, init_net.proc_net);
	entry->read_proc = layer7_read_proc;
	entry->write_proc = layer7_write_proc;
}

static int __init xt_layer7_init(void)
{
	need_conntrack();

	layer7_init_proc();
	if(maxdatalen < 1) {
		printk(KERN_WARNING "layer7: maxdatalen can't be < 1, "
			"using 1\n");
		maxdatalen = 1;
	}
	/* This is not a hard limit.  It's just here to prevent people from
	bringing their slow machines to a grinding halt. */
	else if(maxdatalen > 65536) {
		printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, "
			"using 65536\n");
		maxdatalen = 65536;
	}
	return xt_register_matches(xt_layer7_match,
				   ARRAY_SIZE(xt_layer7_match));
}

static void __exit xt_layer7_fini(void)
{
	layer7_cleanup_proc();
	xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match));
}

module_init(xt_layer7_init);
module_exit(xt_layer7_fini);
