|
我把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); |
|