kernel模块
#include <linux/types.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
#include <linux/netfilter/x_tables.h>
#define DRV_VERSION "1.0"
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION("Xtables: match test");
struct id {
unsigned char id;
};
static int match_check(const struct xt_mtchk_param *par)
{
const struct id *mr = par->matchinfo;
if (mr->id == 0) {
pr_info("%s: id must not be 0\n",
par->match->name);
return -EINVAL;
}
return 0;
}
static bool
match_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct id *mr = par->matchinfo;
printk("just test match id: %u, hooknum %u\n", mr->id, par->hooknum);
return XT_CONTINUE;
}
static struct xt_match match_reg __read_mostly = {
.name = "match",
.family = NFPROTO_IPV4,
.match = match_mt,
.matchsize = sizeof(struct id),
//.table = "mangle",
.hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN),
.checkentry = match_check,
.me = THIS_MODULE,
};
static int __init match_match_init(void)
{
return xt_register_match(&match_reg);
}
static void __exit match_match_exit(void)
{
xt_unregister_match(&match_reg);
}
module_init(match_match_init);
module_exit(match_match_exit);
userspace so:
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <xtables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
enum {
FROM_MATCH = 0,
};
struct id {
unsigned char id;
};
struct ipt_matchinfo
{
struct xt_entry_match t;
struct id mr;
};
static void match_help(void)
{
printf(
"match options:\n"
" --id id <id 1--255>\n");
}
static const struct xt_option_entry match_opts[] = {
{
.name = "id",
.id = FROM_MATCH,
.type = XTTYPE_UINT8,
.flags = XTOPT_MAND,
.min = 1
},
XTOPT_TABLEEND,
};
static void match_parse(struct xt_option_call *cb)
{
struct ipt_matchinfo *info = (void *)(*cb->match);
xtables_option_parse(cb);
switch (cb->entry->id) {
case FROM_MATCH: {
info->mr.id = cb->val.u8;
break;
}
}
}
static void match_save(const void *ip, const struct xt_entry_match *match)
{
const struct ipt_matchinfo *info = (const void *)match;
printf(" --id %u\n", info->mr.id);
}
static struct xtables_match match_mt_reg = {
.name = "match",
.version = XTABLES_VERSION,
.family = NFPROTO_IPV4,
.size = XT_ALIGN(sizeof(struct id)),
.userspacesize = XT_ALIGN(sizeof(struct id)),
.help = match_help,
.x6_parse = match_parse,
.save = match_save,
.x6_options = match_opts,
};
void _init(void)
{
xtables_register_match(&match_mt_reg);
}
Makefile:
CC=gcc
PWD = $(shell pwd)
IPTABLES_SRC = $(PWD)/iptables-1.4.21
INCLUDE = -I$(IPTABLES_SRC)/include
KERNEL_SRC = /lib/modules/`uname -r`/build
obj-m = ipt_match.o
all: ipt_match.ko libipt_match.so
ipt_match.ko: ipt_match.c
$(MAKE) -C $(KERNEL_SRC) SUBDIRS=$(PWD) modules
libipt_match.so: libipt_match.c
$(CC) $(INCLUDE) -fPIC -c libipt_match.c
ld -shared -o libipt_match.so libipt_match.o
usage:
iptables -t mangle -A PREROUTING -s x.x.x.x/24 -m match --id 100