Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / net / ipv4 / netfilter / ip_conntrack_tftp.c
index d132a3c..7e33d3b 100644 (file)
@@ -26,9 +26,9 @@ 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_param_array(ports, int, ports_c, 0400);
+module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "port numbers of tftp servers");
 
 #if 0
@@ -38,15 +38,21 @@ 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, *tfh;
        struct ip_conntrack_expect *exp;
+       unsigned int ret = NF_ACCEPT;
 
-       tfh = skb_header_pointer(skb,
-                                skb->nh.iph->ihl * 4 + sizeof(struct udphdr),
+       tfh = skb_header_pointer(*pskb,
+                                (*pskb)->nh.iph->ihl*4+sizeof(struct udphdr),
                                 sizeof(_tftph), &_tftph);
        if (tfh == NULL)
                return NF_ACCEPT;
@@ -59,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:
@@ -89,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;
 
@@ -102,7 +114,7 @@ static void fini(void)
        } 
 }
 
-static int __init init(void)
+static int __init ip_conntrack_tftp_init(void)
 {
        int i, ret;
        char *tmpname;
@@ -116,11 +128,10 @@ static int __init init(void)
 
                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;
 
@@ -137,14 +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);
                }
        }
        return(0);
 }
 
-PROVIDES_CONNTRACK(tftp);
-
-module_init(init);
-module_exit(fini);
+module_init(ip_conntrack_tftp_init);
+module_exit(ip_conntrack_tftp_fini);