X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fipt_SET.c;fp=net%2Fipv4%2Fnetfilter%2Fipt_SET.c;h=37e18ec072a80fdeaa36943a998ca0626506c610;hb=cee37fe97739d85991964371c1f3a745c00dd236;hp=0000000000000000000000000000000000000000;hpb=37b9e453a7750f55f473d51c91d184b703c2b883;p=linux-2.6.git diff --git a/net/ipv4/netfilter/ipt_SET.c b/net/ipv4/netfilter/ipt_SET.c new file mode 100644 index 000000000..37e18ec07 --- /dev/null +++ b/net/ipv4/netfilter/ipt_SET.c @@ -0,0 +1,128 @@ +/* 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 + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + const struct ipt_set_info_target *info = targinfo; + + if (info->add_set.index != IP_SET_INVALID_ID) + ip_set_addip_kernel(info->add_set.index, + *pskb, + info->add_set.flags); + if (info->del_set.index != IP_SET_INVALID_ID) + ip_set_delip_kernel(info->del_set.index, + *pskb, + info->del_set.flags); + + return IPT_CONTINUE; +} + +static int +checkentry(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, unsigned int hook_mask) +{ + struct ipt_set_info_target *info = + (struct ipt_set_info_target *) targinfo; + ip_set_id_t index; + + if (targinfosize != IPT_ALIGN(sizeof(*info))) { + DP("bad target info size %u", targinfosize); + return 0; + } + + 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(void *targetinfo, unsigned int targetsize) +{ + struct ipt_set_info_target *info = targetinfo; + + if (targetsize != IPT_ALIGN(sizeof(struct ipt_set_info_target))) { + ip_set_printk("invalid targetsize %d", targetsize); + return; + } + + 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", + .target = target, + .checkentry = checkentry, + .destroy = destroy, + .me = THIS_MODULE +}; + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("iptables IP set target module"); + +static int __init init(void) +{ + return ipt_register_target(&SET_target); +} + +static void __exit fini(void) +{ + ipt_unregister_target(&SET_target); +} + +module_init(init); +module_exit(fini);