X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fip_conntrack_tftp.c;h=7e33d3bed5e3831e8b0a57ed06de304e3144b707;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=ddee7378209d324257d01e8611c076136b06de69;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c index ddee73782..7e33d3bed 100644 --- a/net/ipv4/netfilter/ip_conntrack_tftp.c +++ b/net/ipv4/netfilter/ip_conntrack_tftp.c @@ -19,15 +19,16 @@ #include #include #include +#include MODULE_AUTHOR("Magnus Boden "); MODULE_DESCRIPTION("tftp connection tracking helper"); MODULE_LICENSE("GPL"); #define MAX_PORTS 8 -static int ports[MAX_PORTS]; +static unsigned short ports[MAX_PORTS]; static int ports_c; -MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); +module_param_array(ports, ushort, &ports_c, 0400); MODULE_PARM_DESC(ports, "port numbers of tftp servers"); #if 0 @@ -37,18 +38,26 @@ MODULE_PARM_DESC(ports, "port numbers of tftp servers"); #define DEBUGP(format, args...) #endif -static int tftp_help(struct sk_buff *skb, +unsigned int (*ip_nat_tftp_hook)(struct sk_buff **pskb, + enum ip_conntrack_info ctinfo, + struct ip_conntrack_expect *exp); +EXPORT_SYMBOL_GPL(ip_nat_tftp_hook); + +static int tftp_help(struct sk_buff **pskb, struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) { - struct tftphdr tftph; + struct tftphdr _tftph, *tfh; struct ip_conntrack_expect *exp; + unsigned int ret = NF_ACCEPT; - if (skb_copy_bits(skb, skb->nh.iph->ihl * 4 + sizeof(struct udphdr), - &tftph, sizeof(tftph)) != 0) + tfh = skb_header_pointer(*pskb, + (*pskb)->nh.iph->ihl*4+sizeof(struct udphdr), + sizeof(_tftph), &_tftph); + if (tfh == NULL) return NF_ACCEPT; - switch (ntohs(tftph.opcode)) { + switch (ntohs(tfh->opcode)) { /* RRQ and WRQ works the same way */ case TFTP_OPCODE_READ: case TFTP_OPCODE_WRITE: @@ -56,21 +65,27 @@ static int tftp_help(struct sk_buff *skb, DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); - exp = ip_conntrack_expect_alloc(); + exp = ip_conntrack_expect_alloc(ct); if (exp == NULL) - return NF_ACCEPT; + return NF_DROP; exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; exp->mask.src.ip = 0xffffffff; + exp->mask.src.u.udp.port = 0; exp->mask.dst.ip = 0xffffffff; exp->mask.dst.u.udp.port = 0xffff; - exp->mask.dst.protonum = 0xffff; + exp->mask.dst.protonum = 0xff; exp->expectfn = NULL; + exp->flags = 0; DEBUGP("expect: "); DUMP_TUPLE(&exp->tuple); DUMP_TUPLE(&exp->mask); - ip_conntrack_expect_related(exp, ct); + if (ip_nat_tftp_hook) + ret = ip_nat_tftp_hook(pskb, ctinfo, exp); + else if (ip_conntrack_expect_related(exp) != 0) + ret = NF_DROP; + ip_conntrack_expect_put(exp); break; case TFTP_OPCODE_DATA: case TFTP_OPCODE_ACK: @@ -86,9 +101,9 @@ static int tftp_help(struct sk_buff *skb, } static struct ip_conntrack_helper tftp[MAX_PORTS]; -static char tftp_names[MAX_PORTS][10]; +static char tftp_names[MAX_PORTS][sizeof("tftp-65535")]; -static void fini(void) +static void ip_conntrack_tftp_fini(void) { int i; @@ -99,25 +114,24 @@ static void fini(void) } } -static int __init init(void) +static int __init ip_conntrack_tftp_init(void) { int i, ret; char *tmpname; - if (!ports[0]) - ports[0]=TFTP_PORT; + if (ports_c == 0) + ports[ports_c++] = TFTP_PORT; - for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { + for (i = 0; i < ports_c; i++) { /* Create helper structure */ memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper)); tftp[i].tuple.dst.protonum = IPPROTO_UDP; tftp[i].tuple.src.u.udp.port = htons(ports[i]); - tftp[i].mask.dst.protonum = 0xFFFF; + tftp[i].mask.dst.protonum = 0xFF; tftp[i].mask.src.u.udp.port = 0xFFFF; tftp[i].max_expected = 1; - tftp[i].timeout = 0; - tftp[i].flags = IP_CT_HELPER_F_REUSE_EXPECT; + tftp[i].timeout = 5 * 60; /* 5 minutes */ tftp[i].me = THIS_MODULE; tftp[i].help = tftp_help; @@ -134,15 +148,12 @@ static int __init init(void) if (ret) { printk("ERROR registering helper for port %d\n", ports[i]); - fini(); + ip_conntrack_tftp_fini(); return(ret); } - ports_c++; } return(0); } -PROVIDES_CONNTRACK(tftp); - -module_init(init); -module_exit(fini); +module_init(ip_conntrack_tftp_init); +module_exit(ip_conntrack_tftp_fini);