xt_state.c revision df54aae02210e1acf3a1d2ffac9b29003835710c
1/* Kernel module to match connection tracking information. */ 2 3/* (C) 1999-2001 Paul `Rusty' Russell 4 * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11#include <linux/module.h> 12#include <linux/skbuff.h> 13#include <net/netfilter/nf_conntrack.h> 14#include <linux/netfilter/x_tables.h> 15#include <linux/netfilter/xt_state.h> 16 17MODULE_LICENSE("GPL"); 18MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); 19MODULE_DESCRIPTION("ip[6]_tables connection tracking state match module"); 20MODULE_ALIAS("ipt_state"); 21MODULE_ALIAS("ip6t_state"); 22 23static bool 24state_mt(const struct sk_buff *skb, const struct net_device *in, 25 const struct net_device *out, const struct xt_match *match, 26 const void *matchinfo, int offset, unsigned int protoff, 27 bool *hotdrop) 28{ 29 const struct xt_state_info *sinfo = matchinfo; 30 enum ip_conntrack_info ctinfo; 31 unsigned int statebit; 32 33 if (nf_ct_is_untracked(skb)) 34 statebit = XT_STATE_UNTRACKED; 35 else if (!nf_ct_get(skb, &ctinfo)) 36 statebit = XT_STATE_INVALID; 37 else 38 statebit = XT_STATE_BIT(ctinfo); 39 40 return (sinfo->statemask & statebit); 41} 42 43static bool 44state_mt_check(const char *tablename, const void *inf, 45 const struct xt_match *match, void *matchinfo, 46 unsigned int hook_mask) 47{ 48 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 49 printk(KERN_WARNING "can't load conntrack support for " 50 "proto=%u\n", match->family); 51 return false; 52 } 53 return true; 54} 55 56static void state_mt_destroy(const struct xt_match *match, void *matchinfo) 57{ 58 nf_ct_l3proto_module_put(match->family); 59} 60 61static struct xt_match state_mt_reg[] __read_mostly = { 62 { 63 .name = "state", 64 .family = AF_INET, 65 .checkentry = state_mt_check, 66 .match = state_mt, 67 .destroy = state_mt_destroy, 68 .matchsize = sizeof(struct xt_state_info), 69 .me = THIS_MODULE, 70 }, 71 { 72 .name = "state", 73 .family = AF_INET6, 74 .checkentry = state_mt_check, 75 .match = state_mt, 76 .destroy = state_mt_destroy, 77 .matchsize = sizeof(struct xt_state_info), 78 .me = THIS_MODULE, 79 }, 80}; 81 82static int __init state_mt_init(void) 83{ 84 return xt_register_matches(state_mt_reg, ARRAY_SIZE(state_mt_reg)); 85} 86 87static void __exit state_mt_exit(void) 88{ 89 xt_unregister_matches(state_mt_reg, ARRAY_SIZE(state_mt_reg)); 90} 91 92module_init(state_mt_init); 93module_exit(state_mt_exit); 94