falcon_13 发表于 2007-5-12 17:36:13

报错:dereferencing pointer to in

我把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=%d, %d.\n", __FUNCTION__,
          i->mproto, i->ports.mport, i->ports.mport); */

    return ((i->mproto == proto) && (i->ports.mport <= dport)
          && (i->ports.mport >= 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=%d, %d.\n", __FUNCTION__,
          i->rproto, i->ports.rport, i->ports.rport); */
    u_int16_t rproto = i->rproto;

    if (!rproto)
        rproto = proto;

    return ((rproto == proto) && (i->ports.rport <= dport)
          && (i->ports.rport >= 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);

sagaeon 发表于 2007-5-13 10:39:58

查看一下包含list_find的头文件及里面的结构定义

falcon_13 发表于 2007-5-13 15:24:22

里面的结构体应该没有什么问题,因为在2.4下能编译我是把这个文件拿过来的
页: [1]
查看完整版本: 报错:dereferencing pointer to in