]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - net/ipv4/netfilter/ipt_helper.c
[NETFILTER]: Add nf_conntrack subsystem.
[mirror_ubuntu-zesty-kernel.git] / net / ipv4 / netfilter / ipt_helper.c
CommitLineData
1da177e4
LT
1/* iptables module to match on related connections */
2/*
3 * (C) 2001 Martin Josefsson <gandalf@wlug.westbo.se>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * 19 Mar 2002 Harald Welte <laforge@gnumonks.org>:
10 * - Port to newnat infrastructure
11 */
12
13#include <linux/module.h>
14#include <linux/skbuff.h>
15#include <linux/netfilter.h>
9fb9cbb1 16#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
1da177e4
LT
17#include <linux/netfilter_ipv4/ip_conntrack.h>
18#include <linux/netfilter_ipv4/ip_conntrack_core.h>
19#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
9fb9cbb1
YK
20#else
21#include <net/netfilter/nf_conntrack.h>
22#include <net/netfilter/nf_conntrack_core.h>
23#include <net/netfilter/nf_conntrack_helper.h>
24#endif
1da177e4
LT
25#include <linux/netfilter_ipv4/ip_tables.h>
26#include <linux/netfilter_ipv4/ipt_helper.h>
27
28MODULE_LICENSE("GPL");
29MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>");
30MODULE_DESCRIPTION("iptables helper match module");
31
32#if 0
33#define DEBUGP printk
34#else
35#define DEBUGP(format, args...)
36#endif
37
9fb9cbb1 38#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
1da177e4
LT
39static int
40match(const struct sk_buff *skb,
41 const struct net_device *in,
42 const struct net_device *out,
43 const void *matchinfo,
44 int offset,
45 int *hotdrop)
46{
47 const struct ipt_helper_info *info = matchinfo;
48 struct ip_conntrack *ct;
49 enum ip_conntrack_info ctinfo;
50 int ret = info->invert;
51
52 ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
53 if (!ct) {
54 DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
55 return ret;
56 }
57
58 if (!ct->master) {
59 DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
60 return ret;
61 }
62
e45b1be8 63 read_lock_bh(&ip_conntrack_lock);
1da177e4
LT
64 if (!ct->master->helper) {
65 DEBUGP("ipt_helper: master ct %p has no helper\n",
66 exp->expectant);
67 goto out_unlock;
68 }
69
70 DEBUGP("master's name = %s , info->name = %s\n",
71 ct->master->helper->name, info->name);
72
73 if (info->name[0] == '\0')
74 ret ^= 1;
75 else
76 ret ^= !strncmp(ct->master->helper->name, info->name,
77 strlen(ct->master->helper->name));
78out_unlock:
e45b1be8 79 read_unlock_bh(&ip_conntrack_lock);
1da177e4
LT
80 return ret;
81}
82
9fb9cbb1
YK
83#else /* CONFIG_IP_NF_CONNTRACK */
84
85static int
86match(const struct sk_buff *skb,
87 const struct net_device *in,
88 const struct net_device *out,
89 const void *matchinfo,
90 int offset,
91 int *hotdrop)
92{
93 const struct ipt_helper_info *info = matchinfo;
94 struct nf_conn *ct;
95 enum ip_conntrack_info ctinfo;
96 int ret = info->invert;
97
98 ct = nf_ct_get((struct sk_buff *)skb, &ctinfo);
99 if (!ct) {
100 DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
101 return ret;
102 }
103
104 if (!ct->master) {
105 DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
106 return ret;
107 }
108
109 read_lock_bh(&nf_conntrack_lock);
110 if (!ct->master->helper) {
111 DEBUGP("ipt_helper: master ct %p has no helper\n",
112 exp->expectant);
113 goto out_unlock;
114 }
115
116 DEBUGP("master's name = %s , info->name = %s\n",
117 ct->master->helper->name, info->name);
118
119 if (info->name[0] == '\0')
120 ret ^= 1;
121 else
122 ret ^= !strncmp(ct->master->helper->name, info->name,
123 strlen(ct->master->helper->name));
124out_unlock:
125 read_unlock_bh(&nf_conntrack_lock);
126 return ret;
127}
128#endif
129
1da177e4
LT
130static int check(const char *tablename,
131 const struct ipt_ip *ip,
132 void *matchinfo,
133 unsigned int matchsize,
134 unsigned int hook_mask)
135{
136 struct ipt_helper_info *info = matchinfo;
137
138 info->name[29] = '\0';
139
140 /* verify size */
141 if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info)))
142 return 0;
143
144 return 1;
145}
146
147static struct ipt_match helper_match = {
148 .name = "helper",
149 .match = &match,
150 .checkentry = &check,
151 .me = THIS_MODULE,
152};
153
154static int __init init(void)
155{
156 need_ip_conntrack();
157 return ipt_register_match(&helper_match);
158}
159
160static void __exit fini(void)
161{
162 ipt_unregister_match(&helper_match);
163}
164
165module_init(init);
166module_exit(fini);
167