MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / net / ipv4 / netfilter / ipt_layer7.c
blobdb9f692d8a47dac4e1b26e55566a126865087bfa
1 /*
2 Kernel module to match application layer (OSI layer 7)
3 data in connections.
5 http://l7-filter.sf.net
7 By Matthew Strait and Ethan Sommer, 2003-2005.
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version
12 2 of the License, or (at your option) any later version.
13 http://www.gnu.org/licenses/gpl.txt
15 Based on ipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be>
16 and cls_layer7.c (C) 2003 Matthew Strait, Ethan Sommer, Justin Levandoski
19 #include <linux/module.h>
20 #include <linux/skbuff.h>
21 #include <linux/netfilter_ipv4/ip_conntrack.h>
22 #include <linux/proc_fs.h>
23 #include <linux/ctype.h>
24 #include <net/ip.h>
25 #include <net/tcp.h>
26 #include <linux/spinlock.h>
28 #include "regexp/regexp.c"
30 #include <linux/netfilter_ipv4/ipt_layer7.h>
31 #include <linux/netfilter_ipv4/ip_tables.h>
33 MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");
34 MODULE_LICENSE("GPL");
35 MODULE_DESCRIPTION("iptables application layer match module");
36 MODULE_VERSION("2.0");
38 static int maxdatalen = 2048; // this is the default
39 module_param(maxdatalen, int, 0444);
40 MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter");
42 #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
43 #define DPRINTK(format,args...) printk(format,##args)
44 #else
45 #define DPRINTK(format,args...)
46 #endif
48 #define TOTAL_PACKETS master_conntrack->counters[IP_CT_DIR_ORIGINAL].packets + \
49 master_conntrack->counters[IP_CT_DIR_REPLY].packets
51 /* Number of packets whose data we look at.
52 This can be modified through /proc/net/layer7_numpackets */
53 static int num_packets = 10;
55 static struct pattern_cache {
56 char * regex_string;
57 regexp * pattern;
58 struct pattern_cache * next;
59 } * first_pattern_cache = NULL;
61 /* I'm new to locking. Here are my assumptions:
63 - No one will write to /proc/net/layer7_numpackets over and over very fast;
64 if they did, nothing awful would happen.
66 - This code will never be processing the same packet twice at the same time,
67 because iptables rules are traversed in order.
69 - It doesn't matter if two packets from different connections are in here at
70 the same time, because they don't share any data.
72 - It _does_ matter if two packets from the same connection (or one from a
73 master and one from its child) are here at the same time. In this case,
74 we have to protect the conntracks and the list of compiled patterns.
76 DEFINE_RWLOCK(ct_lock);
77 DEFINE_SPINLOCK(list_lock);
79 #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
80 /* Converts an unfriendly string into a friendly one by
81 replacing unprintables with periods and all whitespace with " ". */
82 static char * friendly_print(unsigned char * s)
84 char * f = kmalloc(strlen(s) + 1, GFP_ATOMIC);
85 int i;
87 if(!f) {
88 if (net_ratelimit())
89 printk(KERN_ERR "layer7: out of memory in friendly_print, bailing.\n");
90 return NULL;
93 for(i = 0; i < strlen(s); i++){
94 if(isprint(s[i]) && s[i] < 128) f[i] = s[i];
95 else if(isspace(s[i])) f[i] = ' ';
96 else f[i] = '.';
98 f[i] = '\0';
99 return f;
102 static char dec2hex(int i)
104 switch (i) {
105 case 0 ... 9:
106 return (char)(i + '0');
107 break;
108 case 10 ... 15:
109 return (char)(i - 10 + 'a');
110 break;
111 default:
112 if (net_ratelimit())
113 printk("Problem in dec2hex\n");
114 return '\0';
118 static char * hex_print(unsigned char * s)
120 char * g = kmalloc(strlen(s)*3 + 1, GFP_ATOMIC);
121 int i;
123 if(!g) {
124 if (net_ratelimit())
125 printk(KERN_ERR "layer7: out of memory in hex_print, bailing.\n");
126 return NULL;
129 for(i = 0; i < strlen(s); i++) {
130 g[i*3 ] = dec2hex(s[i]/16);
131 g[i*3 + 1] = dec2hex(s[i]%16);
132 g[i*3 + 2] = ' ';
134 g[i*3] = '\0';
136 return g;
138 #endif // DEBUG
140 /* Use instead of regcomp. As we expect to be seeing the same regexps over and
141 over again, it make sense to cache the results. */
142 static regexp * compile_and_cache(char * regex_string, char * protocol)
144 struct pattern_cache * node = first_pattern_cache;
145 struct pattern_cache * last_pattern_cache = first_pattern_cache;
146 struct pattern_cache * tmp;
147 unsigned int len;
149 while (node != NULL) {
150 if (!strcmp(node->regex_string, regex_string))
151 return node->pattern;
153 last_pattern_cache = node;/* points at the last non-NULL node */
154 node = node->next;
157 /* If we reach the end of the list, then we have not yet cached
158 the pattern for this regex. Let's do that now.
159 Be paranoid about running out of memory to avoid list corruption. */
160 tmp = kmalloc(sizeof(struct pattern_cache), GFP_ATOMIC);
162 if(!tmp) {
163 if (net_ratelimit())
164 printk(KERN_ERR "layer7: out of memory in compile_and_cache, bailing.\n");
165 return NULL;
168 tmp->regex_string = kmalloc(strlen(regex_string) + 1, GFP_ATOMIC);
169 tmp->pattern = kmalloc(sizeof(struct regexp), GFP_ATOMIC);
170 tmp->next = NULL;
172 if(!tmp->regex_string || !tmp->pattern) {
173 if (net_ratelimit())
174 printk(KERN_ERR "layer7: out of memory in compile_and_cache, bailing.\n");
175 kfree(tmp->regex_string);
176 kfree(tmp->pattern);
177 kfree(tmp);
178 return NULL;
181 /* Ok. The new node is all ready now. */
182 node = tmp;
184 if(first_pattern_cache == NULL) /* list is empty */
185 first_pattern_cache = node; /* make node the beginning */
186 else
187 last_pattern_cache->next = node; /* attach node to the end */
189 /* copy the string and compile the regex */
190 len = strlen(regex_string);
191 DPRINTK("About to compile this: \"%s\"\n", regex_string);
192 node->pattern = regcomp(regex_string, &len);
193 if ( !node->pattern ) {
194 if (net_ratelimit())
195 printk(KERN_ERR "layer7: Error compiling regexp \"%s\" (%s)\n", regex_string, protocol);
196 /* pattern is now cached as NULL, so we won't try again. */
199 strcpy(node->regex_string, regex_string);
200 return node->pattern;
203 static int can_handle(const struct sk_buff *skb)
205 if(!skb->nh.iph) /* not IP */
206 return 0;
207 if(skb->nh.iph->protocol != IPPROTO_TCP &&
208 skb->nh.iph->protocol != IPPROTO_UDP &&
209 skb->nh.iph->protocol != IPPROTO_ICMP)
210 return 0;
211 return 1;
214 /* Returns offset the into the skb->data that the application data starts */
215 static int app_data_offset(const struct sk_buff *skb)
217 /* In case we are ported somewhere (ebtables?) where skb->nh.iph
218 isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */
219 int ip_hl = 4*skb->nh.iph->ihl;
221 if( skb->nh.iph->protocol == IPPROTO_TCP ) {
222 /* 12 == offset into TCP header for the header length field.
223 Can't get this with skb->h.th->doff because the tcphdr
224 struct doesn't get set when routing (this is confirmed to be
225 true in Netfilter as well as QoS.) */
226 int tcp_hl = 4*(skb->data[ip_hl + 12] >> 4);
228 return ip_hl + tcp_hl;
229 } else if( skb->nh.iph->protocol == IPPROTO_UDP ) {
230 return ip_hl + 8; /* UDP header is always 8 bytes */
231 } else if( skb->nh.iph->protocol == IPPROTO_ICMP ) {
232 return ip_hl + 8; /* ICMP header is 8 bytes */
233 } else {
234 if (net_ratelimit())
235 printk(KERN_ERR "layer7: tried to handle unknown protocol!\n");
236 return ip_hl + 8; /* something reasonable */
240 /* handles whether there's a match when we aren't appending data anymore */
241 static int match_no_append(struct ip_conntrack * conntrack, struct ip_conntrack * master_conntrack,
242 enum ip_conntrack_info ctinfo, enum ip_conntrack_info master_ctinfo,
243 struct ipt_layer7_info * info)
245 /* If we're in here, throw the app data away */
246 write_lock(&ct_lock);
247 if(master_conntrack->layer7.app_data != NULL) {
249 #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
250 if(!master_conntrack->layer7.app_proto) {
251 char * f = friendly_print(master_conntrack->layer7.app_data);
252 char * g = hex_print(master_conntrack->layer7.app_data);
253 DPRINTK("\nl7-filter gave up after %d bytes (%d packets):\n%s\n",
254 strlen(f), TOTAL_PACKETS, f);
255 kfree(f);
256 DPRINTK("In hex: %s\n", g);
257 kfree(g);
259 #endif
261 kfree(master_conntrack->layer7.app_data);
262 master_conntrack->layer7.app_data = NULL; /* don't free again */
264 write_unlock(&ct_lock);
266 if(master_conntrack->layer7.app_proto){
267 /* Here child connections set their .app_proto (for /proc/net/ip_conntrack) */
268 write_lock(&ct_lock);
269 if(!conntrack->layer7.app_proto) {
270 conntrack->layer7.app_proto = kmalloc(strlen(master_conntrack->layer7.app_proto)+1, GFP_ATOMIC);
271 if(!conntrack->layer7.app_proto){
272 if (net_ratelimit())
273 printk(KERN_ERR "layer7: out of memory in match_no_append, bailing.\n");
274 write_unlock(&ct_lock);
275 return 1;
277 strcpy(conntrack->layer7.app_proto, master_conntrack->layer7.app_proto);
279 write_unlock(&ct_lock);
281 return (!strcmp(master_conntrack->layer7.app_proto, info->protocol));
283 else {
284 /* If not classified, set to "unknown" to distinguish from
285 connections that are still being tested. */
286 write_lock(&ct_lock);
287 master_conntrack->layer7.app_proto = kmalloc(strlen("unknown")+1, GFP_ATOMIC);
288 if(!master_conntrack->layer7.app_proto){
289 if (net_ratelimit())
290 printk(KERN_ERR "layer7: out of memory in match_no_append, bailing.\n");
291 write_unlock(&ct_lock);
292 return 1;
294 strcpy(master_conntrack->layer7.app_proto, "unknown");
295 write_unlock(&ct_lock);
296 return 0;
300 /* add the new app data to the conntrack. Return number of bytes added. */
301 static int add_data(struct ip_conntrack * master_conntrack,
302 char * app_data, int appdatalen)
304 int length = 0, i;
305 int oldlength = master_conntrack->layer7.app_data_len;
307 // This is a fix for a race condition by Deti Fliegl. However, I'm not
308 // clear on whether the race condition exists or whether this really
309 // fixes it. I might just be being dense... Anyway, if it's not really
310 // a fix, all it does is waste a very small amount of time.
311 if(!master_conntrack->layer7.app_data) return 0;
313 /* Strip nulls. Make everything lower case (our regex lib doesn't
314 do case insensitivity). Add it to the end of the current data. */
315 for(i = 0; i < maxdatalen-oldlength-1 &&
316 i < appdatalen; i++) {
317 if(app_data[i] != '\0') {
318 master_conntrack->layer7.app_data[length+oldlength] =
319 /* the kernel version of tolower mungs 'upper ascii' */
320 isascii(app_data[i])? tolower(app_data[i]) : app_data[i];
321 length++;
325 master_conntrack->layer7.app_data[length+oldlength] = '\0';
326 master_conntrack->layer7.app_data_len = length + oldlength;
328 return length;
331 /* Returns true on match and false otherwise. */
332 static int match(const struct sk_buff *skb_const,
333 const struct net_device *in, const struct net_device *out,
334 const struct xt_match *match, const void *matchinfo,
335 int offset, unsigned int protoff, int *hotdrop)
337 struct ipt_layer7_info * info = (struct ipt_layer7_info *)matchinfo;
338 enum ip_conntrack_info master_ctinfo, ctinfo;
339 struct ip_conntrack *master_conntrack, *conntrack;
340 unsigned char * app_data;
341 unsigned int pattern_result, appdatalen;
342 regexp * comppattern;
343 struct sk_buff *skb = (struct sk_buff *)skb_const; /* see note below */
345 if(!can_handle(skb)){
346 DPRINTK("layer7: This is some protocol I can't handle.\n");
347 return info->invert;
350 /* Treat parent & all its children together as one connection, except
351 for the purpose of setting conntrack->layer7.app_proto in the actual
352 connection. This makes /proc/net/ip_conntrack more satisfying. */
353 if(!(conntrack = ip_conntrack_get((struct sk_buff *)skb, &ctinfo)) ||
354 !(master_conntrack = ip_conntrack_get((struct sk_buff *)skb, &master_ctinfo))) {
355 //DPRINTK("layer7: packet is not from a known connection, giving up.\n");
356 return info->invert;
359 /* Try to get a master conntrack (and its master etc) for FTP, etc. */
360 while (master_ct(master_conntrack) != NULL)
361 master_conntrack = master_ct(master_conntrack);
363 /* if we've classified it or seen too many packets */
364 if(TOTAL_PACKETS > num_packets ||
365 master_conntrack->layer7.app_proto) {
367 pattern_result = match_no_append(conntrack, master_conntrack, ctinfo, master_ctinfo, info);
369 /* skb->cb[0] == seen. Avoid doing things twice if there are two l7
370 rules. I'm not sure that using cb for this purpose is correct, although
371 it says "put your private variables there". But it doesn't look like it
372 is being used for anything else in the skbs that make it here. How can
373 I write to cb without making the compiler angry? */
374 skb->cb[0] = 1; /* marking it seen here is probably irrelevant, but consistant */
376 return (pattern_result ^ info->invert);
379 if(skb_is_nonlinear(skb)){
380 if(skb_linearize(skb) != 0){
381 if (net_ratelimit())
382 printk(KERN_ERR "layer7: failed to linearize packet, bailing.\n");
383 return info->invert;
387 /* now that the skb is linearized, it's safe to set these. */
388 app_data = skb->data + app_data_offset(skb);
389 appdatalen = skb->tail - app_data;
391 spin_lock_bh(&list_lock);
392 /* the return value gets checked later, when we're ready to use it */
393 comppattern = compile_and_cache(info->pattern, info->protocol);
394 spin_unlock_bh(&list_lock);
396 /* On the first packet of a connection, allocate space for app data */
397 write_lock(&ct_lock);
398 if(TOTAL_PACKETS == 1 && !skb->cb[0] && !master_conntrack->layer7.app_data) {
399 master_conntrack->layer7.app_data = kmalloc(maxdatalen, GFP_ATOMIC);
400 if(!master_conntrack->layer7.app_data){
401 if (net_ratelimit())
402 printk(KERN_ERR "layer7: out of memory in match, bailing.\n");
403 write_unlock(&ct_lock);
404 return info->invert;
407 master_conntrack->layer7.app_data[0] = '\0';
409 write_unlock(&ct_lock);
411 /* Can be here, but unallocated, if numpackets is increased near
412 the beginning of a connection */
413 if(master_conntrack->layer7.app_data == NULL)
414 return (info->invert); /* unmatched */
416 if(!skb->cb[0]){
417 int newbytes;
418 write_lock(&ct_lock);
419 newbytes = add_data(master_conntrack, app_data, appdatalen);
420 write_unlock(&ct_lock);
422 if(newbytes == 0) { /* didn't add any data */
423 skb->cb[0] = 1;
424 /* Didn't match before, not going to match now */
425 return info->invert;
429 /* If looking for "unknown", then never match. "Unknown" means that
430 we've given up; we're still trying with these packets. */
431 read_lock(&ct_lock);
432 if(!strcmp(info->protocol, "unknown")) {
433 pattern_result = 0;
434 /* If the regexp failed to compile, don't bother running it */
435 } else if(comppattern && regexec(comppattern, master_conntrack->layer7.app_data)) {
436 DPRINTK("layer7: matched %s\n", info->protocol);
437 pattern_result = 1;
438 } else pattern_result = 0;
439 read_unlock(&ct_lock);
441 if(pattern_result) {
442 write_lock(&ct_lock);
443 master_conntrack->layer7.app_proto = kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);
444 if(!master_conntrack->layer7.app_proto){
445 if (net_ratelimit())
446 printk(KERN_ERR "layer7: out of memory in match, bailing.\n");
447 write_unlock(&ct_lock);
448 return (pattern_result ^ info->invert);
450 strcpy(master_conntrack->layer7.app_proto, info->protocol);
451 write_unlock(&ct_lock);
454 /* mark the packet seen */
455 skb->cb[0] = 1;
457 return (pattern_result ^ info->invert);
460 static int checkentry(const char *tablename, const void *ip,
461 const struct xt_match *match, void *matchinfo,
462 unsigned int hook_mask)
464 // struct ipt_layer7_info * info = (struct ipt_layer7_info *)matchinfo;
466 return 1;
469 static struct ipt_match layer7_match = {
470 .name = "layer7",
471 .match = &match,
472 .checkentry = &checkentry,
473 .matchsize = sizeof(struct ipt_layer7_info),
474 .me = THIS_MODULE
477 /* taken from drivers/video/modedb.c */
478 static int my_atoi(const char *s)
480 int val = 0;
482 for (;; s++) {
483 switch (*s) {
484 case '0'...'9':
485 val = 10*val+(*s-'0');
486 break;
487 default:
488 return val;
493 /* write out num_packets to userland. */
494 static int layer7_read_proc(char* page, char ** start, off_t off, int count,
495 int* eof, void * data)
497 if(num_packets > 99 && net_ratelimit())
498 printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n");
500 page[0] = num_packets/10 + '0';
501 page[1] = num_packets%10 + '0';
502 page[2] = '\n';
503 page[3] = '\0';
505 *eof=1;
507 return 3;
510 /* Read in num_packets from userland */
511 static int layer7_write_proc(struct file* file, const char* buffer,
512 unsigned long count, void *data)
514 char * foo = kmalloc(count, GFP_ATOMIC);
516 if(!foo){
517 if (net_ratelimit())
518 printk(KERN_ERR "layer7: out of memory, bailing. num_packets unchanged.\n");
519 return count;
522 if(copy_from_user(foo, buffer, count)) {
523 return -EFAULT;
527 num_packets = my_atoi(foo);
528 kfree (foo);
530 /* This has an arbitrary limit to make the math easier. I'm lazy.
531 But anyway, 99 is a LOT! If you want more, you're doing it wrong! */
532 if(num_packets > 99) {
533 printk(KERN_WARNING "layer7: num_packets can't be > 99.\n");
534 num_packets = 99;
535 } else if(num_packets < 1) {
536 printk(KERN_WARNING "layer7: num_packets can't be < 1.\n");
537 num_packets = 1;
540 return count;
543 /* register the proc file */
544 static void layer7_init_proc(void)
546 struct proc_dir_entry* entry;
547 entry = create_proc_entry("layer7_numpackets", 0644, proc_net);
548 entry->read_proc = layer7_read_proc;
549 entry->write_proc = layer7_write_proc;
552 static void layer7_cleanup_proc(void)
554 remove_proc_entry("layer7_numpackets", proc_net);
557 static int __init ipt_layer7_init(void)
559 layer7_init_proc();
560 if(maxdatalen < 1) {
561 printk(KERN_WARNING "layer7: maxdatalen can't be < 1, using 1\n");
562 maxdatalen = 1;
564 /* This is not a hard limit. It's just here to prevent people from
565 bringing their slow machines to a grinding halt. */
566 else if(maxdatalen > 65536) {
567 printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, using 65536\n");
568 maxdatalen = 65536;
570 return ipt_register_match(&layer7_match);
573 static void __exit ipt_layer7_fini(void)
575 layer7_cleanup_proc();
576 ipt_unregister_match(&layer7_match);
579 module_init(ipt_layer7_init);
580 module_exit(ipt_layer7_fini);