vserver 1.9.3
[linux-2.6.git] / net / ipv4 / netfilter / ip_nat_tftp.c
index a2097bf..cacaab6 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/netfilter_ipv4/ip_conntrack_tftp.h>
 #include <linux/netfilter_ipv4/ip_nat_helper.h>
 #include <linux/netfilter_ipv4/ip_nat_rule.h>
+#include <linux/moduleparam.h>
 
 MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
 MODULE_DESCRIPTION("tftp NAT helper");
@@ -41,7 +42,7 @@ MODULE_LICENSE("GPL");
 
 static int ports[MAX_PORTS];
 static int ports_c = 0;
-MODULE_PARM(ports,"1-" __MODULE_STRING(MAX_PORTS) "i");
+module_param_array(ports, int, ports_c, 0400);
 MODULE_PARM_DESC(ports, "port numbers of tftp servers");
 
 #if 0
@@ -59,7 +60,7 @@ tftp_nat_help(struct ip_conntrack *ct,
              struct sk_buff **pskb)
 {
        int dir = CTINFO2DIR(ctinfo);
-       struct tftphdr tftph;
+       struct tftphdr _tftph, *tfh;
        struct ip_conntrack_tuple repl;
 
        if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL)
@@ -71,11 +72,13 @@ tftp_nat_help(struct ip_conntrack *ct,
                return NF_ACCEPT;
        }
 
-       if (skb_copy_bits(*pskb, (*pskb)->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_DROP;
 
-       switch (ntohs(tftph.opcode)) {
+       switch (ntohs(tfh->opcode)) {
        /* RRQ and WRQ works the same way */
        case TFTP_OPCODE_READ:
        case TFTP_OPCODE_WRITE:
@@ -108,9 +111,12 @@ tftp_nat_expected(struct sk_buff **pskb,
 #if 0
        const struct ip_conntrack_tuple *repl =
                        &master->tuplehash[IP_CT_DIR_REPLY].tuple;
-       struct udphdr udph;
+       struct udphdr _udph, *uh;
 
-       if (skb_copy_bits(*pskb,(*pskb)->nh.iph->ihl*4,&udph,sizeof(udph))!=0)
+       uh = skb_header_pointer(*pskb,
+                               (*pskb)->nh.iph->ihl*4,
+                               sizeof(_udph), &_udph);
+       if (uh == NULL)
                return NF_DROP;
 #endif
 
@@ -125,8 +131,8 @@ tftp_nat_expected(struct sk_buff **pskb,
                mr.range[0].min_ip = mr.range[0].max_ip = orig->dst.ip; 
                DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u "
                        "newsrc: %u.%u.%u.%u\n",
-                        NIPQUAD((*pskb)->nh.iph->saddr), ntohs(udph.source),
-                       NIPQUAD((*pskb)->nh.iph->daddr), ntohs(udph.dest),
+                        NIPQUAD((*pskb)->nh.iph->saddr), ntohs(uh->source),
+                       NIPQUAD((*pskb)->nh.iph->daddr), ntohs(uh->dest),
                        NIPQUAD(orig->dst.ip));
        } else {
                mr.range[0].min_ip = mr.range[0].max_ip = orig->src.ip;
@@ -136,8 +142,8 @@ tftp_nat_expected(struct sk_buff **pskb,
 
                DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u "
                        "newdst: %u.%u.%u.%u:%u\n",
-                        NIPQUAD((*pskb)->nh.iph->saddr), ntohs(udph.source),
-                        NIPQUAD((*pskb)->nh.iph->daddr), ntohs(udph.dest),
+                        NIPQUAD((*pskb)->nh.iph->saddr), ntohs(uh->source),
+                        NIPQUAD((*pskb)->nh.iph->daddr), ntohs(uh->dest),
                         NIPQUAD(orig->src.ip), ntohs(orig->src.u.udp.port));
        }
 
@@ -162,10 +168,10 @@ static int __init init(void)
        int i, ret = 0;
        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++) {
                memset(&tftp[i], 0, sizeof(struct ip_nat_helper));
 
                tftp[i].tuple.dst.protonum = IPPROTO_UDP;
@@ -194,7 +200,6 @@ static int __init init(void)
                        fini();
                        return ret;
                }
-               ports_c++;
        }
        return ret;
 }