如何为eBtables编写自定义模块?
题
基本上,我想编写一个内核模块,该模块将可能的过滤器添加到Ebtables中。然后,我需要告诉eBtables在我设置的桥梁上使用过滤器。
我需要编写自己的模块的原因是我想在连续软件包之间引入延迟(出于某些测试原因)。为了证明,我的网络最初有这样的流量:
+++-----------------+++-----------------+++-----------------+++-----------------
在哪里 +
显示包裹的流量 -
意味着线上没有包装。我想在两者之间放一个桥,以使数据包的模式会改变以下:
+----+----+---------+----+----+---------+----+----+---------+----+----+---------
这意味着我将确保每个数据包的到达之间会有一定的延迟。
现在,我已经编写了以下简单代码,这些代码基本上是从Linux-Source/Net/bridge/netfilter/ebt_ip.c:
static bool match(const struct sk_buff *skb, const struct xt_match_param *par)
{
printk(KERN_INFO"match called\n");
return true; // match everything!
}
static bool check(const struct xt_mtchk_param *par)
{
printk(KERN_INFO"check called\n");
return true; // pass everything!
}
static struct xt_match reg __read_mostly = {
.name = "any", // I made this up, but I tried also putting ip for example which didn't change anything.
.revision = 0,
.family = NFPROTO_BRIDGE,
.match = match,
.checkentry = check,
.matchsize = XT_ALIGN(4), // don't know what this is, so I just gave it an `int`
.me = THIS_MODULE
};
int init_module(void)
{
return xt_register_match(®);
}
void cleanup_module(void)
{
xt_unregister_match(®);
}
我成功加载了模块。但这似乎不在那里。我没有里面的日志 match
和 check
功能使桥显然不考虑我的过滤器。我究竟做错了什么?
我尝试了许多首先加载过滤器,首先设置桥梁或首先设置eBtables规则的组合,但是它们都没有更改任何内容。
PS桥本身起作用。我敢肯定,eBtables也有效,因为如果我添加了删除软件包的策略,我将不会在最终计算机上收到它们。我不知道如何告诉ebtables也考虑我的过滤器。
解决方案
要使用内核模块,您还需要为用户空间程序编写适当的插件,然后插入调用它的规则。
如果您没有任何选择,请勿指定任何 .matchsize
参数in struct xt_match
(等于指定0)。
其他提示
我得到了这种工作,不是最优雅的方式,但是无论如何,我在这里写它是为了未来的流浪者:
假设您的过滤名称是:“任何”
用户空间插件
您需要在eBtables源外不可用的标题。因此,获取源代码,然后转到扩展文件夹。在makefile中,添加 any
至 EXT_FUNC
(这是要构建的目标)并写入源文件 ebt_any.c
如以下内容:
#include <stdio.h>
#include <getopt.h>
#include "../include/ebtables_u.h"
/*struct whatever
{
int a;
};*/
static struct option _any_opts[] =
{
{"use-any", required_argument, 0, 0},
{'\0'}
};
static void _any_help(void)
{
printf("any match options: nothing!\n");
}
static void _any_init(struct ebt_entry_match *match)
{
printf("any_init\n");
}
static void _any_check(const struct ebt_u_entry *entry, const struct ebt_entry_match *match, const char *name,
unsigned int hookmask, unsigned int time)
{
printf("any_check\n");
}
static int _any_parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, struct ebt_entry_match **match)
{
printf("any_parse: %d\n", c);
if (c == 0)
return 1;
return 0; // return true for anything
}
static int _any_compare(const struct ebt_entry_match *m1, const struct ebt_entry_match *m2)
{
/* struct whatever *w1 = (struct whatever *)m1->data;
struct whatever *w2 = (struct whatever *)m2->data;
if (w1->a != w2->a)
return 0;*/
return 1;
}
static void _any_print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match)
{
printf("any_print");
}
static struct ebt_u_match _reg = {
.name = "any",
// .size = sizeof(struct whatever),
.help = _any_help,
.init = _any_init,
.parse = _any_parse,
.final_check = _any_check,
.print = _any_print,
.compare = _any_compare,
.extra_ops = _any_opts,
};
void _init(void)
{
ebt_register_match(&_reg);
}
笔记: 如果您有从用户空间到内核空间的数据,请写东西而不是 struct whatever
. 。我已经评论了,因为我什么都不使用。
笔记: 即使您的程序不需要选项(例如应该匹配所有内容的我的选项),您还是需要给出一个选项,因为这就是Ebtables知道使用过滤器的方式。
笔记: 其中一些功能似乎是不必要的,但是如果您不编写它们,则会获得“错误:不良合并”错误。
内核空间模块
内核空间模块更简单:
#include <linux/netfilter/x_tables.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Shahbaz Youssefi");
MODULE_ALIAS("ebt_any");
/*struct whatever
{
int a;
};*/
static bool match(const struct sk_buff *skb, const struct xt_match_param *par)
{
printk(KERN_INFO"Matching\n");
return true;
}
static bool check(const struct xt_mtchk_param *par)
{
printk(KERN_INFO"Checking\n");
return true;
}
static struct xt_match reg __read_mostly = {
.name = "any",
.match = match,
// .matchsize = sizeof(struct whatever),
.checkentry = check,
.me = THIS_MODULE
};
int init_module(void)
{
int ret = 0;
printk("Bridge initializing...\n");
ret = xt_register_match(®);
printk("Bridge initializing...done!\n");
return ret;
}
void cleanup_module(void)
{
printk("Bridge exiting...\n");
xt_unregister_match(®);
printk("Bridge exiting...done!\n");
}
笔记: 如果您使用 struct whatever
在用户空间中,您必须在内核空间中使用相同的方法。
笔记: 与使用eBtableS标头/功能的用户空间插件不同,内核模块改用XTABLE!
编译模块(相当标准)并安装自动加载。或者,您可以 insmod
和 rmmod
在添加/删除eBtables规则之后,本人自己。
如何使ebtables使用过滤器
只需添加一个包含的规则 --use-any some_value
而且你很好。例如:
ebtables -A FORWARD --use-any 1 -j ACCEPT
笔记: 这个 --use-any
是个 option
这是在 ebt_u_match reg.extra_ops
(在数组中定义 _any_opts
)在用户空间插件中。