- 论坛徽章:
- 46
|
直接贴代码了
ipt_do_table(struct sk_buff **pskb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
struct ipt_table *table)
{
.....
do {
IP_NF_ASSERT(e);
IP_NF_ASSERT(back);
if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) {
struct ipt_entry_target *t;
if (IPT_MATCH_ITERATE(e, do_match,
*pskb, in, out,
offset, &hotdrop) != 0)
goto no_match;
ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
t = ipt_get_target(e);
IP_NF_ASSERT(t->u.kernel.target);
/* Standard target? */
if (!t->u.kernel.target->target) {
int v;
v = ((struct ipt_standard_target *)t)->verdict;
if (v < 0) {
/* Pop from stack? */
if (v != IPT_RETURN) {
verdict = (unsigned)(-v) - 1;
break;
}
e = back;
back = get_entry(table_base,
back->comefrom);
continue;
}
if (table_base + v != (void *)e + e->next_offset
&& !(e->ip.flags & IPT_F_GOTO)) {
/* Save old back ptr in next entry */
struct ipt_entry *next
= (void *)e + e->next_offset;
next->comefrom
= (void *)back - table_base;
/* set back pointer to next entry */
back = next;
}
e = get_entry(table_base, v);
} else {
/* Targets which reenter must return
abs. verdicts */
#ifdef CONFIG_NETFILTER_DEBUG
((struct ipt_entry *)table_base)->comefrom
= 0xeeeeeeec;
#endif
verdict = t->u.kernel.target->target(pskb,
in, out,
hook,
t->u.kernel.target,
t->data);
#ifdef CONFIG_NETFILTER_DEBUG
if (((struct ipt_entry *)table_base)->comefrom
!= 0xeeeeeeec
&& verdict == IPT_CONTINUE) {
printk("Target %s reentered!\n",
t->u.kernel.target->name);
verdict = NF_DROP;
}
((struct ipt_entry *)table_base)->comefrom
= 0x57acc001;
#endif
/* Target might have changed stuff. */
ip = (*pskb)->nh.iph;
datalen = (*pskb)->len - ip->ihl * 4;
if (verdict == IPT_CONTINUE)
e = (void *)e + e->next_offset;
else
/* Verdict */
break;
}
} else {
no_match:
e = (void *)e + e->next_offset;
}
} while (!hotdrop);/*这是循环退出的条件,假如我这里的rule只有一条标准匹配的话,并且没有第二条rule*/
}
多谢各位少侠
|
|