|
OpenBSD可加载内核模块编程完全指南(15) [e4gle@openbsd29]# gcc -D_KERNEL -I/sys -c null_vfsops.c [e4gle@openbsd29]# gcc -D_KERNEL -I/sys -c null_vnops.c [e4gle@openbsd29]# gcc -D_KERNEL -I/sys -c nullmod.c [e4gle@openbsd29]# ld -r -o nullfs.o null_vfsops.o null_vnops.o null_subr.o nullmod.o [e4gle@openbsd29]# modload -o nullfsmod -enullfsmod nullfs.o [e4gle@openbsd29]# modstat Type Id Off Loadaddr Size Info Rev Module Name VFS 0 -1 e0b84000 0003 e0b860d0 2 nullfs [e4gle@openbsd29]#
ok,虚拟文件系统模块就说到这.
★其他类型的模块
这些模块被用来执行一些预定的模块类型所没有定义的操作.在我这个例子中我们将为网络协议栈里加入控制代码,然后打印出我们接收到的
tcp包的一些信息.
当我们在书写其他类型的模块时,我们必须要完整的检查一遍,确定没有预定的操作.例如,同样的操作模块不能被加载两次.这等于我们在往内
核中去写入模块.当然, 我们都会在模块加载和卸载的控制函数里去控制.
一个其他类型的模块结构象下面这样定义:
struct lkm_misc { MODTYPE lkm_type; int lkm_ver; char *lkm_name; u_long lkm_offset; };
同样,我们首先有一个模块的类型(在这个例子中试LM_MISC),然后是lkm的版本,再接着是模块名和offset的值.在我的这个例子中offset值
没有用到,但在/usr/share/lkm/misc 提供的例子中(增加一个系统调用)offset被用来在系统调用表里面标记一个新的系统调用的位置. 用MOD_MISC宏来初始化该结构:
MOD_MISC("tcpinfo")
这里只有一个参数,指定了模块名. 当我们的模块被加载后,该模块把tcp_input函数的指针改为我们制定的new_input函数.新的函数会打印出mbuf里的包头的一些信息,然后
再调用原来的tcp_input函数.在做这些 之前,我们一定要确定同类的模块没有被加载.
对于这个模块一些值得注意的地方:首先运行这个模块时不适合传输大量的tcp包,printf()会变的很慢.大家试一下就知道.这个例子只是做测
试之用,其实大家可以想想我们既然 可以改变tcp协议栈里的函数指针,我们用模块来做一个tcp的内核后门也应该很容易,就留给大家思考吧,呵呵.第二,此代码原来是运行在
freebsd之上的,稍微修改了一下而已, bsd系列的内核真是很相像.
以下是该模块的完整代码(tcpmod.c):
#include <sys/param.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/exec.h> #include <sys/conf.h>
|