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 / ipt_recent.c
index 2d44b07..b847ee4 100644 (file)
 #define HASH_LOG 9
 
 /* Defaults, these can be overridden on the module command-line. */
-static int ip_list_tot = 100;
-static int ip_pkt_list_tot = 20;
-static int ip_list_hash_size = 0;
-static int ip_list_perms = 0644;
+static unsigned int ip_list_tot = 100;
+static unsigned int ip_pkt_list_tot = 20;
+static unsigned int ip_list_hash_size = 0;
+static unsigned int ip_list_perms = 0644;
 #ifdef DEBUG
 static int debug = 1;
 #endif
@@ -38,13 +38,13 @@ KERN_INFO RECENT_NAME " " RECENT_VER ": Stephen Frost <sfrost@snowman.net>.  htt
 MODULE_AUTHOR("Stephen Frost <sfrost@snowman.net>");
 MODULE_DESCRIPTION("IP tables recently seen matching module " RECENT_VER);
 MODULE_LICENSE("GPL");
-module_param(ip_list_tot, int, 0400);
-module_param(ip_pkt_list_tot, int, 0400);
-module_param(ip_list_hash_size, int, 0400);
-module_param(ip_list_perms, int, 0400);
+module_param(ip_list_tot, uint, 0400);
+module_param(ip_pkt_list_tot, uint, 0400);
+module_param(ip_list_hash_size, uint, 0400);
+module_param(ip_list_perms, uint, 0400);
 #ifdef DEBUG
-module_param(debug, int, 0600);
-MODULE_PARM_DESC(debug,"debugging level, defaults to 1");
+module_param(debug, bool, 0600);
+MODULE_PARM_DESC(debug,"enable debugging output");
 #endif
 MODULE_PARM_DESC(ip_list_tot,"number of IPs to remember per list");
 MODULE_PARM_DESC(ip_pkt_list_tot,"number of packets per IP to remember");
@@ -102,8 +102,10 @@ static int
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
+      const struct xt_match *match,
       const void *matchinfo,
       int offset,
+      unsigned int protoff,
       int *hotdrop);
 
 /* Function to hash a given address into the hash table of table_size size */
@@ -317,7 +319,7 @@ static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned
        skb->nh.iph->daddr = 0;
        /* Clear ttl since we have no way of knowing it */
        skb->nh.iph->ttl = 0;
-       match(skb,NULL,NULL,info,0,NULL);
+       match(skb,NULL,NULL,NULL,info,0,0,NULL);
 
        kfree(skb->nh.iph);
 out_free_skb:
@@ -355,8 +357,10 @@ static int
 match(const struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
+      const struct xt_match *match,
       const void *matchinfo,
       int offset,
+      unsigned int protoff,
       int *hotdrop)
 {
        int pkt_count, hits_found, ans;
@@ -532,6 +536,7 @@ match(const struct sk_buff *skb,
                        }
                        if(info->seconds && info->hit_count) {
                                for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) {
+                                       if(r_list[location].last_pkts[pkt_count] == 0) break;
                                        if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++;
                                }
                                if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert;
@@ -653,7 +658,8 @@ match(const struct sk_buff *skb,
  */
 static int
 checkentry(const char *tablename,
-           const struct ipt_ip *ip,
+           const void *ip,
+          const struct xt_match *match,
            void *matchinfo,
            unsigned int matchsize,
            unsigned int hook_mask)
@@ -667,8 +673,6 @@ checkentry(const char *tablename,
        if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() entered.\n");
 #endif
 
-       if (matchsize != IPT_ALIGN(sizeof(struct ipt_recent_info))) return 0;
-
        /* seconds and hit_count only valid for CHECK/UPDATE */
        if(info->check_set & IPT_RECENT_SET) { flag++; if(info->seconds || info->hit_count) return 0; }
        if(info->check_set & IPT_RECENT_REMOVE) { flag++; if(info->seconds || info->hit_count) return 0; }
@@ -817,6 +821,7 @@ checkentry(const char *tablename,
        /* Create our proc 'status' entry. */
        curr_table->status_proc = create_proc_entry(curr_table->name, ip_list_perms, proc_net_ipt_recent);
        if (!curr_table->status_proc) {
+               vfree(hold);
                printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for /proc entry.\n");
                /* Destroy the created table */
                spin_lock_bh(&recent_lock);
@@ -841,7 +846,6 @@ checkentry(const char *tablename,
                spin_unlock_bh(&recent_lock);
                vfree(curr_table->time_info);
                vfree(curr_table->hash_table);
-               vfree(hold);
                vfree(curr_table->table);
                vfree(curr_table);
                return 0;
@@ -868,7 +872,7 @@ checkentry(const char *tablename,
  * up its memory.
  */
 static void
-destroy(void *matchinfo, unsigned int matchsize)
+destroy(const struct xt_match *match, void *matchinfo, unsigned int matchsize)
 {
        const struct ipt_recent_info *info = matchinfo;
        struct recent_ip_tables *curr_table, *last_table;
@@ -948,16 +952,17 @@ destroy(void *matchinfo, unsigned int matchsize)
 /* This is the structure we pass to ipt_register to register our
  * module with iptables.
  */
-static struct ipt_match recent_match = { 
-  .name = "recent", 
-  .match = &match, 
-  .checkentry = &checkentry, 
-  .destroy = &destroy, 
-  .me = THIS_MODULE
+static struct ipt_match recent_match = {
+       .name           = "recent",
+       .match          = match,
+       .matchsize      = sizeof(struct ipt_recent_info),
+       .checkentry     = checkentry,
+       .destroy        = destroy,
+       .me             = THIS_MODULE
 };
 
 /* Kernel module initialization. */
-static int __init init(void)
+static int __init ipt_recent_init(void)
 {
        int err, count;
 
@@ -990,7 +995,7 @@ static int __init init(void)
 }
 
 /* Kernel module destruction. */
-static void __exit fini(void)
+static void __exit ipt_recent_fini(void)
 {
        ipt_unregister_match(&recent_match);
 
@@ -998,5 +1003,5 @@ static void __exit fini(void)
 }
 
 /* Register our module with the kernel. */
-module_init(init);
-module_exit(fini);
+module_init(ipt_recent_init);
+module_exit(ipt_recent_fini);