11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Kernel module to match connection tracking information. */
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* (C) 1999-2001 Paul `Rusty' Russell
42e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald Welte * (C) 2002-2005 Netfilter Core Team <coreteam@netfilter.org>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License version 2 as
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * published by the Free Software Foundation.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/skbuff.h>
13587aa64163bb14f70098f450abab9410787fce9dPatrick McHardy#include <net/netfilter/nf_conntrack.h>
142e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald Welte#include <linux/netfilter/x_tables.h>
152e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald Welte#include <linux/netfilter/xt_state.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
192e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald WelteMODULE_DESCRIPTION("ip[6]_tables connection tracking state match module");
202e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald WelteMODULE_ALIAS("ipt_state");
212e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald WelteMODULE_ALIAS("ip6t_state");
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
231d93a9cbad608f6398ba6c5b588c504ccd35a2caJan Engelhardtstatic bool
2462fc8051083a334578c3f4b3488808f210b4565fJan Engelhardtstate_mt(const struct sk_buff *skb, struct xt_action_param *par)
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
26f7108a20dee44e5bb037f9e48f6a207b42e6ae1cJan Engelhardt	const struct xt_state_info *sinfo = par->matchinfo;
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	enum ip_conntrack_info ctinfo;
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int statebit;
295bfddbd46a95c978f4d3c992339cbdf4f4b790a3Eric Dumazet	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
315bfddbd46a95c978f4d3c992339cbdf4f4b790a3Eric Dumazet	if (!ct)
322e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald Welte		statebit = XT_STATE_INVALID;
335bfddbd46a95c978f4d3c992339cbdf4f4b790a3Eric Dumazet	else {
345bfddbd46a95c978f4d3c992339cbdf4f4b790a3Eric Dumazet		if (nf_ct_is_untracked(ct))
355bfddbd46a95c978f4d3c992339cbdf4f4b790a3Eric Dumazet			statebit = XT_STATE_UNTRACKED;
365bfddbd46a95c978f4d3c992339cbdf4f4b790a3Eric Dumazet		else
375bfddbd46a95c978f4d3c992339cbdf4f4b790a3Eric Dumazet			statebit = XT_STATE_BIT(ctinfo);
385bfddbd46a95c978f4d3c992339cbdf4f4b790a3Eric Dumazet	}
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (sinfo->statemask & statebit);
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
42b0f38452ff73da7e9e0ddc68cd5c6b93c897ca0dJan Engelhardtstatic int state_mt_check(const struct xt_mtchk_param *par)
43b9f78f9fca626875af8adc0f7366a38b8e625a0ePablo Neira Ayuso{
444a5a5c73b7cfee46a0b1411903cfa0dea532deecJan Engelhardt	int ret;
454a5a5c73b7cfee46a0b1411903cfa0dea532deecJan Engelhardt
464a5a5c73b7cfee46a0b1411903cfa0dea532deecJan Engelhardt	ret = nf_ct_l3proto_try_module_get(par->family);
47f95c74e33eff5e3fe9798e2dc0a7749150ea3f80Jan Engelhardt	if (ret < 0)
488bee4bad03c5b601bd6cea123c31025680587cccJan Engelhardt		pr_info("cannot load conntrack support for proto=%u\n",
498bee4bad03c5b601bd6cea123c31025680587cccJan Engelhardt			par->family);
50f95c74e33eff5e3fe9798e2dc0a7749150ea3f80Jan Engelhardt	return ret;
51b9f78f9fca626875af8adc0f7366a38b8e625a0ePablo Neira Ayuso}
52b9f78f9fca626875af8adc0f7366a38b8e625a0ePablo Neira Ayuso
536be3d8598e883fb632edf059ba2f8d1b9f4da138Jan Engelhardtstatic void state_mt_destroy(const struct xt_mtdtor_param *par)
54b9f78f9fca626875af8adc0f7366a38b8e625a0ePablo Neira Ayuso{
55aa5fa3185791aac71c9172d4fda3e8729164b5d1Jan Engelhardt	nf_ct_l3proto_module_put(par->family);
56b9f78f9fca626875af8adc0f7366a38b8e625a0ePablo Neira Ayuso}
57b9f78f9fca626875af8adc0f7366a38b8e625a0ePablo Neira Ayuso
58b44672889c11e13e4f4dc0a8ee23f0e64f1e57c6Jan Engelhardtstatic struct xt_match state_mt_reg __read_mostly = {
59b44672889c11e13e4f4dc0a8ee23f0e64f1e57c6Jan Engelhardt	.name       = "state",
60b44672889c11e13e4f4dc0a8ee23f0e64f1e57c6Jan Engelhardt	.family     = NFPROTO_UNSPEC,
61b44672889c11e13e4f4dc0a8ee23f0e64f1e57c6Jan Engelhardt	.checkentry = state_mt_check,
62b44672889c11e13e4f4dc0a8ee23f0e64f1e57c6Jan Engelhardt	.match      = state_mt,
63b44672889c11e13e4f4dc0a8ee23f0e64f1e57c6Jan Engelhardt	.destroy    = state_mt_destroy,
64b44672889c11e13e4f4dc0a8ee23f0e64f1e57c6Jan Engelhardt	.matchsize  = sizeof(struct xt_state_info),
65b44672889c11e13e4f4dc0a8ee23f0e64f1e57c6Jan Engelhardt	.me         = THIS_MODULE,
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
68d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtstatic int __init state_mt_init(void)
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
70b44672889c11e13e4f4dc0a8ee23f0e64f1e57c6Jan Engelhardt	return xt_register_match(&state_mt_reg);
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
73d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtstatic void __exit state_mt_exit(void)
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
75b44672889c11e13e4f4dc0a8ee23f0e64f1e57c6Jan Engelhardt	xt_unregister_match(&state_mt_reg);
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
78d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtmodule_init(state_mt_init);
79d3c5ee6d545b5372fd525ebe16988a5b6efeceb0Jan Engelhardtmodule_exit(state_mt_exit);
80