1 Index: linux-2.4.35.4/Documentation/Configure.help
2 ===================================================================
3 --- linux-2.4.35.4.orig/Documentation/Configure.help 2007-12-15 05:20:07.880289314 +0100
4 +++ linux-2.4.35.4/Documentation/Configure.help 2007-12-15 05:20:09.280369103 +0100
6 If you want to compile it as a module, say M here and read
7 <file:Documentation/modules.txt>. If unsure, say `N'.
9 +Condition variable match support
10 +CONFIG_IP_NF_MATCH_CONDITION
11 + This option allows you to match firewall rules against condition
12 + variables stored in the /proc/net/ipt_condition directory.
14 + If you want to compile it as a module, say M here and read
15 + Documentation/modules.txt. If unsure, say `N'.
17 conntrack match support
18 CONFIG_IP_NF_MATCH_CONNTRACK
19 This is a general conntrack match module, a superset of the state match.
20 @@ -3354,6 +3362,14 @@
21 If you want to compile it as a module, say M here and read
22 <file:Documentation/modules.txt>. If unsure, say `N'.
24 +Condition variable match support
25 +CONFIG_IP6_NF_MATCH_CONDITION
26 + This option allows you to match firewall rules against condition
27 + variables stored in the /proc/net/ipt_condition directory.
29 + If you want to compile it as a module, say M here and read
30 + Documentation/modules.txt. If unsure, say `N'.
32 Multiple port match support
33 CONFIG_IP6_NF_MATCH_MULTIPORT
34 Multiport matching allows you to match TCP or UDP packets based on
35 Index: linux-2.4.35.4/include/linux/netfilter_ipv4/ipt_condition.h
36 ===================================================================
37 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
38 +++ linux-2.4.35.4/include/linux/netfilter_ipv4/ipt_condition.h 2007-12-15 05:20:09.296370013 +0100
40 +#ifndef __IPT_CONDITION_MATCH__
41 +#define __IPT_CONDITION_MATCH__
43 +#define CONDITION_NAME_LEN 32
45 +struct condition_info {
46 + char name[CONDITION_NAME_LEN];
51 Index: linux-2.4.35.4/include/linux/netfilter_ipv6/ip6t_condition.h
52 ===================================================================
53 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
54 +++ linux-2.4.35.4/include/linux/netfilter_ipv6/ip6t_condition.h 2007-12-15 05:20:09.300370243 +0100
56 +#ifndef __IP6T_CONDITION_MATCH__
57 +#define __IP6T_CONDITION_MATCH__
59 +#define CONDITION6_NAME_LEN 32
61 +struct condition6_info {
62 + char name[CONDITION6_NAME_LEN];
67 Index: linux-2.4.35.4/net/ipv4/netfilter/Config.in
68 ===================================================================
69 --- linux-2.4.35.4.orig/net/ipv4/netfilter/Config.in 2007-12-15 05:20:08.692335591 +0100
70 +++ linux-2.4.35.4/net/ipv4/netfilter/Config.in 2007-12-15 05:20:09.300370243 +0100
72 dep_tristate ' netfilter MARK match support' CONFIG_IP_NF_MATCH_MARK $CONFIG_IP_NF_IPTABLES
73 dep_tristate ' Multiple port match support' CONFIG_IP_NF_MATCH_MULTIPORT $CONFIG_IP_NF_IPTABLES
74 dep_tristate ' TOS match support' CONFIG_IP_NF_MATCH_TOS $CONFIG_IP_NF_IPTABLES
75 + dep_tristate ' condition match support' CONFIG_IP_NF_MATCH_CONDITION $CONFIG_IP_NF_IPTABLES
76 dep_tristate ' recent match support' CONFIG_IP_NF_MATCH_RECENT $CONFIG_IP_NF_IPTABLES
77 dep_tristate ' ECN match support' CONFIG_IP_NF_MATCH_ECN $CONFIG_IP_NF_IPTABLES
78 dep_tristate ' peer to peer traffic match support' CONFIG_IP_NF_MATCH_IPP2P $CONFIG_IP_NF_IPTABLES
79 Index: linux-2.4.35.4/net/ipv4/netfilter/Makefile
80 ===================================================================
81 --- linux-2.4.35.4.orig/net/ipv4/netfilter/Makefile 2007-12-15 05:20:08.696335817 +0100
82 +++ linux-2.4.35.4/net/ipv4/netfilter/Makefile 2007-12-15 05:20:09.300370243 +0100
84 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
85 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
86 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
87 +obj-$(CONFIG_IP_NF_MATCH_CONDITION) += ipt_condition.o
89 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
91 Index: linux-2.4.35.4/net/ipv4/netfilter/ipt_condition.c
92 ===================================================================
93 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
94 +++ linux-2.4.35.4/net/ipv4/netfilter/ipt_condition.c 2007-12-15 05:20:09.300370243 +0100
96 +/*-------------------------------------------*\
97 +| Netfilter Condition Module |
99 +| Description: This module allows firewall |
100 +| rules to match using condition variables |
101 +| stored in /proc files. |
103 +| Author: Stephane Ouellette 2002-10-22 |
104 +| <ouellettes@videotron.ca> |
107 +| 2003-02-10 Second version with improved |
108 +| locking and simplified code. |
110 +| This software is distributed under the |
111 +| terms of the GNU GPL. |
112 +\*-------------------------------------------*/
114 +#include<linux/module.h>
115 +#include<linux/proc_fs.h>
116 +#include<linux/spinlock.h>
117 +#include<linux/string.h>
118 +#include<asm/atomic.h>
119 +#include<linux/netfilter_ipv4/ip_tables.h>
120 +#include<linux/netfilter_ipv4/ipt_condition.h>
123 +#ifndef CONFIG_PROC_FS
124 +#error "Proc file system support is required for this module"
128 +MODULE_AUTHOR("Stephane Ouellette <ouellettes@videotron.ca>");
129 +MODULE_DESCRIPTION("Allows rules to match against condition variables");
130 +MODULE_LICENSE("GPL");
133 +struct condition_variable {
134 + struct condition_variable *next;
135 + struct proc_dir_entry *status_proc;
137 + int enabled; /* TRUE == 1, FALSE == 0 */
141 +static rwlock_t list_lock;
142 +static struct condition_variable *head = NULL;
143 +static struct proc_dir_entry *proc_net_condition = NULL;
147 +ipt_condition_read_info(char *buffer, char **start, off_t offset,
148 + int length, int *eof, void *data)
150 + struct condition_variable *var =
151 + (struct condition_variable *) data;
155 + buffer[0] = (var->enabled) ? '1' : '0';
166 +ipt_condition_write_info(struct file *file, const char *buffer,
167 + unsigned long length, void *data)
169 + struct condition_variable *var =
170 + (struct condition_variable *) data;
173 + /* Match only on the first character */
174 + switch (buffer[0]) {
183 + return (int) length;
188 +match(const struct sk_buff *skb, const struct net_device *in,
189 + const struct net_device *out, const void *matchinfo, int offset,
190 + const void *hdr, u_int16_t datalen, int *hotdrop)
192 + const struct condition_info *info =
193 + (const struct condition_info *) matchinfo;
194 + struct condition_variable *var;
195 + int condition_status = 0;
197 + read_lock(&list_lock);
199 + for (var = head; var; var = var->next) {
200 + if (strcmp(info->name, var->status_proc->name) == 0) {
201 + condition_status = var->enabled;
206 + read_unlock(&list_lock);
208 + return condition_status ^ info->invert;
214 +checkentry(const char *tablename, const struct ipt_ip *ip,
215 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
217 + struct condition_info *info = (struct condition_info *) matchinfo;
218 + struct condition_variable *var, *newvar;
220 + if (matchsize != IPT_ALIGN(sizeof(struct condition_info)))
223 + /* The first step is to check if the condition variable already exists. */
224 + /* Here, a read lock is sufficient because we won't change the list */
225 + read_lock(&list_lock);
227 + for (var = head; var; var = var->next) {
228 + if (strcmp(info->name, var->status_proc->name) == 0) {
229 + atomic_inc(&var->refcount);
230 + read_unlock(&list_lock);
235 + read_unlock(&list_lock);
237 + /* At this point, we need to allocate a new condition variable */
238 + newvar = kmalloc(sizeof(struct condition_variable), GFP_KERNEL);
243 + /* Create the condition variable's proc file entry */
244 + newvar->status_proc = create_proc_entry(info->name, 0644, proc_net_condition);
246 + if (!newvar->status_proc) {
248 + * There are two possibilities:
249 + * 1- Another condition variable with the same name has been created, which is valid.
250 + * 2- There was a memory allocation error.
253 + read_lock(&list_lock);
255 + for (var = head; var; var = var->next) {
256 + if (strcmp(info->name, var->status_proc->name) == 0) {
257 + atomic_inc(&var->refcount);
258 + read_unlock(&list_lock);
263 + read_unlock(&list_lock);
267 + atomic_set(&newvar->refcount, 1);
268 + newvar->enabled = 0;
269 + newvar->status_proc->owner = THIS_MODULE;
270 + newvar->status_proc->data = newvar;
272 + newvar->status_proc->read_proc = ipt_condition_read_info;
273 + newvar->status_proc->write_proc = ipt_condition_write_info;
275 + write_lock(&list_lock);
277 + newvar->next = head;
280 + write_unlock(&list_lock);
287 +destroy(void *matchinfo, unsigned int matchsize)
289 + struct condition_info *info = (struct condition_info *) matchinfo;
290 + struct condition_variable *var, *prev = NULL;
292 + if (matchsize != IPT_ALIGN(sizeof(struct condition_info)))
295 + write_lock(&list_lock);
297 + for (var = head; var && strcmp(info->name, var->status_proc->name);
298 + prev = var, var = var->next);
300 + if (var && atomic_dec_and_test(&var->refcount)) {
302 + prev->next = var->next;
306 + write_unlock(&list_lock);
307 + remove_proc_entry(var->status_proc->name, proc_net_condition);
310 + write_unlock(&list_lock);
314 +static struct ipt_match condition_match = {
315 + .name = "condition",
317 + .checkentry = &checkentry,
318 + .destroy = &destroy,
328 + rwlock_init(&list_lock);
329 + proc_net_condition = proc_mkdir("ipt_condition", proc_net);
331 + if (proc_net_condition) {
332 + errorcode = ipt_register_match(&condition_match);
335 + remove_proc_entry("ipt_condition", proc_net);
337 + errorcode = -EACCES;
346 + ipt_unregister_match(&condition_match);
347 + remove_proc_entry("ipt_condition", proc_net);
352 Index: linux-2.4.35.4/net/ipv6/netfilter/Config.in
353 ===================================================================
354 --- linux-2.4.35.4.orig/net/ipv6/netfilter/Config.in 2007-12-15 05:19:37.590563202 +0100
355 +++ linux-2.4.35.4/net/ipv6/netfilter/Config.in 2007-12-15 05:20:09.300370243 +0100
357 if [ "$CONFIG_IP6_NF_IPTABLES" != "n" ]; then
358 # The simple matches.
359 dep_tristate ' limit match support' CONFIG_IP6_NF_MATCH_LIMIT $CONFIG_IP6_NF_IPTABLES
360 + dep_tristate ' condition match support' CONFIG_IP6_NF_MATCH_CONDITION $CONFIG_IP6_NF_IPTABLES
361 dep_tristate ' MAC address match support' CONFIG_IP6_NF_MATCH_MAC $CONFIG_IP6_NF_IPTABLES
362 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
363 dep_tristate ' Routing header match support (EXPERIMENTAL)' CONFIG_IP6_NF_MATCH_RT $CONFIG_IP6_NF_IPTABLES
364 Index: linux-2.4.35.4/net/ipv6/netfilter/Makefile
365 ===================================================================
366 --- linux-2.4.35.4.orig/net/ipv6/netfilter/Makefile 2007-12-15 05:19:37.598563658 +0100
367 +++ linux-2.4.35.4/net/ipv6/netfilter/Makefile 2007-12-15 05:20:09.304370470 +0100
369 # Link order matters here.
370 obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
371 obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o
372 +obj-$(CONFIG_IP6_NF_MATCH_CONDITION) += ip6t_condition.o
373 obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
374 obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
375 obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
376 Index: linux-2.4.35.4/net/ipv6/netfilter/ip6t_condition.c
377 ===================================================================
378 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
379 +++ linux-2.4.35.4/net/ipv6/netfilter/ip6t_condition.c 2007-12-15 05:20:09.304370470 +0100
381 +/*-------------------------------------------*\
382 +| Netfilter Condition Module for IPv6 |
384 +| Description: This module allows firewall |
385 +| rules to match using condition variables |
386 +| stored in /proc files. |
388 +| Author: Stephane Ouellette 2003-02-10 |
389 +| <ouellettes@videotron.ca> |
391 +| This software is distributed under the |
392 +| terms of the GNU GPL. |
393 +\*-------------------------------------------*/
395 +#include<linux/module.h>
396 +#include<linux/proc_fs.h>
397 +#include<linux/spinlock.h>
398 +#include<linux/string.h>
399 +#include<asm/atomic.h>
400 +#include<linux/netfilter_ipv6/ip6_tables.h>
401 +#include<linux/netfilter_ipv6/ip6t_condition.h>
404 +#ifndef CONFIG_PROC_FS
405 +#error "Proc file system support is required for this module"
409 +MODULE_AUTHOR("Stephane Ouellette <ouellettes@videotron.ca>");
410 +MODULE_DESCRIPTION("Allows rules to match against condition variables");
411 +MODULE_LICENSE("GPL");
414 +struct condition_variable {
415 + struct condition_variable *next;
416 + struct proc_dir_entry *status_proc;
418 + int enabled; /* TRUE == 1, FALSE == 0 */
422 +static rwlock_t list_lock;
423 +static struct condition_variable *head = NULL;
424 +static struct proc_dir_entry *proc_net_condition = NULL;
428 +ipt_condition_read_info(char *buffer, char **start, off_t offset,
429 + int length, int *eof, void *data)
431 + struct condition_variable *var =
432 + (struct condition_variable *) data;
436 + buffer[0] = (var->enabled) ? '1' : '0';
447 +ipt_condition_write_info(struct file *file, const char *buffer,
448 + unsigned long length, void *data)
450 + struct condition_variable *var =
451 + (struct condition_variable *) data;
454 + /* Match only on the first character */
455 + switch (buffer[0]) {
464 + return (int) length;
469 +match(const struct sk_buff *skb, const struct net_device *in,
470 + const struct net_device *out, const void *matchinfo, int offset,
471 + const void *hdr, u_int16_t datalen, int *hotdrop)
473 + const struct condition6_info *info =
474 + (const struct condition6_info *) matchinfo;
475 + struct condition_variable *var;
476 + int condition_status = 0;
478 + read_lock(&list_lock);
480 + for (var = head; var; var = var->next) {
481 + if (strcmp(info->name, var->status_proc->name) == 0) {
482 + condition_status = var->enabled;
487 + read_unlock(&list_lock);
489 + return condition_status ^ info->invert;
495 +checkentry(const char *tablename, const struct ip6t_ip6 *ip,
496 + void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
498 + struct condition6_info *info =
499 + (struct condition6_info *) matchinfo;
500 + struct condition_variable *var, *newvar;
502 + if (matchsize != IP6T_ALIGN(sizeof(struct condition6_info)))
505 + /* The first step is to check if the condition variable already exists. */
506 + /* Here, a read lock is sufficient because we won't change the list */
507 + read_lock(&list_lock);
509 + for (var = head; var; var = var->next) {
510 + if (strcmp(info->name, var->status_proc->name) == 0) {
511 + atomic_inc(&var->refcount);
512 + read_unlock(&list_lock);
517 + read_unlock(&list_lock);
519 + /* At this point, we need to allocate a new condition variable */
520 + newvar = kmalloc(sizeof(struct condition_variable), GFP_KERNEL);
525 + /* Create the condition variable's proc file entry */
526 + newvar->status_proc = create_proc_entry(info->name, 0644, proc_net_condition);
528 + if (!newvar->status_proc) {
530 + * There are two possibilities:
531 + * 1- Another condition variable with the same name has been created, which is valid.
532 + * 2- There was a memory allocation error.
535 + read_lock(&list_lock);
537 + for (var = head; var; var = var->next) {
538 + if (strcmp(info->name, var->status_proc->name) == 0) {
539 + atomic_inc(&var->refcount);
540 + read_unlock(&list_lock);
545 + read_unlock(&list_lock);
549 + atomic_set(&newvar->refcount, 1);
550 + newvar->enabled = 0;
551 + newvar->status_proc->owner = THIS_MODULE;
552 + newvar->status_proc->data = newvar;
554 + newvar->status_proc->read_proc = ipt_condition_read_info;
555 + newvar->status_proc->write_proc = ipt_condition_write_info;
557 + write_lock(&list_lock);
559 + newvar->next = head;
562 + write_unlock(&list_lock);
569 +destroy(void *matchinfo, unsigned int matchsize)
571 + struct condition6_info *info =
572 + (struct condition6_info *) matchinfo;
573 + struct condition_variable *var, *prev = NULL;
575 + if (matchsize != IP6T_ALIGN(sizeof(struct condition6_info)))
578 + write_lock(&list_lock);
580 + for (var = head; var && strcmp(info->name, var->status_proc->name);
581 + prev = var, var = var->next);
583 + if (var && atomic_dec_and_test(&var->refcount)) {
585 + prev->next = var->next;
589 + write_unlock(&list_lock);
590 + remove_proc_entry(var->status_proc->name, proc_net_condition);
593 + write_unlock(&list_lock);
597 +static struct ip6t_match condition_match = {
598 + .name = "condition",
600 + .checkentry = &checkentry,
601 + .destroy = &destroy,
611 + rwlock_init(&list_lock);
612 + proc_net_condition = proc_mkdir("ip6t_condition", proc_net);
614 + if (proc_net_condition) {
615 + errorcode = ipt_register_match(&condition_match);
618 + remove_proc_entry("ip6t_condition", proc_net);
620 + errorcode = -EACCES;
629 + ipt_unregister_match(&condition_match);
630 + remove_proc_entry("ip6t_condition", proc_net);