|
iptables使用dlopen加载动态库,每个库中都定义了void _init(void)函数,在使用dlopen加载库的时候系统会调用_init函数, 在_init函数中调用xtables_register_match对模块进行注册。iptables这种动态加载模块的方式很适合做定制开发,所以我就自己摸索了下。我自己写了一个测试的例子: gcc -O2 -Wall -fPIC -c hello.c gcc -shared -o hello.so hello.o hello.o: In function `_init': hello.c:(.text+0x0): multiple definition of `_init' /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../crti.o:(.init+0x0): first defined here 编译的时候出现了重复定义的错误。这是为什么? _init是共享库用来初始化全局变量和对象的,在库文件中已经定义过了。有什么办法可以使用_init来初始化我们自己的函数呢? 通过查看iptables的模块代码,发现所有的文件都包含#include <xtables.h>头文件,会不会是xtables.h中动了什么手脚? 在hello.c中包含xtables.h头文件,果然编译通过。 #include <stdio.h> #include <xtables.h> int main() { return 0; } void _init(void) { printf("init hello\n"); return ; } gcc -O2 -Wall -o hello -I/home/mogo/2.6.17-x86-old/user/iptables/include -fPIC hello.c [root@rhce lion]# ./hello init hello xtables.h头文件中到底做了什么呢? 我在代码中看到一个宏定义:# define _init __attribute__((constructor)) _INIT,会不会是这个? 于是在hello.c中去掉头文件xtables.h,将该宏定义换进去,果然没问题。 那这个宏定义是什么意思呢? 用__attribute__((constructor))来定义的函数,表示函数是构造函数,在main执行之前被调用;相应的用__attribute__ ((destructor))析构函数,在main退出时执行。 void _init(void)就相当于是__attribute__((constructor)) _INIT(void),其实不管函数名定义成什么都会被执行到。 自动初始化的问题解决了,现在就来看看dlopen是怎么用的。 库模块源码: 运行后生成libhello.so文件 主程式动态加载so文件并调用模块的函数 编译成可执行文件运行: |
初探iptables自动加载模块原理
最新推荐文章于 2024-06-24 14:07:29 发布
本文深入探讨iptables自动加载模块的工作原理,从构造函数、析构函数、结构体、GCC编译器以及空指针的角度出发,揭示其内在机制。
963

被折叠的 条评论
为什么被折叠?



