/*
  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_data(struct nf_conn * master_conntrack,
                    char * app_data, int appdatalen)
{
	int length = 0, i;
	int oldlength = master_conntrack->layer7.app_data_len;

	/* This is a fix for a race condition by Deti Fliegl. However, I'm not 
	   clear on whether the race condition exists or whether this really 
	   fixes it.  I might just be being dense... Anyway, if it's not really 
	   a fix, all it does is waste a very small amount of time. */
	if(!master_conntrack->layer7.app_data) 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-oldlength-1 &&
		   i < appdatalen; i++) {
		if(app_data[i] != '\0') {
			/* the kernel version of tolower mungs 'upper ascii' */
			master_conntrack->layer7.app_data[length+oldlength] =
				isascii(app_data[i])? 
					tolower(app_data[i]) : app_data[i];
			length++;
		}
	}

	master_conntrack->layer7.app_data[length+oldlength] = '\0';
	master_conntrack->layer7.app_data_len = length + oldlength;

	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, 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;
	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(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);

	/* 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, 28)
static bool 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
static bool 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
                return 0;
        }
	return 1;
}


#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);
