]> err.no Git - linux-2.6/blob - net/ipv4/netfilter/ipt_helper.c
[INET_SOCK]: Move struct inet_sock & helper functions to net/inet_sock.h
[linux-2.6] / net / ipv4 / netfilter / ipt_helper.c
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>
16 #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
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>
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
25 #include <linux/netfilter_ipv4/ip_tables.h>
26 #include <linux/netfilter_ipv4/ipt_helper.h>
27
28 MODULE_LICENSE("GPL");
29 MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>");
30 MODULE_DESCRIPTION("iptables helper match module");
31
32 #if 0
33 #define DEBUGP printk
34 #else
35 #define DEBUGP(format, args...)
36 #endif
37
38 #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
39 static int
40 match(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
63         read_lock_bh(&ip_conntrack_lock);
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));
78 out_unlock:
79         read_unlock_bh(&ip_conntrack_lock);
80         return ret;
81 }
82
83 #else /* CONFIG_IP_NF_CONNTRACK */
84
85 static int
86 match(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));
124 out_unlock:
125         read_unlock_bh(&nf_conntrack_lock);
126         return ret;
127 }
128 #endif
129
130 static 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
147 static struct ipt_match helper_match = {
148         .name           = "helper",
149         .match          = &match,
150         .checkentry     = &check,
151         .me             = THIS_MODULE,
152 };
153
154 static int __init init(void)
155 {
156         need_ip_conntrack();
157         return ipt_register_match(&helper_match);
158 }
159
160 static void __exit fini(void)
161 {
162         ipt_unregister_match(&helper_match);
163 }
164
165 module_init(init);
166 module_exit(fini);
167