1/* 2 Kernel module to match application layer (OSI layer 7) data in connections. 3 4 http://l7-filter.sf.net 5 6 (C) 2003, 2004, 2005, 2006, 2007 Matthew Strait and Ethan Sommer. 7 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 13 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. 17*/ 18 19#include <linux/spinlock.h> 20#include <net/ip.h> 21#include <net/tcp.h> 22#include <linux/module.h> 23#include <linux/skbuff.h> 24#include <linux/netfilter.h> 25#include <net/netfilter/nf_conntrack.h> 26#include <net/netfilter/nf_conntrack_core.h> 27#include <linux/netfilter/x_tables.h> 28#include <linux/netfilter/xt_layer7.h> 29#include <linux/ctype.h> 30#include <linux/proc_fs.h> 31#include <net/net_namespace.h> 32#include <net/netfilter/nf_conntrack_acct.h> 33 34#include "regexp/regexp.c" 35 36MODULE_LICENSE("GPL"); 37MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>"); 38MODULE_DESCRIPTION("iptables application layer match module"); 39MODULE_ALIAS("ipt_layer7"); 40MODULE_VERSION("2.0"); 41 42static int maxdatalen = 2048; // this is the default 43module_param(maxdatalen, int, 0444); 44MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter"); 45#ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG 46 #define DPRINTK(format,args...) printk(format,##args) 47#else 48 #define DPRINTK(format,args...) 49#endif 50 51/* Number of packets whose data we look at. 52This can be modified through /proc/net/layer7_numpackets */ 53static int num_packets = 10; 54 55static struct pattern_cache { 56 char * regex_string; 57 regexp * pattern; 58 struct pattern_cache * next; 59} * first_pattern_cache = NULL; 60 61DEFINE_SPINLOCK(l7_lock); 62 63#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG 64/* Converts an unfriendly string into a friendly one by 65replacing unprintables with periods and all whitespace with " ". */ 66static char * friendly_print(unsigned char * s) 67{ 68 char * f = kmalloc(strlen(s) + 1, GFP_ATOMIC); 69 int i; 70 71 if(!f) { 72 if (net_ratelimit()) 73 printk(KERN_ERR "layer7: out of memory in " 74 "friendly_print, bailing.\n"); 75 return NULL; 76 } 77 78 for(i = 0; i < strlen(s); i++){ 79 if(isprint(s[i]) && s[i] < 128) f[i] = s[i]; 80 else if(isspace(s[i])) f[i] = ' '; 81 else f[i] = '.'; 82 } 83 f[i] = '\0'; 84 return f; 85} 86 87static char dec2hex(int i) 88{ 89 switch (i) { 90 case 0 ... 9: 91 return (char)(i + '0'); 92 break; 93 case 10 ... 15: 94 return (char)(i - 10 + 'a'); 95 break; 96 default: 97 if (net_ratelimit()) 98 printk("Problem in dec2hex\n"); 99 return '\0'; 100 } 101} 102 103static char * hex_print(unsigned char * s) 104{ 105 char * g = kmalloc(strlen(s)*3 + 1, GFP_ATOMIC); 106 int i; 107 108 if(!g) { 109 if (net_ratelimit()) 110 printk(KERN_ERR "layer7: out of memory in hex_print, " 111 "bailing.\n"); 112 return NULL; 113 } 114 115 for(i = 0; i < strlen(s); i++) { 116 g[i*3 ] = dec2hex(s[i]/16); 117 g[i*3 + 1] = dec2hex(s[i]%16); 118 g[i*3 + 2] = ' '; 119 } 120 g[i*3] = '\0'; 121 122 return g; 123} 124#endif // DEBUG 125 126/* Use instead of regcomp. As we expect to be seeing the same regexps over and 127over again, it make sense to cache the results. */ 128static regexp * compile_and_cache(char * regex_string, char * protocol) 129{ 130 struct pattern_cache * node = first_pattern_cache; 131 struct pattern_cache * last_pattern_cache = first_pattern_cache; 132 struct pattern_cache * tmp; 133 unsigned int len; 134 135 while (node != NULL) { 136 if (!strcmp(node->regex_string, regex_string)) 137 return node->pattern; 138 139 last_pattern_cache = node;/* points at the last non-NULL node */ 140 node = node->next; 141 } 142 143 /* If we reach the end of the list, then we have not yet cached 144 the pattern for this regex. Let's do that now. 145 Be paranoid about running out of memory to avoid list corruption. */ 146 tmp = kmalloc(sizeof(struct pattern_cache), GFP_ATOMIC); 147 148 if(!tmp) { 149 if (net_ratelimit()) 150 printk(KERN_ERR "layer7: out of memory in " 151 "compile_and_cache, bailing.\n"); 152 return NULL; 153 } 154 155 tmp->regex_string = kmalloc(strlen(regex_string) + 1, GFP_ATOMIC); 156 tmp->pattern = kmalloc(sizeof(struct regexp), GFP_ATOMIC); 157 tmp->next = NULL; 158 159 if(!tmp->regex_string || !tmp->pattern) { 160 if (net_ratelimit()) 161 printk(KERN_ERR "layer7: out of memory in " 162 "compile_and_cache, bailing.\n"); 163 kfree(tmp->regex_string); 164 kfree(tmp->pattern); 165 kfree(tmp); 166 return NULL; 167 } 168 169 /* Ok. The new node is all ready now. */ 170 node = tmp; 171 172 if(first_pattern_cache == NULL) /* list is empty */ 173 first_pattern_cache = node; /* make node the beginning */ 174 else 175 last_pattern_cache->next = node; /* attach node to the end */ 176 177 /* copy the string and compile the regex */ 178 len = strlen(regex_string); 179 DPRINTK("About to compile this: \"%s\"\n", regex_string); 180 node->pattern = regcomp(regex_string, &len); 181 if ( !node->pattern ) { 182 if (net_ratelimit()) 183 printk(KERN_ERR "layer7: Error compiling regexp " 184 "\"%s\" (%s)\n", 185 regex_string, protocol); 186 /* pattern is now cached as NULL, so we won't try again. */ 187 } 188 189 strcpy(node->regex_string, regex_string); 190 return node->pattern; 191} 192 193static int can_handle(const struct sk_buff *skb) 194{ 195 if(skb->protocol != htons(ETH_P_IP)) /* not IP */ 196 return 0; 197 if(ip_hdr(skb)->protocol != IPPROTO_TCP && 198 ip_hdr(skb)->protocol != IPPROTO_UDP && 199 ip_hdr(skb)->protocol != IPPROTO_ICMP) 200 return 0; 201 return 1; 202} 203 204/* Returns offset the into the skb->data that the application data starts */ 205static int app_data_offset(const struct sk_buff *skb) 206{ 207 /* In case we are ported somewhere (ebtables?) where skb->nh.iph 208 isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */ 209 int ip_hl = 4*ip_hdr(skb)->ihl; 210 211 if( ip_hdr(skb)->protocol == IPPROTO_TCP ) { 212 /* 12 == offset into TCP header for the header length field. 213 Can't get this with skb->h.th->doff because the tcphdr 214 struct doesn't get set when routing (this is confirmed to be 215 true in Netfilter as well as QoS.) */ 216 int tcp_hl = 4*(skb->data[ip_hl + 12] >> 4); 217 218 return ip_hl + tcp_hl; 219 } else if( ip_hdr(skb)->protocol == IPPROTO_UDP ) { 220 return ip_hl + 8; /* UDP header is always 8 bytes */ 221 } else if( ip_hdr(skb)->protocol == IPPROTO_ICMP ) { 222 return ip_hl + 8; /* ICMP header is 8 bytes */ 223 } else { 224 if (net_ratelimit()) 225 printk(KERN_ERR "layer7: tried to handle unknown " 226 "protocol!\n"); 227 return ip_hl + 8; /* something reasonable */ 228 } 229} 230 231/* handles whether there's a match when we aren't appending data anymore */ 232static int match_no_append(struct nf_conn * conntrack, 233 struct nf_conn * master_conntrack, 234 enum ip_conntrack_info ctinfo, 235 enum ip_conntrack_info master_ctinfo, 236 struct xt_layer7_info * info) 237{ 238 /* If we're in here, throw the app data away */ 239 if(master_conntrack->layer7.app_data != NULL) { 240 241 #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG 242 if(!master_conntrack->layer7.app_proto) { 243 char * f = 244 friendly_print(master_conntrack->layer7.app_data); 245 char * g = 246 hex_print(master_conntrack->layer7.app_data); 247 struct nf_conn_counter *acct; 248 u_int32_t packets = 0; 249 250 if ((acct = nf_conn_acct_find(master_conntrack))) 251 packets = acct[IP_CT_DIR_ORIGINAL].packets + acct[IP_CT_DIR_REPLY].packets; 252 DPRINTK("\nl7-filter gave up after %d bytes " 253 "(%d packets):\n%s\n", 254 strlen(f), packets, f); 255 kfree(f); 256 DPRINTK("In hex: %s\n", g); 257 kfree(g); 258 } 259 #endif 260 261 kfree(master_conntrack->layer7.app_data); 262 master_conntrack->layer7.app_data = NULL; /* don't free again */ 263 } 264 265 if(master_conntrack->layer7.app_proto){ 266 /* Here child connections set their .app_proto (for /proc) */ 267 if(!conntrack->layer7.app_proto) { 268 conntrack->layer7.app_proto = 269 kmalloc(strlen(master_conntrack->layer7.app_proto)+1, 270 GFP_ATOMIC); 271 if(!conntrack->layer7.app_proto){ 272 if (net_ratelimit()) 273 printk(KERN_ERR "layer7: out of memory " 274 "in match_no_append, " 275 "bailing.\n"); 276 return 1; 277 } 278 strcpy(conntrack->layer7.app_proto, 279 master_conntrack->layer7.app_proto); 280 } 281 282 return (!strcmp(master_conntrack->layer7.app_proto, 283 info->protocol)); 284 } 285 else { 286 /* If not classified, set to "unknown" to distinguish from 287 connections that are still being tested. */ 288 master_conntrack->layer7.app_proto = 289 kmalloc(strlen("unknown")+1, GFP_ATOMIC); 290 if(!master_conntrack->layer7.app_proto){ 291 if (net_ratelimit()) 292 printk(KERN_ERR "layer7: out of memory in " 293 "match_no_append, bailing.\n"); 294 return 1; 295 } 296 strcpy(master_conntrack->layer7.app_proto, "unknown"); 297 return 0; 298 } 299} 300 301/* add the new app data to the conntrack. Return number of bytes added. */ 302static int add_data(struct nf_conn * master_conntrack, 303 char * app_data, int appdatalen) 304{ 305 int length = 0, i; 306 int oldlength = master_conntrack->layer7.app_data_len; 307 308 /* This is a fix for a race condition by Deti Fliegl. However, I'm not 309 clear on whether the race condition exists or whether this really 310 fixes it. I might just be being dense... Anyway, if it's not really 311 a fix, all it does is waste a very small amount of time. */ 312 if(!master_conntrack->layer7.app_data) return 0; 313 314 /* Strip nulls. Make everything lower case (our regex lib doesn't 315 do case insensitivity). Add it to the end of the current data. */ 316 for(i = 0; i < maxdatalen-oldlength-1 && 317 i < appdatalen; i++) { 318 if(app_data[i] != '\0') { 319 /* the kernel version of tolower mungs 'upper ascii' */ 320 master_conntrack->layer7.app_data[length+oldlength] = 321 isascii(app_data[i])? 322 tolower(app_data[i]) : app_data[i]; 323 length++; 324 } 325 } 326 327 master_conntrack->layer7.app_data[length+oldlength] = '\0'; 328 master_conntrack->layer7.app_data_len = length + oldlength; 329 330 return length; 331} 332 333/* taken from drivers/video/modedb.c */ 334static int my_atoi(const char *s) 335{ 336 int val = 0; 337 338 for (;; s++) { 339 switch (*s) { 340 case '0'...'9': 341 val = 10*val+(*s-'0'); 342 break; 343 default: 344 return val; 345 } 346 } 347} 348 349/* write out num_packets to userland. */ 350static int layer7_read_proc(char* page, char ** start, off_t off, int count, 351 int* eof, void * data) 352{ 353 if(num_packets > 99 && net_ratelimit()) 354 printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n"); 355 356 page[0] = num_packets/10 + '0'; 357 page[1] = num_packets%10 + '0'; 358 page[2] = '\n'; 359 page[3] = '\0'; 360 361 *eof=1; 362 363 return 3; 364} 365 366/* Read in num_packets from userland */ 367static int layer7_write_proc(struct file* file, const char* buffer, 368 unsigned long count, void *data) 369{ 370 char * foo = kmalloc(count, GFP_ATOMIC); 371 372 if(!foo){ 373 if (net_ratelimit()) 374 printk(KERN_ERR "layer7: out of memory, bailing. " 375 "num_packets unchanged.\n"); 376 return count; 377 } 378 379 if(copy_from_user(foo, buffer, count)) { 380 return -EFAULT; 381 } 382 383 384 num_packets = my_atoi(foo); 385 kfree (foo); 386 387 /* This has an arbitrary limit to make the math easier. I'm lazy. 388 But anyway, 99 is a LOT! If you want more, you're doing it wrong! */ 389 if(num_packets > 99) { 390 printk(KERN_WARNING "layer7: num_packets can't be > 99.\n"); 391 num_packets = 99; 392 } else if(num_packets < 1) { 393 printk(KERN_WARNING "layer7: num_packets can't be < 1.\n"); 394 num_packets = 1; 395 } 396 397 return count; 398} 399 400static bool match(const struct sk_buff *skbin, struct xt_action_param *par) 401{ 402 /* sidestep const without getting a compiler warning... */ 403 struct sk_buff * skb = (struct sk_buff *)skbin; 404 405 struct xt_layer7_info * info = (struct xt_layer7_info *)par->matchinfo; 406 enum ip_conntrack_info master_ctinfo, ctinfo; 407 struct nf_conn *master_conntrack, *conntrack; 408 unsigned char * app_data; 409 unsigned int pattern_result, appdatalen; 410 regexp * comppattern; 411 struct nf_conn_counter *acct; 412 u_int32_t packets = 0; 413 414 /* Be paranoid/incompetent - lock the entire match function. */ 415 spin_lock_bh(&l7_lock); 416 417 if(!can_handle(skb)){ 418 DPRINTK("layer7: This is some protocol I can't handle.\n"); 419 spin_unlock_bh(&l7_lock); 420 return info->invert; 421 } 422 423 /* Treat parent & all its children together as one connection, except 424 for the purpose of setting conntrack->layer7.app_proto in the actual 425 connection. This makes /proc/net/ip_conntrack more satisfying. */ 426 if(!(conntrack = nf_ct_get((struct sk_buff *)skb, &ctinfo)) || 427 !(master_conntrack=nf_ct_get((struct sk_buff *)skb,&master_ctinfo))){ 428 DPRINTK("layer7: couldn't get conntrack.\n"); 429 spin_unlock_bh(&l7_lock); 430 return info->invert; 431 } 432 433 /* Try to get a master conntrack (and its master etc) for FTP, etc. */ 434 while (master_ct(master_conntrack) != NULL) 435 master_conntrack = master_ct(master_conntrack); 436 437 /* if we've classified it or seen too many packets */ 438 if ((acct = nf_conn_acct_find(master_conntrack))) 439 packets = acct[IP_CT_DIR_ORIGINAL].packets + acct[IP_CT_DIR_REPLY].packets; 440 if(packets > num_packets || 441 master_conntrack->layer7.app_proto) { 442 443 pattern_result = match_no_append(conntrack, master_conntrack, 444 ctinfo, master_ctinfo, info); 445 446 /* skb->cb[0] == seen. Don't do things twice if there are 447 multiple l7 rules. I'm not sure that using cb for this purpose 448 is correct, even though it says "put your private variables 449 there". But it doesn't look like it is being used for anything 450 else in the skbs that make it here. */ 451 skb->cb[0] = 1; /* marking it seen here's probably irrelevant */ 452 453 spin_unlock_bh(&l7_lock); 454 return (pattern_result ^ info->invert); 455 } 456 457 if(skb_is_nonlinear(skb)){ 458 if(skb_linearize(skb) != 0){ 459 if (net_ratelimit()) 460 printk(KERN_ERR "layer7: failed to linearize " 461 "packet, bailing.\n"); 462 spin_unlock_bh(&l7_lock); 463 return info->invert; 464 } 465 } 466 467 /* now that the skb is linearized, it's safe to set these. */ 468 app_data = skb->data + app_data_offset(skb); 469 appdatalen = skb->tail - app_data; 470 471 /* the return value gets checked later, when we're ready to use it */ 472 comppattern = compile_and_cache(info->pattern, info->protocol); 473 474 /* On the first packet of a connection, allocate space for app data */ 475 if(packets == 1 && !skb->cb[0] && 476 !master_conntrack->layer7.app_data){ 477 master_conntrack->layer7.app_data = 478 kmalloc(maxdatalen, GFP_ATOMIC); 479 if(!master_conntrack->layer7.app_data){ 480 if (net_ratelimit()) 481 printk(KERN_ERR "layer7: out of memory in " 482 "match, bailing.\n"); 483 spin_unlock_bh(&l7_lock); 484 return info->invert; 485 } 486 487 master_conntrack->layer7.app_data[0] = '\0'; 488 } 489 490 /* Can be here, but unallocated, if numpackets is increased near 491 the beginning of a connection */ 492 if(master_conntrack->layer7.app_data == NULL){ 493 spin_unlock_bh(&l7_lock); 494 return (info->invert); /* unmatched */ 495 } 496 497 if(!skb->cb[0]){ 498 int newbytes; 499 newbytes = add_data(master_conntrack, app_data, appdatalen); 500 501 if(newbytes == 0) { /* didn't add any data */ 502 skb->cb[0] = 1; 503 /* Didn't match before, not going to match now */ 504 spin_unlock_bh(&l7_lock); 505 return info->invert; 506 } 507 } 508 509 /* If looking for "unknown", then never match. "Unknown" means that 510 we've given up; we're still trying with these packets. */ 511 if(!strcmp(info->protocol, "unknown")) { 512 pattern_result = 0; 513 /* If looking for "unset", then always match. "Unset" means that we 514 haven't yet classified the connection. */ 515 } else if(!strcmp(info->protocol, "unset")) { 516 struct nf_conn_counter *acct; 517 u_int32_t packets = 0; 518 519 if ((acct = nf_conn_acct_find(master_conntrack))) 520 packets = acct[IP_CT_DIR_ORIGINAL].packets + acct[IP_CT_DIR_REPLY].packets; 521 pattern_result = 2; 522 DPRINTK("layer7: matched unset: not yet classified " 523 "(%d/%d packets)\n", packets, num_packets); 524 /* If the regexp failed to compile, don't bother running it */ 525 } else if(comppattern && 526 regexec(comppattern, master_conntrack->layer7.app_data)){ 527 DPRINTK("layer7: matched %s\n", info->protocol); 528 pattern_result = 1; 529 } else pattern_result = 0; 530 531 if(pattern_result == 1) { 532 master_conntrack->layer7.app_proto = 533 kmalloc(strlen(info->protocol)+1, GFP_ATOMIC); 534 if(!master_conntrack->layer7.app_proto){ 535 if (net_ratelimit()) 536 printk(KERN_ERR "layer7: out of memory in " 537 "match, bailing.\n"); 538 spin_unlock_bh(&l7_lock); 539 return (pattern_result ^ info->invert); 540 } 541 strcpy(master_conntrack->layer7.app_proto, info->protocol); 542 } else if(pattern_result > 1) { /* cleanup from "unset" */ 543 pattern_result = 1; 544 } 545 546 /* mark the packet seen */ 547 skb->cb[0] = 1; 548 549 spin_unlock_bh(&l7_lock); 550 return (pattern_result ^ info->invert); 551} 552 553static int check(const struct xt_mtchk_param *par) 554{ 555 // load nf_conntrack_ipv4 556 if (nf_ct_l3proto_try_module_get(par->match->family) < 0) { 557 printk(KERN_WARNING "can't load conntrack support for " 558 "proto=%d\n", par->match->family); 559 return -EINVAL; 560 } 561 return 0; 562} 563 564static void 565destroy(const struct xt_mtdtor_param *par) 566{ 567 nf_ct_l3proto_module_put(par->match->family); 568} 569 570static struct xt_match xt_layer7_match[] = { 571{ 572 .name = "layer7", 573 .family = AF_INET, 574 .checkentry = check, 575 .match = match, 576 .destroy = destroy, 577 .matchsize = sizeof(struct xt_layer7_info), 578 .me = THIS_MODULE 579} 580}; 581 582static void layer7_cleanup_proc(void) 583{ 584 remove_proc_entry("layer7_numpackets", init_net.proc_net); 585} 586 587/* register the proc file */ 588static void layer7_init_proc(void) 589{ 590 struct proc_dir_entry* entry; 591 entry = create_proc_entry("layer7_numpackets", 0644, init_net.proc_net); 592 entry->read_proc = layer7_read_proc; 593 entry->write_proc = layer7_write_proc; 594} 595 596static int __init xt_layer7_init(void) 597{ 598 need_conntrack(); 599 600 layer7_init_proc(); 601 if(maxdatalen < 1) { 602 printk(KERN_WARNING "layer7: maxdatalen can't be < 1, " 603 "using 1\n"); 604 maxdatalen = 1; 605 } 606 /* This is not a hard limit. It's just here to prevent people from 607 bringing their slow machines to a grinding halt. */ 608 else if(maxdatalen > 65536) { 609 printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, " 610 "using 65536\n"); 611 maxdatalen = 65536; 612 } 613 return xt_register_matches(xt_layer7_match, 614 ARRAY_SIZE(xt_layer7_match)); 615} 616 617static void __exit xt_layer7_fini(void) 618{ 619 layer7_cleanup_proc(); 620 xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match)); 621} 622 623module_init(xt_layer7_init); 624module_exit(xt_layer7_fini); 625 626