| 
 | 
 
我把2.4下的一段代码移到2.6下,但是在编译到调用LIST_FIND()的时候报这个错: 
dereferencing pointer to incomplete type 
请问下,是什么问题阿 
 
代码如下: 
#include <linux/types.h> 
#include <linux/ip.h> 
#include <linux/timer.h> 
#include <linux/module.h> 
#include <linux/netfilter.h> 
#include <linux/netdevice.h> 
#include <linux/if.h> 
#include <linux/inetdevice.h> 
#include <net/protocol.h> 
#include <net/checksum.h> 
 
#include <linux/netfilter_ipv4.h> 
#include <linux/netfilter_ipv4/ip_tables.h> 
#include <linux/netfilter_ipv4/ip_conntrack.h> 
#include <linux/netfilter_ipv4/ip_conntrack_core.h> 
#include <linux/netfilter_ipv4/ip_conntrack_tuple.h> 
#include <linux/netfilter_ipv4/ip_autofw.h> 
#include <linux/netfilter_ipv4/lockhelp.h> 
#include <linux/netfilter_ipv4/ip_nat_rule.h> 
#include <linux/netfilter_ipv4/ipt_TRIGGER.h> 
#include <linux/netfilter_ipv4/list_help.h> 
 
/* This rwlock protects the main hash table, protocol/helper/expected 
 *    registrations, conntrack timers*/ 
#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock) 
#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock) 
 
#include <linux/netfilter_ipv4/listhelp.h> 
 
#if 0 
#define DEBUGP printk 
#else 
#define DEBUGP(format, args...) 
#endif 
 
struct ipt_trigger { 
        struct list_head list;                /* Trigger list */ 
        struct timer_list timeout;        /* Timer for list destroying */ 
        u_int32_t srcip;                /* Outgoing source address */ 
        u_int32_t dstip;                /* Outgoing destination address */ 
        u_int16_t mproto;                /* Trigger protocol */ 
        u_int16_t rproto;                /* Related protocol */ 
        struct ipt_trigger_ports ports;        /* Trigger and related ports */ 
        u_int8_t reply;                        /* Confirm a reply connection */ 
}; 
 
LIST_HEAD(trigger_list); 
//DECLARE_LOCK(ip_trigger_lock); 
 
static void trigger_refresh(struct ipt_trigger *trig, unsigned long extra_jiffies) 
{ 
    DEBUGP("%s: \n", __FUNCTION__); 
    IP_NF_ASSERT(trig); 
    WRITE_LOCK(&ip_conntrack_lock); 
 
    /* Need del_timer for race avoidance (may already be dying). */ 
    if (del_timer(&trig->timeout)) { 
        trig->timeout.expires = jiffies + extra_jiffies; 
        add_timer(&trig->timeout); 
    } 
 
    WRITE_UNLOCK(&ip_conntrack_lock); 
} 
 
static void __del_trigger(struct ipt_trigger *trig) 
{ 
    DEBUGP("%s: \n", __FUNCTION__); 
    IP_NF_ASSERT(trig); 
    MUST_BE_WRITE_LOCKED(&ip_conntrack_lock); 
 
     /* delete from 'trigger_list' */ 
    list_del(&trig->list); 
    kfree(trig); 
} 
 
static void trigger_timeout(unsigned long ul_trig) 
{ 
    struct ipt_trigger *trig= (void *) ul_trig; 
 
    DEBUGP("trigger list %p timed out\n", trig); 
    WRITE_LOCK(&ip_conntrack_lock); 
    __del_trigger(trig); 
    WRITE_UNLOCK(&ip_conntrack_lock); 
} 
 
static unsigned int 
add_new_trigger(struct ipt_trigger *trig) 
{ 
    struct ipt_trigger *new; 
 
    DEBUGP("!!!!!!!!!!!! %s !!!!!!!!!!!\n", __FUNCTION__); 
    WRITE_LOCK(&ip_conntrack_lock); 
    new = (struct ipt_trigger *) 
        kmalloc(sizeof(struct ipt_trigger), GFP_ATOMIC); 
 
    if (!new) { 
        WRITE_UNLOCK(&ip_conntrack_lock); 
        DEBUGP("%s: OOM allocating trigger list\n", __FUNCTION__); 
        return -ENOMEM; 
    } 
 
    memset(new, 0, sizeof(*trig)); 
    INIT_LIST_HEAD(&new->list); 
    memcpy(new, trig, sizeof(*trig)); 
 
    /* add to global table of trigger */ 
    list_prepend(&trigger_list, &new->list); 
    /* add and start timer if required */ 
    init_timer(&new->timeout); 
    new->timeout.data = (unsigned long)new; 
    new->timeout.function = trigger_timeout; 
    new->timeout.expires = jiffies + (TRIGGER_TIMEOUT * HZ); 
    add_timer(&new->timeout); 
             
    WRITE_UNLOCK(&ip_conntrack_lock); 
 
    return 0; 
} 
 
static inline int trigger_out_matched(const struct ipt_trigger *i, 
        const u_int16_t proto, const u_int16_t dport) 
{ 
    /* DEBUGP("%s: i=%p, proto= %d, dport=%d.\n", __FUNCTION__, i, proto, dport); 
    DEBUGP("%s: Got one, mproto= %d, mport[0..1]=%d, %d.\n", __FUNCTION__,  
            i->mproto, i->ports.mport[0], i->ports.mport[1]); */ 
 
    return ((i->mproto == proto) && (i->ports.mport[0] <= dport)  
            && (i->ports.mport[1] >= dport)); 
} 
 
static unsigned int 
trigger_out(struct sk_buff **pskb, 
                unsigned int hooknum, 
                const struct net_device *in, 
                const struct net_device *out, 
                const void *targinfo, 
                void *userinfo) 
{ 
    const struct ipt_trigger_info *info = targinfo; 
    struct ipt_trigger trig, *found; 
    const struct iphdr *iph = (*pskb)->nh.iph; 
    struct tcphdr *tcph = (void *)iph + iph->ihl*4;        /* Might be TCP, UDP */ 
 
    DEBUGP("############# %s ############\n", __FUNCTION__); 
    /* Check if the trigger range has already existed in 'trigger_list'. */ 
    found = LIST_FIND(&trigger_list, trigger_out_matched, 
            struct ipt_trigger *, iph->protocol, ntohs(tcph->dest)); 
 
    if (found) { 
        /* Yeah, it exists. We need to update(delay) the destroying timer. */ 
        trigger_refresh(found, TRIGGER_TIMEOUT * HZ); 
        /* In order to allow multiple hosts use the same port range, we update 
           the 'saddr' after previous trigger has a reply connection. */ 
        if (found->reply) 
            found->srcip = iph->saddr; 
    } 
    else { 
        /* Create new trigger */ 
        memset(&trig, 0, sizeof(trig)); 
        trig.srcip = iph->saddr; 
        trig.mproto = iph->protocol; 
        trig.rproto = info->proto; 
        memcpy(&trig.ports, &info->ports, sizeof(struct ipt_trigger_ports)); 
        add_new_trigger(&trig);        /* Add the new 'trig' to list 'trigger_list'. */ 
    } 
 
    return IPT_CONTINUE;        /* We don't block any packet. */ 
} 
 
static inline int trigger_in_matched(const struct ipt_trigger *i, 
        const u_int16_t proto, const u_int16_t dport) 
{ 
    /* DEBUGP("%s: i=%p, proto= %d, dport=%d.\n", __FUNCTION__, i, proto, dport); 
    DEBUGP("%s: Got one, rproto= %d, rport[0..1]=%d, %d.\n", __FUNCTION__,  
            i->rproto, i->ports.rport[0], i->ports.rport[1]); */ 
    u_int16_t rproto = i->rproto; 
 
    if (!rproto) 
        rproto = proto; 
 
    return ((rproto == proto) && (i->ports.rport[0] <= dport)  
            && (i->ports.rport[1] >= dport)); 
} 
 
static unsigned int 
trigger_in(struct sk_buff **pskb, 
                unsigned int hooknum, 
                const struct net_device *in, 
                const struct net_device *out, 
                const void *targinfo, 
                void *userinfo) 
{ 
    struct ipt_trigger *found; 
    const struct iphdr *iph = (*pskb)->nh.iph; 
    struct tcphdr *tcph = (void *)iph + iph->ihl*4;        /* Might be TCP, UDP */ 
 
    /* Check if the trigger-ed range has already existed in 'trigger_list'. */ 
    found = LIST_FIND(&trigger_list, trigger_in_matched, 
            struct ipt_trigger *, iph->protocol, ntohs(tcph->dest)); 
    if (found) { 
        DEBUGP("############# %s ############\n", __FUNCTION__); 
        /* Yeah, it exists. We need to update(delay) the destroying timer. */ 
        trigger_refresh(found, TRIGGER_TIMEOUT * HZ); 
        return NF_ACCEPT;        /* Accept it, or the imcoming packet could be  
                                   dropped in the FORWARD chain */ 
    } 
  
    return IPT_CONTINUE;        /* Our job is the interception. */ 
} 
 
 
static struct ipt_target redirect_reg 
= { { NULL, NULL }, "TRIGGER", trigger_target, trigger_check, NULL, 
    THIS_MODULE }; 
 
static int __init init(void) 
{ 
        return ipt_register_target(&redirect_reg); 
} 
 
static void __exit fini(void) 
{ 
        ipt_unregister_target(&redirect_reg); 
} 
 
module_init(init); 
module_exit(fini); |   
 
 
 
 |