|
|
|
@ -170,7 +170,7 @@ |
|
|
|
|
+
|
|
|
|
|
+/* 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,
|
|
|
|
|
+static regexp * compile_and_cache(const char * regex_string,
|
|
|
|
|
+ const char * protocol)
|
|
|
|
|
+{
|
|
|
|
|
+ struct pattern_cache * node = first_pattern_cache;
|
|
|
|
@ -227,7 +227,7 @@ |
|
|
|
|
+ if ( !node->pattern ) {
|
|
|
|
|
+ if (net_ratelimit())
|
|
|
|
|
+ printk(KERN_ERR "layer7: Error compiling regexp "
|
|
|
|
|
+ "\"%s\" (%s)\n",
|
|
|
|
|
+ "\"%s\" (%s)\n",
|
|
|
|
|
+ regex_string, protocol);
|
|
|
|
|
+ /* pattern is now cached as NULL, so we won't try again. */
|
|
|
|
|
+ }
|
|
|
|
@ -275,8 +275,8 @@ |
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 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,
|
|
|
|
|
+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)
|
|
|
|
@ -286,9 +286,9 @@ |
|
|
|
|
+
|
|
|
|
|
+ #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
|
|
|
|
|
+ if(!master_conntrack->layer7.app_proto) {
|
|
|
|
|
+ char * f =
|
|
|
|
|
+ char * f =
|
|
|
|
|
+ friendly_print(master_conntrack->layer7.app_data);
|
|
|
|
|
+ char * g =
|
|
|
|
|
+ char * g =
|
|
|
|
|
+ hex_print(master_conntrack->layer7.app_data);
|
|
|
|
|
+ DPRINTK("\nl7-filter gave up after %d bytes "
|
|
|
|
|
+ "(%d packets):\n%s\n",
|
|
|
|
@ -306,8 +306,8 @@ |
|
|
|
|
+ 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,
|
|
|
|
|
+ conntrack->layer7.app_proto =
|
|
|
|
|
+ kmalloc(strlen(master_conntrack->layer7.app_proto)+1,
|
|
|
|
|
+ GFP_ATOMIC);
|
|
|
|
|
+ if(!conntrack->layer7.app_proto){
|
|
|
|
|
+ if (net_ratelimit())
|
|
|
|
@ -316,17 +316,17 @@ |
|
|
|
|
+ "bailing.\n");
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ strcpy(conntrack->layer7.app_proto,
|
|
|
|
|
+ strcpy(conntrack->layer7.app_proto,
|
|
|
|
|
+ master_conntrack->layer7.app_proto);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return (!strcmp(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 =
|
|
|
|
|
+ master_conntrack->layer7.app_proto =
|
|
|
|
|
+ kmalloc(strlen("unknown")+1, GFP_ATOMIC);
|
|
|
|
|
+ if(!master_conntrack->layer7.app_proto){
|
|
|
|
|
+ if (net_ratelimit())
|
|
|
|
@ -346,9 +346,9 @@ |
|
|
|
|
+ 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
|
|
|
|
|
+ /* 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;
|
|
|
|
|
+
|
|
|
|
@ -359,7 +359,7 @@ |
|
|
|
|
+ if(app_data[i] != '\0') {
|
|
|
|
|
+ /* the kernel version of tolower mungs 'upper ascii' */
|
|
|
|
|
+ master_conntrack->layer7.app_data[length+oldlength] =
|
|
|
|
|
+ isascii(app_data[i])?
|
|
|
|
|
+ isascii(app_data[i])?
|
|
|
|
|
+ tolower(app_data[i]) : app_data[i];
|
|
|
|
|
+ length++;
|
|
|
|
|
+ }
|
|
|
|
@ -449,7 +449,7 @@ |
|
|
|
|
+ bool *hotdrop)
|
|
|
|
|
+{
|
|
|
|
|
+ /* sidestep const without getting a compiler warning... */
|
|
|
|
|
+ struct sk_buff * skb = (struct sk_buff *)skbin;
|
|
|
|
|
+ struct sk_buff * skb = (struct sk_buff *)skbin;
|
|
|
|
|
+
|
|
|
|
|
+ const struct xt_layer7_info * info = matchinfo;
|
|
|
|
|
+ enum ip_conntrack_info master_ctinfo, ctinfo;
|
|
|
|
@ -485,12 +485,12 @@ |
|
|
|
|
+ if(TOTAL_PACKETS > num_packets ||
|
|
|
|
|
+ master_conntrack->layer7.app_proto) {
|
|
|
|
|
+
|
|
|
|
|
+ pattern_result = match_no_append(conntrack, master_conntrack,
|
|
|
|
|
+ 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
|
|
|
|
|
+ /* 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 */
|
|
|
|
@ -517,9 +517,9 @@ |
|
|
|
|
+ comppattern = compile_and_cache(info->pattern, info->protocol);
|
|
|
|
|
+
|
|
|
|
|
+ /* On the first packet of a connection, allocate space for app data */
|
|
|
|
|
+ if(TOTAL_PACKETS == 1 && !skb->cb[0] &&
|
|
|
|
|
+ if(TOTAL_PACKETS == 1 && !skb->cb[0] &&
|
|
|
|
|
+ !master_conntrack->layer7.app_data){
|
|
|
|
|
+ master_conntrack->layer7.app_data =
|
|
|
|
|
+ master_conntrack->layer7.app_data =
|
|
|
|
|
+ kmalloc(maxdatalen, GFP_ATOMIC);
|
|
|
|
|
+ if(!master_conntrack->layer7.app_data){
|
|
|
|
|
+ if (net_ratelimit())
|
|
|
|
@ -562,14 +562,14 @@ |
|
|
|
|
+ DPRINTK("layer7: matched unset: not yet classified "
|
|
|
|
|
+ "(%d/%d packets)\n", TOTAL_PACKETS, num_packets);
|
|
|
|
|
+ /* If the regexp failed to compile, don't bother running it */
|
|
|
|
|
+ } else if(comppattern &&
|
|
|
|
|
+ } 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 =
|
|
|
|
|
+ master_conntrack->layer7.app_proto =
|
|
|
|
|
+ kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);
|
|
|
|
|
+ if(!master_conntrack->layer7.app_proto){
|
|
|
|
|
+ if (net_ratelimit())
|
|
|
|
@ -914,7 +914,7 @@ |
|
|
|
|
+ register int len;
|
|
|
|
|
+ int flags;
|
|
|
|
|
+ struct match_globals g;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /* commented out by ethan
|
|
|
|
|
+ extern char *malloc();
|
|
|
|
|
+ */
|
|
|
|
@ -1041,7 +1041,7 @@ |
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* Make a closing node, and hook it on the end. */
|
|
|
|
|
+ ender = regnode(g, (paren) ? CLOSE+parno : END);
|
|
|
|
|
+ ender = regnode(g, (paren) ? CLOSE+parno : END);
|
|
|
|
|
+ regtail(g, ret, ender);
|
|
|
|
|
+
|
|
|
|
|
+ /* Hook the tails of the branches to the closing node. */
|
|
|
|
@ -1986,7 +1986,7 @@ |
|
|
|
|
+ register char c;
|
|
|
|
|
+ register int no;
|
|
|
|
|
+ register int len;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /* Not necessary and gcc doesn't like it -MLS */
|
|
|
|
|
+ /*extern char *strncpy();*/
|
|
|
|
|
+
|
|
|
|
|