-
-
[讨论]nefilter模块的问题(系统调用)
-
发表于:
2016-12-30 18:16
3927
-
我编写了一个测试模块(网上的例子,功能是将收到的数据包的“源地址”改为 8.8.8.8,让本机“收不到”远端的数据包),如下:
// test.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/inet.h>
static struct nf_hook_ops nfho;
unsigned int my_hookfn(unsigned int hooknum,struct sk_buff *skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff *))
{
struct iphdr *iph;
iph = ip_hdr(skb);
printk(KERN_INFO"src IP %pI4\n", &iph->saddr);
//模块功能是将收到的数据包的“源地址”改为 8.8.8.8,让本机“收不到”远端的数据包
iph->saddr = in_aton("8.8.8.8");
return NF_ACCEPT;
}
测试函数---> void abc(void)
{
printk(KERN_INFO "test:abc\n");
}
static int __init sknf_init(void)
{
nfho.hook = my_hookfn;
nfho.pf = PF_INET;
nfho.hooknum = NF_INET_PRE_ROUTING;
nfho.priority = NF_IP_PRI_FIRST;
if (nf_register_hook(&nfho))
{
printk(KERN_ERR"nf_register_hook() failed\n");
return -1;
}
return 0;
}
static void __exit sknf_exit(void)
{
nf_unregister_hook(&nfho);
}
module_init(sknf_init);
module_exit(sknf_exit);
MODULE_AUTHOR("test");
MODULE_LICENSE("GPL");
Makefile如下:
obj-m := test.o
modules-objs := test
KDIR := /usr/src/linux-headers-$(shell uname -r)
all: realclean mod clean
mod:
make -C $(KDIR) M=`pwd` modules
realclean:
rm -rf *.o *.cmd .tmp* *.ko.cmd *.mod.c *.o.cmd .*.mod.o.cmd .*.ko.cmd .*.o.cmd *.ko
clean:
rm -rf *.o *.cmd .tmp* *.ko.cmd *.mod.c *.o.cmd .*.mod.o.cmd .*.ko.cmd .*.o.cmd
install:
sudo insmod test.ko
remove:
sudo rmmod test
1、在terminal_1中,编译模块并安装模块(成功):
>make all
>make install
2、在terminal_2中,进行模块测试(并打开wireshark观察数据包状况)
>curl
21eK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3u0S2K9h3c8#2i4K6u0W2j5$3!0E0
发现本机已发送“
272K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3u0S2K9h3c8#2i4K6u0W2j5$3!0E0i4@1f1J5i4K6R3H3i4K6W2p5i4@1f1%4i4K6W2m8i4K6R3@1i4@1f1$3i4K6W2r3i4@1p5#2i4@1f1^5i4@1q4r3i4@1p5J5i4@1g2r3i4@1u0o6i4K6S2o6i4@1f1#2i4@1t1&6i4@1t1$3i4@1f1^5i4K6S2q4i4@1t1%4i4@1f1#2i4@1u0q4i4K6V1%4i4@1f1^5i4@1u0r3i4K6W2o6i4@1f1%4i4@1q4n7i4@1q4r3i4@1f1%4i4K6W2m8i4K6R3@1k6r3&6K6i4@1f1#2i4K6W2n7i4K6W2q4i4@1f1#2i4@1u0m8i4K6V1@1i4@1g2r3i4@1u0o6i4K6R3^5i4@1f1#2i4K6S2p5i4@1t1K6i4@1f1$3i4K6V1@1i4@1t1$3i4@1f1#2i4K6R3^5i4@1t1H3i4@1f1#2i4K6S2o6i4K6R3#2i4@1f1#2i4K6V1H3i4@1q4n7i4@1f1%4i4K6V1&6i4@1u0q4i4@1f1#2i4@1u0m8i4@1p5$3K9i4m8Q4c8e0g2Q4z5f1y4Q4b7U0m8Q4c8e0g2Q4z5f1c8Q4z5o6m8Q4c8e0N6Q4z5f1q4Q4z5o6c8Q4c8e0k6Q4z5e0g2Q4b7U0m8Q4c8e0k6Q4z5p5c8Q4b7f1g2Q4c8e0g2Q4z5p5y4Q4z5o6g2Q4c8f1k6Q4b7V1y4Q4z5o6W2Q4c8e0y4Q4z5o6m8Q4z5o6u0Q4c8e0c8Q4b7U0W2Q4z5p5u0Q4c8e0g2Q4z5e0m8Q4z5p5g2Q4c8f1k6Q4b7V1y4Q4z5p5y4Q4c8e0k6Q4z5f1y4Q4b7f1y4Q4c8e0k6Q4z5f1y4Q4b7V1q4Q4c8e0g2Q4b7U0m8Q4b7U0q4Q4c8e0g2Q4z5o6k6Q4z5p5c8Q4c8e0u0Q4z5o6m8Q4z5f1y4Q4c8e0k6Q4b7U0u0Q4b7e0q4Q4c8e0k6Q4z5f1y4Q4z5o6W2Q4c8e0u0Q4z5o6m8Q4z5f1c8Q4c8e0g2Q4z5e0u0Q4z5p5y4Q4c8e0S2Q4b7V1k6Q4z5f1y4Q4c8e0N6Q4b7f1u0Q4b7f1k6Q4c8e0k6Q4z5f1y4Q4z5o6W2Q4c8e0k6Q4z5f1u0Q4b7U0c8Q4c8e0g2Q4b7e0c8Q4z5f1q4Q4c8e0N6Q4z5f1q4Q4z5o6c8Q4c8e0W2Q4z5o6m8Q4z5f1q4Q4c8e0c8Q4b7V1k6Q4b7e0q4Q4c8f1k6Q4b7V1y4Q4z5o6S2Q4c8e0k6Q4b7f1c8Q4b7e0y4Q4c8e0g2Q4b7U0S2Q4b7U0S2Q4c8e0g2Q4b7V1q4Q4z5e0c8Q4c8e0S2Q4b7f1k6Q4b7e0g2Q4c8e0k6Q4z5e0S2Q4b7f1k6Q4c8e0S2Q4z5p5g2Q4b7U0N6Q4c8e0g2Q4z5p5k6Q4z5e0k6%4N6%4N6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2!0q4y4#2)9&6b7g2)9^5y4q4!0q4y4#2!0n7c8q4)9&6x3g2!0q4z5g2!0m8x3g2!0n7y4g2!0q4c8W2!0n7b7#2)9^5z5g2!0q4x3#2)9^5x3q4)9^5x3R3`.`.
3、在terminal_1中,卸载该模块
>make remove
4、在termial_2中,再次进行模块测试(并打开wireshark观察数据包状况)
>curl
9d4K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3u0S2K9h3c8#2i4K6u0W2j5$3!0E0
发现本机已发送“
485K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3u0S2K9h3c8#2i4K6u0W2j5$3!0E0i4@1f1J5i4K6R3H3i4K6W2p5i4@1f1%4i4K6W2m8i4K6R3@1i4@1f1$3i4K6W2r3i4@1p5#2i4@1f1^5i4@1q4r3i4@1p5J5i4@1g2r3i4@1u0o6i4K6S2o6i4@1f1#2i4@1t1&6i4@1t1$3i4@1f1^5i4K6S2q4i4@1t1%4i4@1f1#2i4@1u0q4i4K6V1%4i4@1f1^5i4@1u0r3i4K6W2o6i4@1f1%4i4@1q4n7i4@1q4r3i4@1f1%4i4K6W2m8i4K6R3@1k6r3&6K6i4@1f1#2i4K6W2n7i4K6W2q4i4@1f1#2i4@1u0m8i4K6V1@1i4@1g2r3i4@1u0o6i4K6R3^5i4@1f1#2i4K6S2p5i4@1t1K6i4@1f1$3i4K6V1@1i4@1t1$3i4@1f1#2i4K6R3^5i4@1t1H3i4@1f1#2i4K6S2o6i4K6R3#2i4@1f1#2i4K6V1H3i4@1q4n7i4@1f1%4i4K6V1&6i4@1u0q4i4@1f1#2i4@1u0m8i4@1p5$3K9i4m8Q4c8e0g2Q4z5f1y4Q4b7U0m8Q4c8e0g2Q4z5f1c8Q4z5o6m8Q4c8e0N6Q4z5f1q4Q4z5o6c8Q4c8e0k6Q4z5e0g2Q4b7U0m8Q4c8e0k6Q4z5p5c8Q4b7f1g2Q4c8e0g2Q4z5p5y4Q4z5o6g2Q4c8f1k6Q4b7V1y4Q4z5o6W2Q4c8e0y4Q4z5o6m8Q4z5o6u0Q4c8e0c8Q4b7U0W2Q4z5p5u0Q4c8e0g2Q4z5e0m8Q4z5p5g2Q4c8f1k6Q4b7V1y4Q4z5p5y4Q4c8e0k6Q4z5f1y4Q4b7f1y4Q4c8e0k6Q4z5f1y4Q4b7V1q4Q4c8e0S2Q4b7V1k6Q4z5e0S2Q4c8e0S2Q4z5p5g2Q4b7U0N6Q4c8e0g2Q4z5p5k6Q4z5e0k6Q4c8e0g2Q4z5o6S2Q4b7U0m8%4N6%4N6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2!0q4y4#2)9&6b7g2)9^5y4q4!0q4y4#2!0n7c8q4)9&6x3g2!0q4z5g2!0m8x3g2!0n7y4g2!0q4c8W2!0n7b7#2)9^5x3g2!0q4y4g2)9^5c8q4!0n7x3#2!0q4c8W2!0n7b7#2)9^5b7#2!0q4z5g2)9^5x3q4)9&6b7g2!0q4y4q4!0n7c8W2!0m8x3g2!0q4y4W2)9^5x3g2!0m8x3W2!0q4y4g2!0m8y4q4)9^5c8q4!0q4y4q4!0n7b7g2)9^5y4W2!0q4y4W2!0m8c8q4!0m8x3#2!0q4y4g2!0n7z5q4!0n7z5q4!0q4x3#2)9^5x3q4)9^5x3R3`.`.
5、可见,test.ko这个测试模块是可以正常工作的。
问题:
1、在模块源文件 test.c中,我另外写了一个 abc() 的测试函数,我怎样才可以调用该函数呢?即,我的应用程序(我另外写的c代码,不包含在test.ko中的)如何调用“linux系统中正在运行的模块(test.ko)”里的函数?
2、目前程序的功能是将收到的数据包的“源地址”改为 8.8.8.8,如果我现在将它的功能改为将收到的数据包的“源地址”改为 2.2.2.2,那是否意味着我要手工改程序并重新编译?我的意思是,在真实的应用中,在防火墙的界面了,原先在修改源地址的一栏里写的是8.8.8.8,现在我要将它改为2.2.2.2,正常情况下,按“确定”按钮就可生效。但这个“生效”是如何实现的呢?防火墙界面必定是ring3的,它的这个“确定”按钮是如何实现内核数据的更改?而且,一般情况下,按下”确定“按钮后,防火墙功能是立即生效的,且防火墙是没有重启的(即不存在重新编译)........
注:
我知道这里涉及到ring3 --> ring0 的问题,一般是会用到系统调用去实现,那netfilter提供类似的系统调用吗?如果有,那是什么?如果没有,那各位做netfilter防火墙的,你们的netfilter防火墙里都是一大堆“自制”(每个功能写一个系统调用)的系统调用?
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课