From 633b62df0104203591d5c427f6769857571b2540 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu" Date: Wed, 2 Jul 2008 12:20:18 +0000 Subject: Initial ipset release with kernel modules included. --- kernel/ipt_SET.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 kernel/ipt_SET.c (limited to 'kernel/ipt_SET.c') diff --git a/kernel/ipt_SET.c b/kernel/ipt_SET.c new file mode 100644 index 0000000..63ada14 --- /dev/null +++ b/kernel/ipt_SET.c @@ -0,0 +1,179 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson + * Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* ipt_SET.c - netfilter target to manipulate IP sets */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned int +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +target(struct sk_buff *skb, +#else +target(struct sk_buff **pskb, +#endif + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) + const struct xt_target *target, +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) + const void *targinfo, + void *userinfo) +#else + const void *targinfo) +#endif +{ + const struct ipt_set_info_target *info = targinfo; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + struct sk_buff *skb = *pskb; +#endif + + + if (info->add_set.index != IP_SET_INVALID_ID) + ip_set_addip_kernel(info->add_set.index, + skb, + info->add_set.flags); + if (info->del_set.index != IP_SET_INVALID_ID) + ip_set_delip_kernel(info->del_set.index, + skb, + info->del_set.flags); + + return IPT_CONTINUE; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) +static bool +#else +static int +#endif +checkentry(const char *tablename, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + const void *e, +#else + const struct ipt_entry *e, +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) + const struct xt_target *target, +#endif + void *targinfo, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) + unsigned int targinfosize, +#endif + unsigned int hook_mask) +{ + struct ipt_set_info_target *info = targinfo; + ip_set_id_t index; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) + if (targinfosize != IPT_ALIGN(sizeof(*info))) { + DP("bad target info size %u", targinfosize); + return 0; + } +#endif + + if (info->add_set.index != IP_SET_INVALID_ID) { + index = ip_set_get_byindex(info->add_set.index); + if (index == IP_SET_INVALID_ID) { + ip_set_printk("cannot find add_set index %u as target", + info->add_set.index); + return 0; /* error */ + } + } + + if (info->del_set.index != IP_SET_INVALID_ID) { + index = ip_set_get_byindex(info->del_set.index); + if (index == IP_SET_INVALID_ID) { + ip_set_printk("cannot find del_set index %u as target", + info->del_set.index); + return 0; /* error */ + } + } + if (info->add_set.flags[IP_SET_MAX_BINDINGS] != 0 + || info->del_set.flags[IP_SET_MAX_BINDINGS] != 0) { + ip_set_printk("That's nasty!"); + return 0; /* error */ + } + + return 1; +} + +static void destroy( +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) + const struct xt_target *target, +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) + void *targetinfo, unsigned int targetsize) +#else + void *targetinfo) +#endif +{ + struct ipt_set_info_target *info = targetinfo; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) + if (targetsize != IPT_ALIGN(sizeof(struct ipt_set_info_target))) { + ip_set_printk("invalid targetsize %d", targetsize); + return; + } +#endif + if (info->add_set.index != IP_SET_INVALID_ID) + ip_set_put(info->add_set.index); + if (info->del_set.index != IP_SET_INVALID_ID) + ip_set_put(info->del_set.index); +} + +static struct ipt_target SET_target = { + .name = "SET", +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) + .family = AF_INET, +#endif + .target = target, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) + .targetsize = sizeof(struct ipt_set_info_target), +#endif + .checkentry = checkentry, + .destroy = destroy, + .me = THIS_MODULE +}; + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("iptables IP set target module"); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) +#define ipt_register_target xt_register_target +#define ipt_unregister_target xt_unregister_target +#endif + +static int __init ipt_SET_init(void) +{ + return ipt_register_target(&SET_target); +} + +static void __exit ipt_SET_fini(void) +{ + ipt_unregister_target(&SET_target); +} + +module_init(ipt_SET_init); +module_exit(ipt_SET_fini); -- cgit v1.2.3