内容简介:“tcp丢包分析”系列文章代码来自谢宝友老师,由西邮陈莉君教授研一学生进行解析,本文由戴君毅整理,梁金荣编辑,贺东升校对。最初开发
“tcp丢包分析”系列文章代码来自谢宝友老师,由西邮陈莉君教授研一学生进行解析,本文由戴君毅整理,梁金荣编辑,贺东升校对。
最初开发 /proc
文件系统是为了提供有关系统中进程的信息。但是这个文件系统非常有用, /proc
文件系统包含了一些目录(用作组织信息的方式)和虚拟文件。虚拟文件可以向用户呈现内核中的一些信息,也可以用作一种从用户空间向内核发送信息的手段。
/proc
文件系统可以为用户提供很多信息, 在左边是一系列数字编号,每个实际上都是一个目录,表示系统中的一个进程。由于在 Linux 中创建的第一个进程是 init
进程,因此它的 process-id
为 1。
右边的目录包含特定信息,比如 cpuinfo
包含了CPU的信息, modules
包含了内核模块的信息。
为了解决一些实际问题,我们需要在 /proc
下创建条目捕获信息,使用文件系统通用方法肯定是不行的,需要使用相关API编写内核模块来实现。
在做谢宝友老师写的“TCP丢包分析”实验里,首先就会在 /proc
下创建条目,较为简单,先来看 init
和 exit
:
框架还是比较清晰的,需要深入源码来感受一下,第一部分代码:
struct proc dir entry *pe;
结构 proc_dir_entry
定义在 <fs/proc/internal.h>
下,可以称为一个 pde
,在创建一个文件或目录时就会创建一个 pde
来管理它们。而在打开它们的时候,则会创建一个 proc_inode
结构:
可以使用 PROC_I
宏,也就是我们熟悉的 container_of
,从虚拟文件系统的 inode
得到 proc_inode
,进而得到 pde
。
回到 proc_dir_entry
结构,很多信息从字段名字就可以看出, pde
需要指向创建自己的父 pde
结构, subdir
的组织方式是红黑树,还需要我们实现操作集以及一些引用计数和命名规则等等。
有意思的是,除了操作集之外还有一个 proc_write_t
,对于一些功能比较简单的 proc
文件,我们只要实现这个函数即可,而不用设置 inode_operations
结构,在注册 proc
文件的时候,会自动为 proc_fops
设置一个缺省的 file_operations
结构。
此时,我们可以想象以下模型:
第二部分代码是:
proc_mkdir("mooc", NULL);
proc_mkdir("mooc/net", NULL);
remove proc entry("mooc/net", NULL);
remove proc entry("mooc", NULL);
易知其功能是在 /proc
下创建和删除条目 mooc/net
,以创建操作为例,看下内核代码如何实现的:
这里逻辑很简单, proc_mkdir
实际上是 proc_mkdir_data
默认了权限为 S_IRUGO|S_IXUGO
,再调用 __proc_create
初始化一个局部 pde
,如果成功则初始化操作集,并调用 proc_register
注册这个 pde
到父 pde
下并返回。
__proc_create
调用 kmem_cache_zalloc
从 cache
中获取空间给 pde
,并且对条目名称进行检查。如果成功,则对名称、模式等属性赋值,设置引用计数并初始化锁。
__proc_register
接收两个参数,一个父亲 pde
,一个当前 pde
,目的是把当前 pde
挂到父亲名下,前面提到 subdir
的组织形式是红黑树,那么肯定涉及相关代码,来看:
首先判断当前 pde
的 id
是否越界,如果没有打开子目录锁,把当前 pde
的 parent
字段指向父亲 pde
,并尝试在红黑树中插入子目录,成功后重新上锁并返回当前 pde
。
红黑树的插入操作篇幅所限不再叙述。
下面看第三部分代码:
proc_create
内部也是调用 proc_create_data
,但还需自行指定权限以及操作集回调,用于创建一个 proc
文件,在3.10内核中取代 create_proc_entry
这个旧的接口。
回到实验代码,我们为加入的条目编写操作集接口。
一般地,内核通过在 procfs
文件系统下建立文件来向用户空间提供输出信息,用户空间可以通过任何文本阅读应用查看该文件信息,但是 procfs
有一个缺陷,如果输出内容大于1个内存页,需要多次读,因此处理起来很难,另外,如果输出太大,速度比较慢,有时会出现一些意想不到的情况, AlexanderViro
实现了一套新的功能,使得内核输出大文件信息更容易,它们叫做 seq_file
,所以在使用它们的操作集时需要包含 seq_file.h
头文件。
Drop_packet_open
实际上是调用了 single_open
:
为什么这么做?内核文档给出了相关描述:
https://www.kernel.org/doc/Documentation/filesystems/seq_file.txt
你可能发现,内核文档里显示的是 seq_open
,而实验里是 single_open
,它们有什么区别呢?实际上内核文档的最后给出了答案:
谢宝友老师的实验中运用 seq_file
的极简版本(extra-simple version),只需定义一个 show()
函数。完整的情况我们还需要实现 start()
, next()
等迭代器来对 seq_file
进行操作。极简版本中, open
方法需要调用 single_open
,对应的, release
方法调用 single_release
。
推荐阅读https://www.ibm.com/developerworks/cn/linux/l-proc.html
以上所述就是小编给大家介绍的《“tcp丢包分析”实验解析(一)--proc文件系统》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- “tcp丢包分析”实验解析(三)--驱动接收包过程
- “tcp丢包分析”实验解析(二)--kprobe和tracepoint
- 内网渗透实验:基于Cobaltstrike的一系列实验
- nfs 共享实验
- Arduino呼吸灯实验
- Ansible简介与实验
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。