您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > Netfilter新增target模块浅析---Copy
Netfilter新增target模块浅析2011-6-16Netfilter新增加target模块浅析2/9目录1模块功能介绍...............................................................................................................................32应用层实现...................................................................................................................................33内核实现.......................................................................................................................................74配置部分.......................................................................................................................................85附录..............................................................................................................................................86参考资料.......................................................................................................................................9Netfilter新增加target模块浅析3/9Netfilter新增target模块浅析1模块功能介绍大家现在已经对iptables的使用有了一定的了解,iptables基本命令格式为:iptablesACTIONchainrule-specificationoptions本文档中,我们要讨论的是options中的-jtarget中target模块的实现方式,要实现一个target功能,其中包括二部分,即内核空间中的和用户空间中的。下面就一个实际的例子来一起学习整个功能的实现过程。我们以IPID模块为例。(注:本文档中提到的均为没有使用共享库,即宏NO_SHARED_LIBS定义了。)我们要实现的IPID模块为修改IP头中的ID字段。我们可以看下IP报头格式。Identification字段主要用来唯一的标志一个分片的数据包,当然,该字段还可以用于其它功能。我们现在要实现的是修改这个ID字段,实现二种方法,一种是数据包的ID有规律的递增,另一种是无规律的随机产生。下面演示的是具体命令:#iptables-tmangle-IShareProtection-ibr0-jIPID--ipid-pace12应用层实现下面我们从用户空间开始,实现对以上命令的解析。先看下iptables_target结构structxtables_target{structxtables_target*next;xt_chainlabelname;/*模块的版本号(默认为0).*/u_int8_trevision;u_int16_tfamily;constchar*version;/*Sizeoftargetdata.*/Netfilter新增加target模块浅析4/9size_tsize;/*Sizeoftargetdatareleventforuserspacecomparisonpurposes*/size_tuserspacesize;/*Functionwhichprintsoutusagemessage.*/void(*help)(void);/*Initializethetarget.*/void(*init)(structxt_entry_target*t);/*Functionwhichparsescommandoptions;returnstrueifitateanoption*//*entryisstructipt_entryforexample*/int(*parse)(intc,char**argv,intinvert,unsignedint*flags,constvoid*entry,structxt_entry_target**targetinfo);/*Finalcheck;exitifnotok.*/void(*final_check)(unsignedintflags);/*Printsoutthetargetiffnon-NULL:putspaceatend*/void(*print)(constvoid*ip,conststructxt_entry_target*target,intnumeric);/*Savesthetarginfoinparsableformtostdout.*/void(*save)(constvoid*ip,conststructxt_entry_target*target);/*Pointertolistofextracommand-lineoptions*/conststructoption*extra_opts;/*Ignorethesemenbehindthecurtain:*/unsignedintoption_offset;structxt_entry_target*t;unsignedinttflags;unsignedintused;#ifdefNO_SHARED_LIBSunsignedintloaded;/*simulateloadingsooptionsaremergedproperly*/#endif};以上结构的成员不必全部实现,一般来说只要初始化下面必个成员(ipt_IPID.c):可以看到name为IPID,即我们演示命令中-j后面的target名。staticstructiptables_targetipid_target={.next=NULL,.name=IPID,.version=IPTABLES_VERSION,.size=IPT_ALIGN(sizeof(structipt_IPID_info)),.userspacesize=IPT_ALIGN(sizeof(structipt_IPID_info)),.help=&ipid_help,.parse=&ipid_parse,.final_check=&ipid_check,.print=&ipid_print,Netfilter新增加target模块浅析5/9.save=&ipid_save,.extra_opts=ipid_opts};其中支持参数的结构体为extra_opts,它是structoption结构:staticstructoptionipid_opts[]={{ipid-pace,1,NULL,'1'},{ipid-chaotic,1,NULL,'2'},{}};option结构详细内容及成员解释如下:structoption{constchar*name;inthas_arg;int*flag;intval;};对结构中的各元素解释如下:constchar*name这是选项名,前面没有短横线。譬如help、verbose之类。inthas_arg描述了选项是否有选项参数。如果有,是哪种类型的参数,此时,它的值一定是下表中的一个。符号常量数值含义No_argument0选项没有参数Required_argument1选项需要参数Optional_argument2选项参数可选int*flag如果这个指针为NULL,那么getopt_long()返回该结构val字段中的数值。如果该指针不为NULL,getopt_long()会使得它所指向的变量中填入val字段中的数值,并且getopt_long()返回0。如果flag不是NULL,但未发现长选项,那么它所指向的变量的数值不变。intval这个值是发现了长选项时的返回值,或者flag不是NULL时载入*flag中的值。典型情况下,若flag不是NULL,那么val是个真/假值,譬如1或0;另一方面,如果flag是NULL,那么val通常是字符常量,若长选项与短选项一致,那么该字符常量应该与optstring中出现的这个选项的参数相同。当所有以上这些成员的函数指针都已经初始实现并初始化完成,最后剩下的工作就是将我们新加的target注册到全局变量xtables_targets中了。我们要增加函数:void_init(void){register_target(&ipid_target);}这个函数看起来比较奇怪,搜索一下,发现没有哪个调用它的地方。有情况那它是怎样注册的呢。查看iptables\extensions\Makefile,发现有下面一段。extensions/initext.o:extensions/initext.cNetfilter新增加target模块浅析6/9extensions/initext6.o:extensions/initext6.cextensions/initext.c:extensions/Makefileecho$@foriin$(EXT_FUNC);do\echoexternvoid$${i}_init(void);$@;\doneechovoidinit_extensions(void){$@foriin$(EXT_FUNC);do\echo$${i}_init();$@;\doneecho}$@extensions/initext6.c:extensions/Makefileecho$@foriin$(EXT6_FUNC);do\echoexternvoid$${i}_init(void);$@;\doneechovoidinit_extensions(void){$@foriin$(EXT6_FUNC);do\echo$${i}_init();$@;\doneecho}$@extensions/lib%.o:extensions/lib%.c$(CC)$(CFLAGS)-D_INIT=$*_init-c-o$@$原来会根据Makefile生成文件initext.c文件,根据编译进去的模块,自动生成函数。externvoidipt_IPID_init(void);voidinit_extensions(void){ipt_IPID_init();}在xtables.h中有下面宏定义:#define_init__attribute__((constructor))my_init#ifdefNO_SHARED_LIBS#ifdef_INIT#undef_init#define_init_INIT#endif在上面的MAKEFILE中,可以看出宏_INIT是会被具体的模块名字代替的,比如我们这里说到的IPID模块,替换后_INIT=ipt_IDID_init。再看头文件中宏_init被_INIT代替,所以我们需要实现注册的函数应该是这样的。void_init(void){register_target(&ipid_target);Netfilter新增加target模块浅析7/9}从以上可以看出,当iptables的main函数执行的时候就会执行init_extensions
本文标题:Netfilter新增target模块浅析---Copy
链接地址:https://www.777doc.com/doc-4519425 .html