X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fip_conntrack_ftp.c;h=df7008989c3813473bd557019424abb73f0efbf8;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=b9c27d5e458ba49e99d7c7805e41c846d8832957;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index b9c27d5e4..df7008989 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c @@ -19,6 +19,7 @@ #include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Rusty Russell "); @@ -27,16 +28,16 @@ MODULE_DESCRIPTION("ftp connection tracking helper"); /* This is slow, but it's simple. --RR */ static char ftp_buffer[65536]; -DECLARE_LOCK(ip_ftp_lock); +static DECLARE_LOCK(ip_ftp_lock); struct module *ip_conntrack_ftp = THIS_MODULE; #define MAX_PORTS 8 static int ports[MAX_PORTS]; static int ports_c; -MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); +module_param_array(ports, int, ports_c, 0400); static int loose; -MODULE_PARM(loose, "i"); +module_param(loose, int, 0600); #if 0 #define DEBUGP printk @@ -247,7 +248,8 @@ static int help(struct sk_buff *skb, enum ip_conntrack_info ctinfo) { unsigned int dataoff, datalen; - struct tcphdr tcph; + struct tcphdr _tcph, *th; + char *fb_ptr; u_int32_t old_seq_aft_nl; int old_seq_aft_nl_set, ret; u_int32_t array[6] = { 0 }; @@ -267,10 +269,12 @@ static int help(struct sk_buff *skb, return NF_ACCEPT; } - if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) != 0) + th = skb_header_pointer(skb, skb->nh.iph->ihl*4, + sizeof(_tcph), &_tcph); + if (th == NULL) return NF_ACCEPT; - dataoff = skb->nh.iph->ihl*4 + tcph.doff*4; + dataoff = skb->nh.iph->ihl*4 + th->doff*4; /* No data? */ if (dataoff >= skb->len) { DEBUGP("ftp: skblen = %u\n", skb->len); @@ -279,26 +283,28 @@ static int help(struct sk_buff *skb, datalen = skb->len - dataoff; LOCK_BH(&ip_ftp_lock); - skb_copy_bits(skb, dataoff, ftp_buffer, skb->len - dataoff); + fb_ptr = skb_header_pointer(skb, dataoff, + skb->len - dataoff, ftp_buffer); + BUG_ON(fb_ptr == NULL); old_seq_aft_nl_set = ct_ftp_info->seq_aft_nl_set[dir]; old_seq_aft_nl = ct_ftp_info->seq_aft_nl[dir]; DEBUGP("conntrack_ftp: datalen %u\n", datalen); - if (ftp_buffer[datalen - 1] == '\n') { + if (fb_ptr[datalen - 1] == '\n') { DEBUGP("conntrack_ftp: datalen %u ends in \\n\n", datalen); if (!old_seq_aft_nl_set - || after(ntohl(tcph.seq) + datalen, old_seq_aft_nl)) { + || after(ntohl(th->seq) + datalen, old_seq_aft_nl)) { DEBUGP("conntrack_ftp: updating nl to %u\n", - ntohl(tcph.seq) + datalen); + ntohl(th->seq) + datalen); ct_ftp_info->seq_aft_nl[dir] = - ntohl(tcph.seq) + datalen; + ntohl(th->seq) + datalen; ct_ftp_info->seq_aft_nl_set[dir] = 1; } } if(!old_seq_aft_nl_set || - (ntohl(tcph.seq) != old_seq_aft_nl)) { + (ntohl(th->seq) != old_seq_aft_nl)) { DEBUGP("ip_conntrack_ftp_help: wrong seq pos %s(%u)\n", old_seq_aft_nl_set ? "":"(UNSET) ", old_seq_aft_nl); ret = NF_ACCEPT; @@ -315,7 +321,7 @@ static int help(struct sk_buff *skb, for (i = 0; i < ARRAY_SIZE(search); i++) { if (search[i].dir != dir) continue; - found = find_pattern(ftp_buffer, skb->len - dataoff, + found = find_pattern(fb_ptr, skb->len - dataoff, search[i].pattern, search[i].plen, search[i].skip, @@ -333,7 +339,7 @@ static int help(struct sk_buff *skb, if (net_ratelimit()) printk("conntrack_ftp: partial %s %u+%u\n", search[i].pattern, - ntohl(tcph.seq), datalen); + ntohl(th->seq), datalen); ret = NF_DROP; goto out; } else if (found == 0) { /* No match */ @@ -343,7 +349,7 @@ static int help(struct sk_buff *skb, DEBUGP("conntrack_ftp: match `%.*s' (%u bytes at %u)\n", (int)matchlen, data + matchoff, - matchlen, ntohl(tcph.seq) + matchoff); + matchlen, ntohl(th->seq) + matchoff); /* Allocate expectation which will be inserted */ exp = ip_conntrack_expect_alloc(); @@ -357,7 +363,7 @@ static int help(struct sk_buff *skb, /* Update the ftp info */ if (htonl((array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3]) == ct->tuplehash[dir].tuple.src.ip) { - exp->seq = ntohl(tcph.seq) + matchoff; + exp->seq = ntohl(th->seq) + matchoff; exp_ftp_info->len = matchlen; exp_ftp_info->ftptype = search[i].ftptype; exp_ftp_info->port = array[4] << 8 | array[5]; @@ -420,10 +426,10 @@ static int __init init(void) int i, ret; char *tmpname; - if (ports[0] == 0) - ports[0] = FTP_PORT; + if (ports_c == 0) + ports[ports_c++] = FTP_PORT; - for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { + for (i = 0; i < ports_c; i++) { ftp[i].tuple.src.u.tcp.port = htons(ports[i]); ftp[i].tuple.dst.protonum = IPPROTO_TCP; ftp[i].mask.src.u.tcp.port = 0xFFFF; @@ -449,13 +455,11 @@ static int __init init(void) fini(); return ret; } - ports_c++; } return 0; } PROVIDES_CONNTRACK(ftp); -EXPORT_SYMBOL(ip_ftp_lock); module_init(init); module_exit(fini);