GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / net / ipv4 / netfilter / lfp.c
blob94075dde99823b28f8247d7dd9870d1c3da97646
1 /*
2 * Packet matching code.
4 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
5 * Copyright (C) 2009-2002 Netfilter core team <coreteam@netfilter.org>
7 * 19 Jan 2002 Harald Welte <laforge@gnumonks.org>
8 * - increase module usage count as soon as we have rules inside
9 * a table
11 #include <linux/cache.h>
12 #include <linux/skbuff.h>
13 #include <linux/kmod.h>
14 #include <linux/vmalloc.h>
15 #include <linux/netdevice.h>
16 #include <linux/module.h>
17 #include <linux/ip.h>
18 #include <linux/tcp.h>
19 #include <net/route.h>
20 #include <net/ip.h>
21 #include <linux/netfilter.h>
22 #include <linux/netfilter_ipv4.h>
23 #include <net/netfilter/nf_nat_core.h>
24 #include <net/netfilter/nf_conntrack.h>
25 #include <net/netfilter/nf_conntrack_core.h>
26 #include <linux/netfilter/nf_conntrack_common.h>
27 #include <linux/netfilter_ipv4/ip_tables.h>
28 #include <linux/proc_fs.h>
30 #define LFP_DEBUG 0
32 #if LFP_DEBUG
33 #define DEBUGP(format, args...) printk(KERN_DEBUG format, ##args)
34 #else
35 #define DEBUGP(format, args...)
36 #endif
38 unsigned int lfp_ip=0;
40 struct lfp_port_s {
41 unsigned int port;
44 #define NR_STATIC_LFP_PORTS 2
45 #define NR_DYNAMIC_LFP_PORTS 5
46 #define NR_ALL_LFP_PORTS (NR_STATIC_LFP_PORTS + NR_DYNAMIC_LFP_PORTS)
47 static struct lfp_port_s lfp_ports[NR_ALL_LFP_PORTS] = {
48 [0] = { 445 },
49 [1] = { 20 },
51 static int next_slot = NR_STATIC_LFP_PORTS;
53 #define NFC_LFP_ENABLE (1<<29)
55 typedef int (*lfpHitHook)(int pf, unsigned int hook, struct sk_buff *skb);
56 lfpHitHook lfp_hit_hook = NULL;
58 static inline int lfp_hit_hook_func(lfpHitHook hook_func)
60 lfp_hit_hook = hook_func;
61 return 0;
64 static inline int lfp_func(int pf, unsigned int hook, struct sk_buff *skb)
66 int i, ret = 0;
67 struct iphdr *iph;
68 struct tcphdr *tcph;
69 struct lfp_port_s *p;
70 __u32 ipaddr=0, r_ipaddr=0;
71 __u16 port=0;
73 if(lfp_ip == 0 || pf != AF_INET) return 0;
74 if(skb->nfcache & NFC_LFP_ENABLE) return 1;
76 iph = ip_hdr(skb);
77 if (unlikely(iph->protocol != IPPROTO_TCP))
78 return 0;
80 if (hook == NF_INET_PRE_ROUTING || hook == NF_INET_LOCAL_IN) {
81 tcph = (struct tcphdr *)(skb->data+(iph->ihl<<2));
83 ipaddr = iph->daddr;
84 r_ipaddr = iph->saddr;
85 port = ntohs(tcph->dest);
86 } else if (hook == NF_INET_LOCAL_OUT || hook == NF_INET_POST_ROUTING) {
87 tcph = (struct tcphdr *)(skb->data+(iph->ihl<<2));
89 ipaddr = iph->saddr;
90 r_ipaddr = iph->daddr;
91 port = ntohs(tcph->source);
94 if (likely(ipaddr != lfp_ip || !ipaddr))
95 return 0;
97 DEBUGP("ip match: %x %x %x %x\n", hook, ipaddr, r_ipaddr, lfp_ip);
98 for (i = 0, p = &lfp_ports[0]; i < NR_ALL_LFP_PORTS; ++i, ++p) {
99 if (!p->port)
100 continue;
102 if (port == p->port) {
103 skb->nfcache |= NFC_LFP_ENABLE;
104 ret = 1;
105 break;
109 return ret;
112 #ifdef CONFIG_PROC_FS
113 static int lfp_ctrl(struct file *file, const char *buffer, unsigned long length, void *data)
115 char s[10];
117 if ((length > 0) && (length < 10)) {
118 memcpy(s, buffer, length);
119 s[length] = 0;
120 lfp_ip = simple_strtoul(s, NULL, 16);
122 else lfp_ip=0;
124 if(lfp_ip==0) lfp_hit_hook_func (NULL);
125 else lfp_hit_hook_func(lfp_func);
127 return length;
130 static int lfp_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
132 sprintf(page, "%x,%p,%d\n", lfp_ip, lfp_hit_hook, LFP_DEBUG);
133 *eof = 1;
134 return strlen(page);
137 /* Add port to LFP ports list
138 * @return:
139 * 0: Add port to empty slot success.
140 * 1: Override port to an exist port.
141 * 2: Same port exist
142 * -1: Invalid port number.
144 int lfp_add_port(unsigned int port)
146 int i, ret = 0;
147 struct lfp_port_s *p;
149 if (!port || port > 65535)
150 return -1;
152 for (i = 0, p = &lfp_ports[0]; i < NR_ALL_LFP_PORTS; ++i, ++p) {
153 if (!p->port || p->port != port)
154 continue;
156 return 2;
159 /* find empty slot */
160 for (i = 0, p = &lfp_ports[NR_STATIC_LFP_PORTS]; i < NR_DYNAMIC_LFP_PORTS; ++i, ++p) {
161 if (p->port)
162 continue;
164 p->port = port;
165 DEBUGP("Add port %d to LFP port list\n", port);
166 return 0;
169 if (next_slot < NR_STATIC_LFP_PORTS || next_slot >= NR_ALL_LFP_PORTS)
170 next_slot = NR_STATIC_LFP_PORTS;
172 p = &lfp_ports[next_slot];
173 if (p->port) {
174 DEBUGP("Override port %d with %d\n", p->port, port);
175 ret = 1;
177 p->port = port;
178 next_slot++;
180 return ret;
183 /* Remove port from dynamic LFP ports list.
184 * @return:
185 * 0: Remove port success.
186 * 1: Port not found.
187 * -1: Invalid port number.
189 int lfp_del_port(unsigned int port)
191 int i;
192 struct lfp_port_s *p;
194 if (!port || port > 65535)
195 return -1;
197 for (i = 0, p = &lfp_ports[NR_STATIC_LFP_PORTS]; i < NR_DYNAMIC_LFP_PORTS; ++i, ++p) {
198 if (!p->port || p->port != port)
199 continue;
201 p->port = 0;
202 DEBUGP("Remove port %d from LFP port list\n", port);
203 return 0;
206 return 1;
209 /* Query port in LFP ports list
210 * @return:
211 * 0: Not found
212 * 1: found
213 * -1: Invalid port number.
215 int lfp_query_port(unsigned int port)
217 int i;
218 struct lfp_port_s *p;
220 if (!port || port > 65535)
221 return -1;
223 for (i = 0, p = &lfp_ports[NR_STATIC_LFP_PORTS]; i < NR_DYNAMIC_LFP_PORTS; ++i, ++p) {
224 if (port != p->port)
225 continue;
227 DEBUGP("Port %d found in LFP port list\n", port);
228 return 1;
231 return 0;
234 static int lfp_port_write_proc(struct file *file, const char *buffer, unsigned long length, void *data)
236 unsigned int port = 0;
238 port = simple_strtoul(buffer, NULL, 10);
239 lfp_add_port(port);
241 return length;
244 static int lfp_port_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
246 int i, len = 0, c = 0;
247 struct lfp_port_s *p;
249 if (next_slot < NR_STATIC_LFP_PORTS || next_slot >= NR_ALL_LFP_PORTS)
250 next_slot = NR_STATIC_LFP_PORTS;
252 for (i = 0, p = &lfp_ports[NR_STATIC_LFP_PORTS]; !c && i < NR_DYNAMIC_LFP_PORTS; ++i, ++p) {
253 if (!p->port)
254 c++;
257 for (i = NR_STATIC_LFP_PORTS, p = &lfp_ports[NR_STATIC_LFP_PORTS]; i < NR_ALL_LFP_PORTS; ++i, ++p) {
258 if (!p->port)
259 continue;
261 len += sprintf(page + len, "%d%c\n", p->port, (c || i != next_slot)?' ':'*');
264 *eof = 1;
265 return len;
267 #endif /* CONFIG_PROC_FS */
269 static int __init init(void)
271 #ifdef CONFIG_PROC_FS
272 struct proc_dir_entry *p;
274 p = create_proc_entry("lfpctrl", 0600, init_net.proc_net);
276 if (p) {
277 p->read_proc = lfp_read_proc;
278 p->write_proc = lfp_ctrl;
281 p = create_proc_entry("lfp_ports_ctrl", 0600, init_net.proc_net);
282 if (p) {
283 p->read_proc = lfp_port_read_proc;
284 p->write_proc = lfp_port_write_proc;
286 #endif
287 // it will be enabled later
288 lfp_hit_hook_func (NULL);
289 return 0;
292 static void __exit fini(void)
294 lfp_hit_hook_func (NULL);
296 #ifdef CONFIG_PROC_FS
297 remove_proc_entry("lfp_ports_ctrl", init_net.proc_net);
298 remove_proc_entry("lfpctrl", init_net.proc_net);
299 #endif
302 module_init(init);
303 module_exit(fini);
304 MODULE_LICENSE("Proprietary");