nf_hook_ops 钩子的注册
来源:互联网 发布:python read utf8 编辑:程序博客网 时间:2024/05/12 00:19
nf_hook_ops 钩子的注册
在filter表的初始化函数static int __init init(void)中除了有一个nf_register_hook函数注册一个tables外,还由nf_register_hook函数注册了3个hook
1 nf_hook_ops数据结构 netfilter.h
struct nf_hook_ops
{
struct list_head list; //链表成员
/* User fills in from here down. */
nf_hookfn *hook; //钩子函数指针
struct module *owner;
int pf; //协议簇,对于ipv4而言,是PF_INET
int hooknum; //hook类型
/* Hooks are ordered in ascending priority. */
int priority; //优先级
};
list成员用于维护Netfilter hook的列表。
hook成员是一个指向nf_hookfn类型的函数的指针,该函数是这个hook被调用时执行的函数。nf_hookfn同样在linux/netfilter.h中定义。
pf这个成员用于指定协议族。有效的协议族在linux/socket.h中列出,但对于IPv4我们使用协议族PF_INET。
hooknum这个成员用于指定安装的这个函数对应的具体的hook类型:
NF_IP_PRE_ROUTING 在完整性校验之后,选路确定之前
NF_IP_LOCAL_IN 在选路确定之后,且数据包的目的是本地主机
NF_IP_FORWARD 目的地是其它主机地数据包
NF_IP_LOCAL_OUT 来自本机进程的数据包在其离开本地主机的过程中
NF_IP_POST_ROUTING 在数据包离开本地主机“上线”之前
struct nf_hook_ops只是存储勾子的数据结构,而真正存储这些勾子供协议栈调用的是nf_hooks,从定义可以看出,它其实就是二维数组的链表。
struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; [net\filter\core.c]
其中NFPROTO_NUMPROTO表示勾子关联的协议,NF_MAX_HOOKS表示勾子应用的位置,可选值在每个协议模块内部定义,这些值代表了勾子函数在协议流程中应用的位置。
再看看它的初始化,仍以filter表为例
static struct nf_hook_ops ipt_ops[]
= { { { NULL, NULL }, ipt_hook, PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_FILTER },
{ { NULL, NULL }, ipt_hook, PF_INET, NF_IP_FORWARD, NF_IP_PRI_FILTER },
{ { NULL, NULL }, ipt_local_out_hook, PF_INET, NF_IP_LOCAL_OUT,
NF_IP_PRI_FILTER }
};
2 int nf_register_hook函数 netfilter.c
注册实际上就是在一个nf_hook_ops链表中再插入一个nf_hook_ops结构
int nf_register_hook(struct nf_hook_ops *reg)
{
struct list_head *i;
spin_lock_bh(&nf_hook_lock);
list_for_each(i, &nf_hooks[reg->pf][reg->hooknum]) {
if (reg->priority < ((struct nf_hook_ops *)i)->priority)
break;
}
list_add_rcu(®->list, i->prev);
spin_unlock_bh(&nf_hook_lock);
synchronize_net();
return 0;
}
list_for_each 函数遍历当前待注册的钩子的协议pf及Hook类型所对应的链表,其首地址是&nf_hooks[reg->pf][reg->hooknum],如果当前待注册钩子的优先级小于匹配的的节点的优先级,则找到了待插入的位置,也就是说,按优先级的升序排列。
list_add_rcu把当前节点插入到查到找的适合的位置,这样,完成后,所有pf协议下的hooknum类型的钩子,都被注册到&nf_hooks[reg->pf][reg->hooknum]为首的链表当中了。
内核同时还提供了nf_register_hooks()和nf_unregister_hooks(),将reg重复注册n次或将reg从nf_hooks中注销n次。当勾子函数注册完成后,nf_hooks的结构如图所示:
3ipt_hook钩子函数 iptable_raw.c
注册nf_hook_ops,也就向内核注册了一个钩子函数,这些函数有ipt_hook,ipt_local_hook,ipt_route_hook,ipt_local_out_hook等。
前面在nf_iterate()里调用的钩子函数就是它了
下面是ipt_hook函数的定义:
static unsigned int
ipt_hook(unsigned int hook, /* hook点 */
struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)) /* 默认处理函数 */
{
/* 参数&packet_filter是由注册该nf_hook_ops的表(filter)决定的,也有可能是&packet_raw */
return ipt_do_table(pskb, hook, in, out, &packet_filter, NULL);
}
实际上是直接调用ipt_do_table(ip_tables.c)函数
接下来就是根据table里面的entry来处理数据包了
一个table就是一组防火墙规则的集合
而一个entry就是一条规则,每个entry由一系列的matches和一个target组成
一旦数据包匹配了该某个entry的所有matches,就用target来处理它
Match又分为两部份,一部份为一些基本的元素,如来源/目的地址,进/出网口,协议等,对应了struct ipt_ip,我们常常将其称为标准的match,另一部份match则以插件的形式存在,是动态可选择,也允许第三方开发的,常常称为扩展的match,如字符串匹配,p2p匹配等。同样,规则的target也是可扩展的。这样,一条规则占用的空间,可以分为:struct ipt_ip+n*match+n*target,(n表示了其个数,这里的match指的是可扩展的match部份)
From:http://blog.chinaunix.net/uid-26366978-id-3270944.html
- nf_hook_ops 钩子的注册
- nf_hook_ops 钩子的注册
- nf_hook_ops 钩子的注册
- nf_hook_ops 钩子的注册
- netfilter源码分析(4)-nf_hook_ops 钩子的注册
- netfilter源码分析(4)-nf_hook_ops 钩子的注册
- JVM里注册Spring的关闭钩子
- 消息钩子注册浅析
- 钩子函数于注册
- 【转】消息钩子注册浅析
- 什么是钩子,钩子的原理
- 封装:钩子注册全局组合快捷键
- 钩子1(线程级的钩子)
- [钩子技术]简单的鼠标钩子
- C#什么是钩子,关于钩子的使用
- 系统钩子的应用
- 无钩子的键盘记录
- 无钩子的键盘记录
- animation listerner 在动画开始、重复、结束后设置通知
- 做组合动画
- 怎么配置eclipse的联想功能
- 第十七周项目2:引用作形参
- js返回上一个页面并且刷新页面
- nf_hook_ops 钩子的注册
- 网页中插入FLASH(swf文件)的html代码
- Android 音频的播放之二MediaPlayer
- 第十七周项目6-学生成绩统计(6)
- CentOS 6.X 查看Windows系统的 NTFS 文件 以及安装 SMplayer 观看视频的方法
- app支付--支付宝支付
- 电阻匹配
- 无线通信距离的计算[转载]
- Android Lollipop 设置状态栏颜色