- 论坛徽章:
- 0
|
Netfilter在网络报文在协议栈的处理流程中插入钩子,插入点包括以下五个位置
#define NF_IP_PRE_ROUTING 0
/* If the packet is destined for this box. */
#define NF_IP_LOCAL_IN 1
/* If the packet is destined for another interface. */
#define NF_IP_FORWARD 2
/* Packets coming from a local process. */
#define NF_IP_LOCAL_OUT 3
/* Packets about to hit the wire. */
#define NF_IP_POST_ROUTING 4
对应的函数分别是
- ip_rcv
- ip_local_deliver
- ip_forward
- ip_queue_xmit
- ip_output
比如ip_rcv最后调用NF_HOOK这个宏
return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish);
NF_HOOK会调用nf_hook_slow,遍历注册在nf_hooks上的这个点的钩子函数
verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev,
outdev, &elem, okfn, hook_thresh);
如果所有的钩子函数都返回成功,就会调用okfn函数,这样Netfiler的钩子函数就嵌入到一个包的正常处理过程中了。每个表对应的模块在初始化的时候调用nf_register_hooks注册它需要插入的钩子函数,比如filter表,它会在local in,forward,local out三个点上插入钩子函数
static struct nf_hook_ops ipt_ops[] = {
{
.hook = ipt_hook,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_IP_LOCAL_IN,
.priority = NF_IP_PRI_FILTER,
},
{
.hook = ipt_hook,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_IP_FORWARD,
.priority = NF_IP_PRI_FILTER,
},
{
.hook = ipt_local_out_hook,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_IP_LOCAL_OUT,
.priority = NF_IP_PRI_FILTER,
},
};
同一个点上,不同模块插入的钩子函数是按照一定优先级调用的:
enum nf_ip_hook_priorities {
NF_IP_PRI_FIRST = INT_MIN,
NF_IP_PRI_CONNTRACK_DEFRAG = -400,
NF_IP_PRI_RAW = -300,
NF_IP_PRI_SELINUX_FIRST = -225,
NF_IP_PRI_CONNTRACK = -200,
NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
NF_IP_PRI_MANGLE = -150,
NF_IP_PRI_NAT_DST = -100,
NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
NF_IP_PRI_FILTER = 0,
NF_IP_PRI_NAT_SRC = 100,
NF_IP_PRI_SELINUX_LAST = 225,
NF_IP_PRI_CONNTRACK_HELPER = INT_MAX - 2,
NF_IP_PRI_NAT_SEQ_ADJUST = INT_MAX - 1,
NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
NF_IP_PRI_LAST = INT_MAX,
};
对于
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/90271/showart_2093956.html |
|