netfilter与用户空间通信二法
来源:互联网 发布:unity3d java服务器 编辑:程序博客网 时间:2024/06/04 23:22
http://blog.csdn.net/wangxing1018/article/details/4295536
netfilter与用户空间通信二法
声明:此文章只是 陈鑫在Linux 系统内核空间与用户空间通信的实现与分析 的笔记,结合自己在一些开源项目看到的体会,仅此而已。原理性的东西都在 陈鑫 的文章中有详尽的说明和解释。如果侵犯了作者的权利,请通知我,我会及时删除。
1 先说明一下环境。Linux 内核代码的运行环境有三种:用户上下文环境、硬中断环境和软中断环境。但三种环境的局限性分两种,因为软中断环境只是硬中断环境的延续。
内核态环境介绍局限性用户上下文内核态代码的运行与一用户空间进程相关,如系统调用中代码的运行环境。不可直接将本地变量传递给用户态的内存区,因为内核态和用户态的内存映射机制不同。硬中断和软中断环境硬中断或软中断过程中代码的运行环境,如 IP 数据报的接收代码的运行环境,网络设备的驱动程序等。不可直接向用户态内存区传递数据;代码在运行过程中不可阻塞。
2 传统进程间通信的局限性。 Linux 传统的进程间通信有很多,如各类管道、消息队列、内存共享、信号量等等。但它们都无法介于内核态与用户态使用,原因如表:
通信方法无法介于内核态与用户态的原因管道(不包括命名管道)局限于父子进程间的通信。消息队列在硬、软中断中无法无阻塞地接收数据。信号量无法介于内核态和用户态使用。内存共享需要信号量辅助,而信号量又无法使用。套接字在硬、软中断中无法无阻塞地接收数据。
3 解决办法。Linux内核态与用户态进程通信方法的提出与实现。分为 用户上下文环境、硬中断和软中断环境两种情况。
3.1 用户上下文环境
运行在用户上下文环境中的代码是可以阻塞的,这样,便可以使用消息队列和 UNIX 域套接字来实现内核态与用户态的通信。但这些方法的数据传输效率较低,Linux 内核提供 copy_from_user()/copy_to_user() 函数来实现内核态与用户态数据的拷贝,但这两个函数会引发阻塞,所以不能用在硬、软中断中。一般将这两个特殊拷贝函数用在类似于系统调用一类的函数中,此 类函数在使用中往往"穿梭"于内核态与用户态。
3.2 硬、软中断环境
比起用户上下文环境,硬中断和软中断环境与用户态进程无丝毫关系,而且运行过程不能阻塞。在 Linux 2.4 版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用 netlink 套接字实现的,netlink 套接字的最大特点是对中断过程的支持,同时还使用 netlink 实现了 ip queue 工具,但 ip queue 的使用有其局限性,不能自由地用于各种中断过程。还有重要的一点:netlink 套接字是不用经过TCP/IP协议栈处理的,效率方面没的说。赞。
说 了这么多,都是别人的东西。但是磨刀不误砍柴工,没有前面的知识铺垫,只怕你对怎么样,为什么这样用也是一知半解,这可是工程技术人员的大忌。
4 netfilter与用户空间通信二法
netfilter 的五个钩子在内核TCP/IP协议栈的作用和布局,我就不废话了。 杨沙洲的 Linux Netfilter实现机制和扩展技术 还不错滴。
法1:nf_sockopt_ops通信方式
此法在内核模块中注册nf_register_sockopt一个 nf_sockopt_ops结构体。比如:
- static struct nf_sockopt_ops nso = {
- .pf = PF_INET, // 协议族
- .set_optmin = 常数, // 定义最小set命令字
- .set_optmax = 常数+N, // 定义最大set命令字
- .set = do_nso_set, // 定义set处理函数
- .get_optmin = 常数, // 定义最小get命令字
- .get_optmax = 常数+N, // 定义最大get命令字
- .get = do_nso_get, // 定义set处理函数
- };
其中命令字不能和内核已有的重复,宜大不宜小。命令字很重要,是用来做标识符的。set/get处理函数是直接由用户空间的 set/getsockopt函数调用的。 setsockopt函数向内核写数据,用getsockopt向内核读数据。
从上图可以看到,其实此法的本质,就是使用 copy_from_user()/copy_to_user()完成内核和用户的通信的, 效率其实不高, 多用在传递控制 选项 信息,不适合做大量的数据传输。
法2: netlink 套接字
上图 很清楚的描述了netlink套接字的通信过程。具体细节,大家可以参考上面两篇文章。
总结:
法一: 多用在用户上下文环境,适合做控制选项,传递少量的控制信息。
法二: 多用在 硬、软中断环境,也就是处理 网络数据报的接收等,适合大量处理数据的传输。我用它粗略实现过类似 ethereal的功能,层层吧IP分组剥开。
二者使用环境不一样,使用目的不一样,完全可以在一起发挥更大的作用。
- netfilter与用户空间通信二法
- netfilter与用户空间通信二法
- netfilter与用户空间通信二法
- netfilter与用户空间通信
- netfilter内核态与用户态 通信 之 sockopt
- netfilter内核态与用户态 通信 之 sockopt
- netfilter内核态与用户态 通信 之 sockopt
- linux内核空间与用户空间通信
- linux内核用户通信netfilter
- 用户空间与内核通信-netlink
- linux 内核与用户空间通信
- Linux 内核与用户空间通信
- Linux内核空间与用户空间通信之netlink
- linux用户空间与内核空间的通信技术总结
- netlink 用户空间与内核空间通信实例
- Linux 系统内核空间与用户空间通信…
- Linux 内核空间与用户空间异步通信机制
- 内核空间与用户空间的通信方式
- C# 枚举 Win32_LogicalDisk 类的所有实例,并显示每个实例的 DeviceID 值
- stagefright,OpenMax框架
- 数据结构学习笔记之三(二叉树)
- [算法] poj 3356 字符串的距离 AGTC
- multiple definition of 问题解决方法
- netfilter与用户空间通信二法
- bash 初探与PATH 详解
- 操作系统小结
- golange 错误如下 Resource interpreted as Script but transferred with MIME type text
- Linux环境下PostgreSQL与PostGIS的安装与配置
- 多线程常用语法
- 新手写OFBiz的HelloWorld
- Intellij IDEA 自动生成 serialVersionUID
- Java中static、final用法小结