source: trunk/target/linux/generic-2.6/patches-2.6.25/101-netfilter_layer7_pktmatch.patch @ 13137

Last change on this file since 13137 was 13137, checked in by juhosg, 8 years ago

[kernel] update to 2.6.25.19, and refresh patches

File size: 3.8 KB
  • include/linux/netfilter/xt_layer7.h

    a b struct xt_layer7_info { 
    88    char protocol[MAX_PROTOCOL_LEN]; 
    99    char pattern[MAX_PATTERN_LEN]; 
    1010    u_int8_t invert; 
     11    u_int8_t pkt; 
    1112}; 
    1213 
    1314#endif /* _XT_LAYER7_H */ 
  • net/netfilter/xt_layer7.c

    a b static int match_no_append(struct nf_con 
    297297} 
    298298 
    299299/* add the new app data to the conntrack.  Return number of bytes added. */ 
    300 static int add_data(struct nf_conn * master_conntrack, 
    301                     char * app_data, int appdatalen) 
     300static int add_datastr(char *target, int offset, char *app_data, int len) 
    302301{ 
    303302        int length = 0, i; 
    304         int oldlength = master_conntrack->layer7.app_data_len; 
    305  
    306         /* This is a fix for a race condition by Deti Fliegl. However, I'm not  
    307            clear on whether the race condition exists or whether this really  
    308            fixes it.  I might just be being dense... Anyway, if it's not really  
    309            a fix, all it does is waste a very small amount of time. */ 
    310         if(!master_conntrack->layer7.app_data) return 0; 
     303         
     304        if (!target) return 0; 
    311305 
    312306        /* Strip nulls. Make everything lower case (our regex lib doesn't 
    313307        do case insensitivity).  Add it to the end of the current data. */ 
    314         for(i = 0; i < maxdatalen-oldlength-1 && 
    315                    i < appdatalen; i++) { 
     308        for(i = 0; i < maxdatalen-offset-1 && i < len; i++) { 
    316309                if(app_data[i] != '\0') { 
    317310                        /* the kernel version of tolower mungs 'upper ascii' */ 
    318                         master_conntrack->layer7.app_data[length+oldlength] = 
     311                        target[length+offset] = 
    319312                                isascii(app_data[i])?  
    320313                                        tolower(app_data[i]) : app_data[i]; 
    321314                        length++; 
    322315                } 
    323316        } 
     317        target[length+offset] = '\0'; 
     318         
     319        return length; 
     320} 
    324321 
    325         master_conntrack->layer7.app_data[length+oldlength] = '\0'; 
    326         master_conntrack->layer7.app_data_len = length + oldlength; 
     322/* add the new app data to the conntrack.  Return number of bytes added. */ 
     323static int add_data(struct nf_conn * master_conntrack, 
     324                    char * app_data, int appdatalen) 
     325{ 
     326        int length; 
    327327 
     328        length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen); 
     329        master_conntrack->layer7.app_data_len += length; 
    328330        return length; 
    329331} 
    330332 
    match(const struct sk_buff *skbin, 
    411413        const struct xt_layer7_info * info = matchinfo; 
    412414        enum ip_conntrack_info master_ctinfo, ctinfo; 
    413415        struct nf_conn *master_conntrack, *conntrack; 
    414         unsigned char * app_data; 
     416        unsigned char *app_data, *tmp_data; 
    415417        unsigned int pattern_result, appdatalen; 
    416418        regexp * comppattern; 
    417419 
    match(const struct sk_buff *skbin, 
    439441                master_conntrack = master_ct(master_conntrack); 
    440442 
    441443        /* if we've classified it or seen too many packets */ 
    442         if(TOTAL_PACKETS > num_packets || 
    443            master_conntrack->layer7.app_proto) { 
     444        if(!info->pkt && (TOTAL_PACKETS > num_packets || 
     445           master_conntrack->layer7.app_proto)) { 
    444446 
    445447                pattern_result = match_no_append(conntrack, master_conntrack,  
    446448                                                 ctinfo, master_ctinfo, info); 
    match(const struct sk_buff *skbin, 
    473475        /* the return value gets checked later, when we're ready to use it */ 
    474476        comppattern = compile_and_cache(info->pattern, info->protocol); 
    475477 
     478        if (info->pkt) { 
     479                tmp_data = kmalloc(maxdatalen, GFP_ATOMIC); 
     480                if(!tmp_data){ 
     481                        if (net_ratelimit()) 
     482                                printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); 
     483                        return info->invert; 
     484                } 
     485 
     486                tmp_data[0] = '\0'; 
     487                add_datastr(tmp_data, 0, app_data, appdatalen); 
     488                pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0); 
     489 
     490                kfree(tmp_data); 
     491                tmp_data = NULL; 
     492                spin_unlock_bh(&l7_lock); 
     493 
     494                return (pattern_result ^ info->invert); 
     495        } 
     496 
    476497        /* On the first packet of a connection, allocate space for app data */ 
    477498        if(TOTAL_PACKETS == 1 && !skb->cb[0] &&  
    478499           !master_conntrack->layer7.app_data){ 
Note: See TracBrowser for help on using the repository browser.