fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / net / ipv4 / netfilter / ip_conntrack_irc.c
index 33cc734..91832ec 100644 (file)
  *
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/netfilter.h>
 #include <linux/ip.h>
 #include <net/checksum.h>
 #include <net/tcp.h>
 
-#include <linux/netfilter_ipv4/lockhelp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
 #include <linux/netfilter_ipv4/ip_conntrack_irc.h>
 #include <linux/moduleparam.h>
 
 #define MAX_PORTS 8
-static int ports[MAX_PORTS];
+static unsigned short ports[MAX_PORTS];
 static int ports_c;
-static int max_dcc_channels = 8;
+static unsigned int max_dcc_channels = 8;
 static unsigned int dcc_timeout = 300;
 /* This is slow, but it's simple. --RR */
-static char irc_buffer[65536];
-static DECLARE_LOCK(irc_buffer_lock);
+static char *irc_buffer;
+static DEFINE_SPINLOCK(irc_buffer_lock);
 
 unsigned int (*ip_nat_irc_hook)(struct sk_buff **pskb,
                                enum ip_conntrack_info ctinfo,
@@ -53,14 +51,14 @@ EXPORT_SYMBOL_GPL(ip_nat_irc_hook);
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
 MODULE_LICENSE("GPL");
-module_param_array(ports, int, &ports_c, 0400);
+module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "port numbers of IRC servers");
-module_param(max_dcc_channels, int, 0400);
+module_param(max_dcc_channels, uint, 0400);
 MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session");
-module_param(dcc_timeout, int, 0400);
+module_param(dcc_timeout, uint, 0400);
 MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
 
-static char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
+static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
 #define MINMATCHLEN    5
 
 #if 0
@@ -116,6 +114,7 @@ static int help(struct sk_buff **pskb,
        u_int16_t dcc_port;
        int i, ret = NF_ACCEPT;
        char *addr_beg_p, *addr_end_p;
+       typeof(ip_nat_irc_hook) ip_nat_irc;
 
        DEBUGP("entered\n");
 
@@ -141,7 +140,7 @@ static int help(struct sk_buff **pskb,
        if (dataoff >= (*pskb)->len)
                return NF_ACCEPT;
 
-       LOCK_BH(&irc_buffer_lock);
+       spin_lock_bh(&irc_buffer_lock);
        ib_ptr = skb_header_pointer(*pskb, dataoff,
                                    (*pskb)->len - dataoff, irc_buffer);
        BUG_ON(ib_ptr == NULL);
@@ -198,7 +197,7 @@ static int help(struct sk_buff **pskb,
                                continue;
                        }
 
-                       exp = ip_conntrack_expect_alloc();
+                       exp = ip_conntrack_expect_alloc(ct);
                        if (exp == NULL) {
                                ret = NF_DROP;
                                goto out;
@@ -220,33 +219,34 @@ static int help(struct sk_buff **pskb,
                                    IPPROTO_TCP }});
                        exp->mask = ((struct ip_conntrack_tuple)
                                { { 0, { 0 } },
-                                 { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
+                                 { htonl(0xFFFFFFFF),
+                                       { .tcp = { htons(0xFFFF) } }, 0xFF }});
                        exp->expectfn = NULL;
-                       exp->master = ct;
-                       if (ip_nat_irc_hook)
-                               ret = ip_nat_irc_hook(pskb, ctinfo, 
-                                                     addr_beg_p - ib_ptr,
-                                                     addr_end_p - addr_beg_p,
-                                                     exp);
-                       else if (ip_conntrack_expect_related(exp) != 0) {
-                               ip_conntrack_expect_free(exp);
+                       exp->flags = 0;
+                       ip_nat_irc = rcu_dereference(ip_nat_irc_hook);
+                       if (ip_nat_irc)
+                               ret = ip_nat_irc(pskb, ctinfo,
+                                                addr_beg_p - ib_ptr,
+                                                addr_end_p - addr_beg_p,
+                                                exp);
+                       else if (ip_conntrack_expect_related(exp) != 0)
                                ret = NF_DROP;
-                       }
+                       ip_conntrack_expect_put(exp);
                        goto out;
                } /* for .. NUM_DCCPROTO */
        } /* while data < ... */
 
  out:
-       UNLOCK_BH(&irc_buffer_lock);
+       spin_unlock_bh(&irc_buffer_lock);
        return ret;
 }
 
 static struct ip_conntrack_helper irc_helpers[MAX_PORTS];
-static char irc_names[MAX_PORTS][10];
+static char irc_names[MAX_PORTS][sizeof("irc-65535")];
 
-static void fini(void);
+static void ip_conntrack_irc_fini(void);
 
-static int __init init(void)
+static int __init ip_conntrack_irc_init(void)
 {
        int i, ret;
        struct ip_conntrack_helper *hlpr;
@@ -256,10 +256,10 @@ static int __init init(void)
                printk("ip_conntrack_irc: max_dcc_channels must be a positive integer\n");
                return -EBUSY;
        }
-       if (dcc_timeout < 0) {
-               printk("ip_conntrack_irc: dcc_timeout must be a positive integer\n");
-               return -EBUSY;
-       }
+
+       irc_buffer = kmalloc(65536, GFP_KERNEL);
+       if (!irc_buffer)
+               return -ENOMEM;
        
        /* If no port given, default to standard irc port */
        if (ports_c == 0)
@@ -269,7 +269,7 @@ static int __init init(void)
                hlpr = &irc_helpers[i];
                hlpr->tuple.src.u.tcp.port = htons(ports[i]);
                hlpr->tuple.dst.protonum = IPPROTO_TCP;
-               hlpr->mask.src.u.tcp.port = 0xFFFF;
+               hlpr->mask.src.u.tcp.port = htons(0xFFFF);
                hlpr->mask.dst.protonum = 0xFF;
                hlpr->max_expected = max_dcc_channels;
                hlpr->timeout = dcc_timeout;
@@ -290,7 +290,7 @@ static int __init init(void)
                if (ret) {
                        printk("ip_conntrack_irc: ERROR registering port %d\n",
                                ports[i]);
-                       fini();
+                       ip_conntrack_irc_fini();
                        return -EBUSY;
                }
        }
@@ -299,7 +299,7 @@ static int __init init(void)
 
 /* This function is intentionally _NOT_ defined as __exit, because 
  * it is needed by the init function */
-static void fini(void)
+static void ip_conntrack_irc_fini(void)
 {
        int i;
        for (i = 0; i < ports_c; i++) {
@@ -307,7 +307,8 @@ static void fini(void)
                       ports[i]);
                ip_conntrack_helper_unregister(&irc_helpers[i]);
        }
+       kfree(irc_buffer);
 }
 
-module_init(init);
-module_exit(fini);
+module_init(ip_conntrack_irc_init);
+module_exit(ip_conntrack_irc_fini);