/* 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);