2 Kernel module to match application layer (OSI layer 7) data in connections.
4 http://l7-filter.sf.net
6 (C) 2003-2009 Matthew Strait and Ethan Sommer.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version
11 2 of the License, or (at your option) any later version.
12 http://www.gnu.org/licenses/gpl.txt
14 Based on ipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be>,
15 xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait,
16 Ethan Sommer, Justin Levandoski.
19 #include <linux/spinlock.h>
20 #include <linux/version.h>
23 #include <linux/module.h>
24 #include <linux/skbuff.h>
25 #include <linux/netfilter.h>
26 #include <net/netfilter/nf_conntrack.h>
27 #include <net/netfilter/nf_conntrack_core.h>
28 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
29 #include <net/netfilter/nf_conntrack_extend.h>
30 #include <net/netfilter/nf_conntrack_acct.h>
32 #include <linux/netfilter/x_tables.h>
33 #include <linux/netfilter/xt_layer7.h>
34 #include <linux/ctype.h>
35 #include <linux/proc_fs.h>
37 #include "regexp/regexp.c"
39 MODULE_LICENSE("GPL");
40 MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");
41 MODULE_DESCRIPTION("iptables application layer match module");
42 MODULE_ALIAS("ipt_layer7");
43 MODULE_VERSION("2.23");
45 static int maxdatalen
= 2048; // this is the default
46 module_param(maxdatalen
, int, 0444);
47 MODULE_PARM_DESC(maxdatalen
, "maximum bytes of data looked at by l7-filter");
48 #ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG
49 #define DPRINTK(format,args...) printk(format,##args)
51 #define DPRINTK(format,args...)
54 /* Number of packets whose data we look at.
55 This can be modified through /proc/net/layer7_numpackets */
56 static int num_packets
= 10;
58 static struct pattern_cache
{
61 struct pattern_cache
* next
;
62 } * first_pattern_cache
= NULL
;
64 DEFINE_SPINLOCK(l7_lock
);
66 static int total_acct_packets(struct nf_conn
*ct
)
68 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
70 return (ct
->counters
[IP_CT_DIR_ORIGINAL
].packets
+ ct
->counters
[IP_CT_DIR_REPLY
].packets
);
72 struct nf_conn_counter
*acct
;
75 acct
= nf_conn_acct_find(ct
);
78 return (atomic64_read(&acct
[IP_CT_DIR_ORIGINAL
].packets
) + atomic64_read(&acct
[IP_CT_DIR_REPLY
].packets
));
82 #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
83 /* Converts an unfriendly string into a friendly one by
84 replacing unprintables with periods and all whitespace with " ". */
85 static char * friendly_print(unsigned char * s
)
87 char * f
= kmalloc(strlen(s
) + 1, GFP_ATOMIC
);
92 printk(KERN_ERR
"layer7: out of memory in "
93 "friendly_print, bailing.\n");
97 for(i
= 0; i
< strlen(s
); i
++){
98 if(isprint(s
[i
]) && s
[i
] < 128) f
[i
] = s
[i
];
99 else if(isspace(s
[i
])) f
[i
] = ' ';
106 static char dec2hex(int i
)
113 return (i
- 10 + 'a');
117 printk("layer7: Problem in dec2hex\n");
122 static char * hex_print(unsigned char * s
)
124 char * g
= kmalloc(strlen(s
)*3 + 1, GFP_ATOMIC
);
129 printk(KERN_ERR
"layer7: out of memory in hex_print, "
134 for(i
= 0; i
< strlen(s
); i
++) {
135 g
[i
*3 ] = dec2hex(s
[i
]/16);
136 g
[i
*3 + 1] = dec2hex(s
[i
]%16);
145 /* Use instead of regcomp. As we expect to be seeing the same regexps over and
146 over again, it make sense to cache the results. */
147 static regexp
* compile_and_cache(const char * regex_string
,
148 const char * protocol
)
150 struct pattern_cache
* node
= first_pattern_cache
;
151 struct pattern_cache
* last_pattern_cache
= first_pattern_cache
;
152 struct pattern_cache
* tmp
;
155 while (node
!= NULL
) {
156 if (!strcmp(node
->regex_string
, regex_string
))
157 return node
->pattern
;
159 last_pattern_cache
= node
;/* points at the last non-NULL node */
163 /* If we reach the end of the list, then we have not yet cached
164 the pattern for this regex. Let's do that now.
165 Be paranoid about running out of memory to avoid list corruption. */
166 tmp
= kmalloc(sizeof(struct pattern_cache
), GFP_ATOMIC
);
170 printk(KERN_ERR
"layer7: out of memory in "
171 "compile_and_cache, bailing.\n");
175 tmp
->regex_string
= kmalloc(strlen(regex_string
) + 1, GFP_ATOMIC
);
176 tmp
->pattern
= kmalloc(sizeof(struct regexp
), GFP_ATOMIC
);
179 if(!tmp
->regex_string
|| !tmp
->pattern
) {
181 printk(KERN_ERR
"layer7: out of memory in "
182 "compile_and_cache, bailing.\n");
183 kfree(tmp
->regex_string
);
189 /* Ok. The new node is all ready now. */
192 if(first_pattern_cache
== NULL
) /* list is empty */
193 first_pattern_cache
= node
; /* make node the beginning */
195 last_pattern_cache
->next
= node
; /* attach node to the end */
197 /* copy the string and compile the regex */
198 len
= strlen(regex_string
);
199 DPRINTK("About to compile this: \"%s\"\n", regex_string
);
200 node
->pattern
= regcomp((char *)regex_string
, &len
);
201 if ( !node
->pattern
) {
203 printk(KERN_ERR
"layer7: Error compiling regexp "
205 regex_string
, protocol
);
206 /* pattern is now cached as NULL, so we won't try again. */
209 strcpy(node
->regex_string
, regex_string
);
210 return node
->pattern
;
213 static int can_handle(const struct sk_buff
*skb
)
215 if(!ip_hdr(skb
)) /* not IP */
217 if(ip_hdr(skb
)->protocol
!= IPPROTO_TCP
&&
218 ip_hdr(skb
)->protocol
!= IPPROTO_UDP
&&
219 ip_hdr(skb
)->protocol
!= IPPROTO_ICMP
)
224 /* Returns offset the into the skb->data that the application data starts */
225 static int app_data_offset(const struct sk_buff
*skb
)
227 /* In case we are ported somewhere (ebtables?) where ip_hdr(skb)
228 isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */
229 int ip_hl
= 4*ip_hdr(skb
)->ihl
;
231 if( ip_hdr(skb
)->protocol
== IPPROTO_TCP
) {
232 /* 12 == offset into TCP header for the header length field.
233 Can't get this with skb->h.th->doff because the tcphdr
234 struct doesn't get set when routing (this is confirmed to be
235 true in Netfilter as well as QoS.) */
236 int tcp_hl
= 4*(skb
->data
[ip_hl
+ 12] >> 4);
238 return ip_hl
+ tcp_hl
;
239 } else if( ip_hdr(skb
)->protocol
== IPPROTO_UDP
) {
240 return ip_hl
+ 8; /* UDP header is always 8 bytes */
241 } else if( ip_hdr(skb
)->protocol
== IPPROTO_ICMP
) {
242 return ip_hl
+ 8; /* ICMP header is 8 bytes */
245 printk(KERN_ERR
"layer7: tried to handle unknown "
247 return ip_hl
+ 8; /* something reasonable */
251 /* handles whether there's a match when we aren't appending data anymore */
252 static int match_no_append(struct nf_conn
* conntrack
,
253 struct nf_conn
* master_conntrack
,
254 enum ip_conntrack_info ctinfo
,
255 enum ip_conntrack_info master_ctinfo
,
256 const struct xt_layer7_info
* info
)
258 /* If we're in here, throw the app data away */
259 if(master_conntrack
->layer7
.app_data
!= NULL
) {
261 #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
262 if(!master_conntrack
->layer7
.app_proto
) {
264 friendly_print(master_conntrack
->layer7
.app_data
);
266 hex_print(master_conntrack
->layer7
.app_data
);
267 DPRINTK("\nl7-filter gave up after %d bytes "
268 "(%d packets):\n%s\n",
269 strlen(f
), total_acct_packets(master_conntrack
), f
);
271 DPRINTK("In hex: %s\n", g
);
276 kfree(master_conntrack
->layer7
.app_data
);
277 master_conntrack
->layer7
.app_data
= NULL
; /* don't free again */
280 if(master_conntrack
->layer7
.app_proto
){
281 /* Here child connections set their .app_proto (for /proc) */
282 if(!conntrack
->layer7
.app_proto
) {
283 conntrack
->layer7
.app_proto
=
284 kmalloc(strlen(master_conntrack
->layer7
.app_proto
)+1,
286 if(!conntrack
->layer7
.app_proto
){
288 printk(KERN_ERR
"layer7: out of memory "
289 "in match_no_append, "
293 strcpy(conntrack
->layer7
.app_proto
,
294 master_conntrack
->layer7
.app_proto
);
297 return (!strcmp(master_conntrack
->layer7
.app_proto
,
301 /* If not classified, set to "unknown" to distinguish from
302 connections that are still being tested. */
303 master_conntrack
->layer7
.app_proto
=
304 kmalloc(strlen("unknown")+1, GFP_ATOMIC
);
305 if(!master_conntrack
->layer7
.app_proto
){
307 printk(KERN_ERR
"layer7: out of memory in "
308 "match_no_append, bailing.\n");
311 strcpy(master_conntrack
->layer7
.app_proto
, "unknown");
316 /* add the new app data to the conntrack. Return number of bytes added. */
317 static int add_data(struct nf_conn
* master_conntrack
,
318 char * app_data
, int appdatalen
)
321 int oldlength
= master_conntrack
->layer7
.app_data_len
;
323 /* This is a fix for a race condition by Deti Fliegl. However, I'm not
324 clear on whether the race condition exists or whether this really
325 fixes it. I might just be being dense... Anyway, if it's not really
326 a fix, all it does is waste a very small amount of time. */
327 if(!master_conntrack
->layer7
.app_data
) return 0;
329 /* Strip nulls. Make everything lower case (our regex lib doesn't
330 do case insensitivity). Add it to the end of the current data. */
331 for(i
= 0; i
< maxdatalen
-oldlength
-1 &&
332 i
< appdatalen
; i
++) {
333 if(app_data
[i
] != '\0') {
334 /* the kernel version of tolower mungs 'upper ascii' */
335 master_conntrack
->layer7
.app_data
[length
+oldlength
] =
336 isascii(app_data
[i
])?
337 tolower(app_data
[i
]) : app_data
[i
];
342 master_conntrack
->layer7
.app_data
[length
+oldlength
] = '\0';
343 master_conntrack
->layer7
.app_data_len
= length
+ oldlength
;
348 /* taken from drivers/video/modedb.c */
349 static int my_atoi(const char *s
)
356 val
= 10*val
+(*s
-'0');
364 static int layer7_numpackets_proc_show(struct seq_file
*s
, void *p
) {
365 seq_printf(s
, "%d\n", num_packets
);
370 static int layer7_numpackets_proc_open(struct inode
*inode
, struct file
*file
) {
371 return single_open(file
, layer7_numpackets_proc_show
, NULL
);
374 /* Read in num_packets from userland */
375 static ssize_t
layer7_numpackets_write_proc(struct file
* file
, const char __user
*buffer
,
376 size_t count
, loff_t
*data
) {
380 if (copy_from_user(&value
, buffer
, sizeof(value
)))
383 new_num_packets
= my_atoi(value
);
385 if ((new_num_packets
< 1) || (new_num_packets
> 99)) {
386 printk(KERN_WARNING
"layer7: numpackets must be between 1 and 99\n");
390 num_packets
= new_num_packets
;
396 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
397 match(const struct sk_buff
*skbin
, struct xt_action_param
*par
)
398 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
399 match(const struct sk_buff
*skbin
, const struct xt_match_param
*par
)
401 match(const struct sk_buff
*skbin
,
402 const struct net_device
*in
,
403 const struct net_device
*out
,
404 const struct xt_match
*match
,
405 const void *matchinfo
,
407 unsigned int protoff
,
411 /* sidestep const without getting a compiler warning... */
412 struct sk_buff
* skb
= (struct sk_buff
*)skbin
;
414 const struct xt_layer7_info
* info
=
415 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
421 enum ip_conntrack_info master_ctinfo
, ctinfo
;
422 struct nf_conn
*master_conntrack
, *conntrack
;
423 unsigned char * app_data
;
424 unsigned int pattern_result
, appdatalen
;
425 regexp
* comppattern
;
427 /* Be paranoid/incompetent - lock the entire match function. */
428 spin_lock_bh(&l7_lock
);
430 if(!can_handle(skb
)){
431 DPRINTK("layer7: This is some protocol I can't handle.\n");
432 spin_unlock_bh(&l7_lock
);
436 /* Treat parent & all its children together as one connection, except
437 for the purpose of setting conntrack->layer7.app_proto in the actual
438 connection. This makes /proc/net/ip_conntrack more satisfying. */
439 if(!(conntrack
= nf_ct_get(skb
, &ctinfo
)) ||
440 !(master_conntrack
=nf_ct_get(skb
,&master_ctinfo
))){
441 DPRINTK("layer7: couldn't get conntrack.\n");
442 spin_unlock_bh(&l7_lock
);
446 /* Try to get a master conntrack (and its master etc) for FTP, etc. */
447 while (master_ct(master_conntrack
) != NULL
)
448 master_conntrack
= master_ct(master_conntrack
);
450 /* if we've classified it or seen too many packets */
451 if(total_acct_packets(master_conntrack
) > num_packets
||
452 master_conntrack
->layer7
.app_proto
) {
454 pattern_result
= match_no_append(conntrack
, master_conntrack
,
455 ctinfo
, master_ctinfo
, info
);
457 /* skb->cb[0] == seen. Don't do things twice if there are
458 multiple l7 rules. I'm not sure that using cb for this purpose
459 is correct, even though it says "put your private variables
460 there". But it doesn't look like it is being used for anything
461 else in the skbs that make it here. */
462 skb
->cb
[0] = 1; /* marking it seen here's probably irrelevant */
464 spin_unlock_bh(&l7_lock
);
465 return (pattern_result
^ info
->invert
);
468 if(skb_is_nonlinear(skb
)){
469 if(skb_linearize(skb
) != 0){
471 printk(KERN_ERR
"layer7: failed to linearize "
472 "packet, bailing.\n");
473 spin_unlock_bh(&l7_lock
);
478 /* now that the skb is linearized, it's safe to set these. */
479 app_data
= skb
->data
+ app_data_offset(skb
);
480 appdatalen
= skb_tail_pointer(skb
) - app_data
;
482 /* the return value gets checked later, when we're ready to use it */
483 comppattern
= compile_and_cache(info
->pattern
, info
->protocol
);
485 /* On the first packet of a connection, allocate space for app data */
486 if(total_acct_packets(master_conntrack
) == 1 && !skb
->cb
[0] &&
487 !master_conntrack
->layer7
.app_data
){
488 master_conntrack
->layer7
.app_data
=
489 kmalloc(maxdatalen
, GFP_ATOMIC
);
490 if(!master_conntrack
->layer7
.app_data
){
492 printk(KERN_ERR
"layer7: out of memory in "
493 "match, bailing.\n");
494 spin_unlock_bh(&l7_lock
);
498 master_conntrack
->layer7
.app_data
[0] = '\0';
501 /* Can be here, but unallocated, if numpackets is increased near
502 the beginning of a connection */
503 if(master_conntrack
->layer7
.app_data
== NULL
){
504 spin_unlock_bh(&l7_lock
);
505 return info
->invert
; /* unmatched */
510 newbytes
= add_data(master_conntrack
, app_data
, appdatalen
);
512 if(newbytes
== 0) { /* didn't add any data */
514 /* Didn't match before, not going to match now */
515 spin_unlock_bh(&l7_lock
);
520 /* If looking for "unknown", then never match. "Unknown" means that
521 we've given up; we're still trying with these packets. */
522 if(!strcmp(info
->protocol
, "unknown")) {
524 /* If looking for "unset", then always match. "Unset" means that we
525 haven't yet classified the connection. */
526 } else if(!strcmp(info
->protocol
, "unset")) {
528 DPRINTK("layer7: matched unset: not yet classified "
530 total_acct_packets(master_conntrack
), num_packets
);
531 /* If the regexp failed to compile, don't bother running it */
532 } else if(comppattern
&&
533 regexec(comppattern
, master_conntrack
->layer7
.app_data
)){
534 DPRINTK("layer7: matched %s\n", info
->protocol
);
536 } else pattern_result
= 0;
538 if(pattern_result
== 1) {
539 master_conntrack
->layer7
.app_proto
=
540 kmalloc(strlen(info
->protocol
)+1, GFP_ATOMIC
);
541 if(!master_conntrack
->layer7
.app_proto
){
543 printk(KERN_ERR
"layer7: out of memory in "
544 "match, bailing.\n");
545 spin_unlock_bh(&l7_lock
);
546 return (pattern_result
^ info
->invert
);
548 strcpy(master_conntrack
->layer7
.app_proto
, info
->protocol
);
549 } else if(pattern_result
> 1) { /* cleanup from "unset" */
553 /* mark the packet seen */
556 spin_unlock_bh(&l7_lock
);
557 return (pattern_result
^ info
->invert
);
560 // load nf_conntrack_ipv4
561 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
566 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
567 check(const struct xt_mtchk_param
*par
)
569 if (nf_ct_l3proto_try_module_get(par
->match
->family
) < 0) {
570 printk(KERN_WARNING
"can't load conntrack support for "
571 "proto=%d\n", par
->match
->family
);
573 check(const char *tablename
, const void *inf
,
574 const struct xt_match
*match
, void *matchinfo
,
575 unsigned int hook_mask
)
577 if (nf_ct_l3proto_try_module_get(match
->family
) < 0) {
578 printk(KERN_WARNING
"can't load conntrack support for "
579 "proto=%d\n", match
->family
);
581 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
593 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
594 static void destroy(const struct xt_mtdtor_param
*par
)
596 nf_ct_l3proto_module_put(par
->match
->family
);
599 static void destroy(const struct xt_match
*match
, void *matchinfo
)
601 nf_ct_l3proto_module_put(match
->family
);
605 static struct xt_match xt_layer7_match
[] __read_mostly
= {
612 .matchsize
= sizeof(struct xt_layer7_info
),
617 static const struct file_operations layer7_numpackets_proc_fops
= {
618 .owner
= THIS_MODULE
,
619 .open
= layer7_numpackets_proc_open
,
622 .release
= single_release
,
623 .write
= layer7_numpackets_write_proc
,
626 static int __init
xt_layer7_init(void)
630 // Register proc interface
631 proc_create_data("layer7_numpackets", 0644,
632 init_net
.proc_net
, &layer7_numpackets_proc_fops
, NULL
);
635 printk(KERN_WARNING
"layer7: maxdatalen can't be < 1, "
639 /* This is not a hard limit. It's just here to prevent people from
640 bringing their slow machines to a grinding halt. */
641 else if(maxdatalen
> 65536) {
642 printk(KERN_WARNING
"layer7: maxdatalen can't be > 65536, "
646 return xt_register_matches(xt_layer7_match
,
647 ARRAY_SIZE(xt_layer7_match
));
650 static void __exit
xt_layer7_fini(void)
652 remove_proc_entry("layer7_numpackets", init_net
.proc_net
);
653 xt_unregister_matches(xt_layer7_match
, ARRAY_SIZE(xt_layer7_match
));
656 module_init(xt_layer7_init
);
657 module_exit(xt_layer7_fini
);