我得到了这个工作,不是以最优雅的方式,但无论如何,我在这里为未来的流浪者写它:
假设您的过滤器名称是:“任何”
用户空间插件
您需要在 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 知道如何使用您的过滤器。
注意:其中一些函数似乎是不必要的,但如果你不编写它们,你会得到一个“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(®);
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 头文件/函数的用户空间插件不同,内核模块使用 xtables!
编译模块(相当标准)并安装它以进行自动加载。或者,您可以在添加/删除 ebtables 规则之前insmod
和自己的模块。rmmod
如何让 ebtables 使用你的过滤器
只需添加一个包含的规则,就可以了--use-any some_value
。例如:
ebtables -A FORWARD --use-any 1 -j ACCEPT
注意:这--use-any
是在用户空间插件option
中给出的ebt_u_match reg.extra_ops
(在数组中定义)。_any_opts