您的位置:首页 > 其它

初探iptables自动加载模块原理

2012-04-16 17:39 381 查看
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是怎么用的。

库模块源码:

#include <stdio.h>

#include <match.h>

#define _init __attribute__((constructor)) _INIT

static int hello()

{

printf("hello called\n");

return 0;

}

static struct test_match test = {

.name = "hello",

.match = hello

};

void _init(void)

{

printf("init hello\n");

register_match(&test);

return ;

}

复制代码
运行后生成libhello.so文件

主程式动态加载so文件并调用模块的函数

#include <stdio.h>

#include <match.h>

#include <dlfcn.h>

int main()

{

struct test_match *ptr;

if (dlopen("./libhello.so", RTLD_NOW) == NULL) {

printf("load lib error.\n");

return 0;

}

ptr = find_match("hello");

if (ptr) {

printf("find match:%s\n", ptr->name);

ptr->match();

}

return 0;

}

复制代码
编译成可执行文件运行:

[root@rhce netcos]# ./main

init hello

find match:hello

hello called

复制代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: