gpt4 book ai didi

linux - 如何为 ebtables 编写自定义模块?

转载 作者:IT王子 更新时间:2023-10-29 01:02:08 26 4
gpt4 key购买 nike

基本上,我想编写一个内核模块,为 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(&reg);
}

void cleanup_module(void)
{
xt_unregister_match(&reg);
}

我成功加载了模块。但它就像不存在一样。我没有在 matchcheck 函数中获取日志,所以桥显然没有考虑我的过滤器。我做错了什么?

我尝试了很多组合,先加载我的过滤器,先设置网桥或先设置 ebtables 规则,但它们都没有改变任何东西。

附言这座桥本身就可以工作。我确信 ebtables 也有效,因为如果我添加一个丢弃包的策略,我不会在最终计算机上收到它们。我想不通的是如何告诉 ebtables 也考虑我的过滤器。

最佳答案

我得到了这个工作,不是以最优雅的方式,但无论如何,我在这里为 future 的流浪者写下它:

假设您的过滤器名称是:“any”

用户空间插件

您需要在 ebtables 源之外不可用的 header 。所以,获取源代码,然后转到扩展文件夹。在 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 知道如何使用您的过滤器.

注意:其中有些函数看似不必要,但如果您不编写它们,则会出现“BUG: bad merge”错误。

内核空间模块

内核空间模块更简单:

#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(&reg);
printk("Bridge initializing...done!\n");
return ret;
}

void cleanup_module(void)
{
printk("Bridge exiting...\n");
xt_unregister_match(&reg);
printk("Bridge exiting...done!\n");
}

注意:如果您在用户空间中使用struct whatever,您必须在内核空间中使用相同的结构。

注意:与使用 ebtables header /函数的用户空间插件不同,内核模块使用 xtables 代替!!

编译模块(相当标准)并安装它以自动加载。或者,您可以在添加/删除 ebtables 规则之前自行insmodrmmod 模块。

如何让ebtables使用你的过滤器

只需添加一个包含 --use-any some_value 的规则就可以了。例如:

ebtables -A FORWARD --use-any 1 -j ACCEPT

注意:这个--use-anyebt_u_match reg.extra_ops中给出的选项 (在用户空间插件的数组 _any_opts 中定义)。

关于linux - 如何为 ebtables 编写自定义模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9313088/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com