1、如图所示,netfilter在内核处理数据包的五个关键点(PRE_ROUTING, IN, FORWARD, OUT, POST_ROUTING)都设置了钩子点
2、每个表在相应的钩子点注册了钩子函数,在nf_hooks[][]这个全局二维数组中数组中每个元素都是一个list_head链表节点,如果在该点没有表去主注册钩子函数,则该链表节点指向自身,
如果有表在这个钩子点注册了钩子函数则用list_head将这些list_head结构连接起来,连接起来的每一个list_head节点嵌入在一个nf_hook_ops结构当中,可以通过list_head节点得到相应
的nf_hook_ops结构。nf_hook_ops结构如下:
struct nf_hook_ops {
下面就是存放在nf_hooks[][]中的list_head
struct list_head list;
具体的钩子函数,如果是filter表的话就是iptable_filter_hook()
nf_hookfn *hook;
struct module *owner;
应用的协议
u_int8_t pf;
对应的钩子点
unsigned int hooknum;
/* Hooks are ordered in ascending priority. */
对应的优先级,如mangle表的hook的优先级要高于filter表hook的优先级,根据该优先级将list_head节点插入到正确的位置,是的链表中钩子函数的优先级是从高到低
int priority;
};
3、在每个关键的钩子点切入netfilter的流程如下:
NF_HOOK( )-->......nf_hook_slow( )-->nf_iterate( )-->判断在全局的二维数组nf_hooks[ ][ ]中是否注册了有钩子函数。
下面是filter表在FORWARD这个链上的执行流程:
内核在数据包处理时到达FORWARD 这个关键的钩子点,首先调用NF_HOOK().....->nf_iterate(),判断在nf_hook[ipv4][FORWARD]是否注册了钩子函数,判断出结果是注册了
然后在根据链表中的list_head结构得到对应的nf_hook_ops结构, 调用该结构中的函数指针 nf_hookfn *hook 来处理数据包,对应filter表的话就应该是调用iptable_filter_hook( hook,...table)
阅读(2421) | 评论(0) | 转发(0) |