mirror of https://github.com/hak5/openwrt.git
add condition, connbytes, string and quota netfilter modules
SVN-Revision: 2478lede-17.01
parent
e62d353cbe
commit
ad5a52c6f0
|
@ -343,11 +343,14 @@ CONFIG_IP_NF_FTP=y
|
||||||
CONFIG_IP_NF_AMANDA=m
|
CONFIG_IP_NF_AMANDA=m
|
||||||
CONFIG_IP_NF_TFTP=m
|
CONFIG_IP_NF_TFTP=m
|
||||||
CONFIG_IP_NF_IRC=y
|
CONFIG_IP_NF_IRC=y
|
||||||
|
CONFIG_IP_NF_CT_ACCT=m
|
||||||
|
CONFIG_IP_NF_MATCH_CONNBYTES=m
|
||||||
CONFIG_IP_NF_CT_PROTO_GRE=m
|
CONFIG_IP_NF_CT_PROTO_GRE=m
|
||||||
CONFIG_IP_NF_PPTP=m
|
CONFIG_IP_NF_PPTP=m
|
||||||
CONFIG_IP_NF_QUEUE=m
|
CONFIG_IP_NF_QUEUE=m
|
||||||
CONFIG_IP_NF_IPTABLES=y
|
CONFIG_IP_NF_IPTABLES=y
|
||||||
CONFIG_IP_NF_MATCH_LIMIT=m
|
CONFIG_IP_NF_MATCH_LIMIT=m
|
||||||
|
CONFIG_IP_NF_MATCH_QUOTA=m
|
||||||
CONFIG_IP_NF_SET=m
|
CONFIG_IP_NF_SET=m
|
||||||
CONFIG_IP_NF_SET_MAX=256
|
CONFIG_IP_NF_SET_MAX=256
|
||||||
CONFIG_IP_NF_SET_HASHSIZE=1024
|
CONFIG_IP_NF_SET_HASHSIZE=1024
|
||||||
|
@ -364,6 +367,7 @@ CONFIG_IP_NF_MATCH_PKTTYPE=m
|
||||||
CONFIG_IP_NF_MATCH_MARK=y
|
CONFIG_IP_NF_MATCH_MARK=y
|
||||||
CONFIG_IP_NF_MATCH_MULTIPORT=y
|
CONFIG_IP_NF_MATCH_MULTIPORT=y
|
||||||
CONFIG_IP_NF_MATCH_TOS=m
|
CONFIG_IP_NF_MATCH_TOS=m
|
||||||
|
CONFIG_IP_NF_MATCH_CONDITION=m
|
||||||
CONFIG_IP_NF_MATCH_RECENT=m
|
CONFIG_IP_NF_MATCH_RECENT=m
|
||||||
CONFIG_IP_NF_MATCH_ECN=m
|
CONFIG_IP_NF_MATCH_ECN=m
|
||||||
CONFIG_IP_NF_MATCH_IPP2P=m
|
CONFIG_IP_NF_MATCH_IPP2P=m
|
||||||
|
@ -377,6 +381,7 @@ CONFIG_IP_NF_MATCH_STATE=y
|
||||||
CONFIG_IP_NF_MATCH_CONNTRACK=m
|
CONFIG_IP_NF_MATCH_CONNTRACK=m
|
||||||
CONFIG_IP_NF_MATCH_CONNMARK=m
|
CONFIG_IP_NF_MATCH_CONNMARK=m
|
||||||
CONFIG_IP_NF_MATCH_UNCLEAN=m
|
CONFIG_IP_NF_MATCH_UNCLEAN=m
|
||||||
|
CONFIG_IP_NF_MATCH_STRING=m
|
||||||
CONFIG_IP_NF_MATCH_OWNER=m
|
CONFIG_IP_NF_MATCH_OWNER=m
|
||||||
CONFIG_IP_NF_MATCH_LAYER7=m
|
CONFIG_IP_NF_MATCH_LAYER7=m
|
||||||
# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set
|
# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set
|
||||||
|
@ -422,6 +427,7 @@ CONFIG_IPV6=m
|
||||||
CONFIG_IP6_NF_QUEUE=m
|
CONFIG_IP6_NF_QUEUE=m
|
||||||
CONFIG_IP6_NF_IPTABLES=m
|
CONFIG_IP6_NF_IPTABLES=m
|
||||||
CONFIG_IP6_NF_MATCH_LIMIT=m
|
CONFIG_IP6_NF_MATCH_LIMIT=m
|
||||||
|
CONFIG_IP6_NF_MATCH_CONDITION=m
|
||||||
CONFIG_IP6_NF_MATCH_MAC=m
|
CONFIG_IP6_NF_MATCH_MAC=m
|
||||||
# CONFIG_IP6_NF_MATCH_RT is not set
|
# CONFIG_IP6_NF_MATCH_RT is not set
|
||||||
# CONFIG_IP6_NF_MATCH_OPTS is not set
|
# CONFIG_IP6_NF_MATCH_OPTS is not set
|
||||||
|
|
|
@ -354,11 +354,14 @@ CONFIG_IP_NF_FTP=y
|
||||||
CONFIG_IP_NF_AMANDA=m
|
CONFIG_IP_NF_AMANDA=m
|
||||||
CONFIG_IP_NF_TFTP=m
|
CONFIG_IP_NF_TFTP=m
|
||||||
CONFIG_IP_NF_IRC=y
|
CONFIG_IP_NF_IRC=y
|
||||||
|
CONFIG_IP_NF_CT_ACCT=m
|
||||||
|
CONFIG_IP_NF_MATCH_CONNBYTES=m
|
||||||
CONFIG_IP_NF_CT_PROTO_GRE=m
|
CONFIG_IP_NF_CT_PROTO_GRE=m
|
||||||
CONFIG_IP_NF_PPTP=m
|
CONFIG_IP_NF_PPTP=m
|
||||||
CONFIG_IP_NF_QUEUE=m
|
CONFIG_IP_NF_QUEUE=m
|
||||||
CONFIG_IP_NF_IPTABLES=y
|
CONFIG_IP_NF_IPTABLES=y
|
||||||
CONFIG_IP_NF_MATCH_LIMIT=m
|
CONFIG_IP_NF_MATCH_LIMIT=m
|
||||||
|
CONFIG_IP_NF_MATCH_QUOTA=m
|
||||||
CONFIG_IP_NF_SET=m
|
CONFIG_IP_NF_SET=m
|
||||||
CONFIG_IP_NF_SET_MAX=256
|
CONFIG_IP_NF_SET_MAX=256
|
||||||
CONFIG_IP_NF_SET_HASHSIZE=1024
|
CONFIG_IP_NF_SET_HASHSIZE=1024
|
||||||
|
@ -375,6 +378,7 @@ CONFIG_IP_NF_MATCH_PKTTYPE=m
|
||||||
CONFIG_IP_NF_MATCH_MARK=y
|
CONFIG_IP_NF_MATCH_MARK=y
|
||||||
CONFIG_IP_NF_MATCH_MULTIPORT=y
|
CONFIG_IP_NF_MATCH_MULTIPORT=y
|
||||||
CONFIG_IP_NF_MATCH_TOS=m
|
CONFIG_IP_NF_MATCH_TOS=m
|
||||||
|
CONFIG_IP_NF_MATCH_CONDITION=m
|
||||||
CONFIG_IP_NF_MATCH_RECENT=m
|
CONFIG_IP_NF_MATCH_RECENT=m
|
||||||
CONFIG_IP_NF_MATCH_ECN=m
|
CONFIG_IP_NF_MATCH_ECN=m
|
||||||
CONFIG_IP_NF_MATCH_IPP2P=m
|
CONFIG_IP_NF_MATCH_IPP2P=m
|
||||||
|
@ -388,6 +392,7 @@ CONFIG_IP_NF_MATCH_STATE=y
|
||||||
CONFIG_IP_NF_MATCH_CONNTRACK=m
|
CONFIG_IP_NF_MATCH_CONNTRACK=m
|
||||||
CONFIG_IP_NF_MATCH_CONNMARK=m
|
CONFIG_IP_NF_MATCH_CONNMARK=m
|
||||||
CONFIG_IP_NF_MATCH_UNCLEAN=m
|
CONFIG_IP_NF_MATCH_UNCLEAN=m
|
||||||
|
CONFIG_IP_NF_MATCH_STRING=m
|
||||||
CONFIG_IP_NF_MATCH_OWNER=m
|
CONFIG_IP_NF_MATCH_OWNER=m
|
||||||
CONFIG_IP_NF_MATCH_LAYER7=m
|
CONFIG_IP_NF_MATCH_LAYER7=m
|
||||||
# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set
|
# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set
|
||||||
|
@ -433,6 +438,7 @@ CONFIG_IPV6=m
|
||||||
CONFIG_IP6_NF_QUEUE=m
|
CONFIG_IP6_NF_QUEUE=m
|
||||||
CONFIG_IP6_NF_IPTABLES=m
|
CONFIG_IP6_NF_IPTABLES=m
|
||||||
CONFIG_IP6_NF_MATCH_LIMIT=m
|
CONFIG_IP6_NF_MATCH_LIMIT=m
|
||||||
|
CONFIG_IP6_NF_MATCH_CONDITION=m
|
||||||
CONFIG_IP6_NF_MATCH_MAC=m
|
CONFIG_IP6_NF_MATCH_MAC=m
|
||||||
# CONFIG_IP6_NF_MATCH_RT is not set
|
# CONFIG_IP6_NF_MATCH_RT is not set
|
||||||
# CONFIG_IP6_NF_MATCH_OPTS is not set
|
# CONFIG_IP6_NF_MATCH_OPTS is not set
|
||||||
|
|
|
@ -282,16 +282,31 @@ CONFIG_IP_NF_FTP=y
|
||||||
CONFIG_IP_NF_AMANDA=m
|
CONFIG_IP_NF_AMANDA=m
|
||||||
CONFIG_IP_NF_TFTP=m
|
CONFIG_IP_NF_TFTP=m
|
||||||
CONFIG_IP_NF_IRC=y
|
CONFIG_IP_NF_IRC=y
|
||||||
|
CONFIG_IP_NF_CT_ACCT=m
|
||||||
|
CONFIG_IP_NF_MATCH_CONNBYTES=m
|
||||||
CONFIG_IP_NF_CT_PROTO_GRE=m
|
CONFIG_IP_NF_CT_PROTO_GRE=m
|
||||||
CONFIG_IP_NF_PPTP=m
|
CONFIG_IP_NF_PPTP=m
|
||||||
CONFIG_IP_NF_QUEUE=m
|
CONFIG_IP_NF_QUEUE=m
|
||||||
CONFIG_IP_NF_IPTABLES=y
|
CONFIG_IP_NF_IPTABLES=y
|
||||||
CONFIG_IP_NF_MATCH_LIMIT=m
|
CONFIG_IP_NF_MATCH_LIMIT=m
|
||||||
|
CONFIG_IP_NF_MATCH_QUOTA=m
|
||||||
|
CONFIG_IP_NF_SET=m
|
||||||
|
CONFIG_IP_NF_SET_MAX=256
|
||||||
|
CONFIG_IP_NF_SET_HASHSIZE=1024
|
||||||
|
CONFIG_IP_NF_MATCH_SET=m
|
||||||
|
CONFIG_IP_NF_TARGET_SET=m
|
||||||
|
CONFIG_IP_NF_SET_IPMAP=m
|
||||||
|
CONFIG_IP_NF_SET_PORTMAP=m
|
||||||
|
CONFIG_IP_NF_SET_MACIPMAP=m
|
||||||
|
CONFIG_IP_NF_SET_IPHASH=m
|
||||||
|
CONFIG_IP_NF_SET_NETHASH=m
|
||||||
|
CONFIG_IP_NF_SET_IPTREE=m
|
||||||
CONFIG_IP_NF_MATCH_MAC=m
|
CONFIG_IP_NF_MATCH_MAC=m
|
||||||
CONFIG_IP_NF_MATCH_PKTTYPE=m
|
CONFIG_IP_NF_MATCH_PKTTYPE=m
|
||||||
CONFIG_IP_NF_MATCH_MARK=y
|
CONFIG_IP_NF_MATCH_MARK=y
|
||||||
CONFIG_IP_NF_MATCH_MULTIPORT=y
|
CONFIG_IP_NF_MATCH_MULTIPORT=y
|
||||||
CONFIG_IP_NF_MATCH_TOS=m
|
CONFIG_IP_NF_MATCH_TOS=m
|
||||||
|
CONFIG_IP_NF_MATCH_CONDITION=m
|
||||||
CONFIG_IP_NF_MATCH_RECENT=m
|
CONFIG_IP_NF_MATCH_RECENT=m
|
||||||
CONFIG_IP_NF_MATCH_ECN=m
|
CONFIG_IP_NF_MATCH_ECN=m
|
||||||
CONFIG_IP_NF_MATCH_IPP2P=m
|
CONFIG_IP_NF_MATCH_IPP2P=m
|
||||||
|
@ -305,6 +320,7 @@ CONFIG_IP_NF_MATCH_STATE=y
|
||||||
CONFIG_IP_NF_MATCH_CONNTRACK=m
|
CONFIG_IP_NF_MATCH_CONNTRACK=m
|
||||||
CONFIG_IP_NF_MATCH_CONNMARK=m
|
CONFIG_IP_NF_MATCH_CONNMARK=m
|
||||||
CONFIG_IP_NF_MATCH_UNCLEAN=m
|
CONFIG_IP_NF_MATCH_UNCLEAN=m
|
||||||
|
CONFIG_IP_NF_MATCH_STRING=m
|
||||||
CONFIG_IP_NF_MATCH_OWNER=m
|
CONFIG_IP_NF_MATCH_OWNER=m
|
||||||
CONFIG_IP_NF_MATCH_LAYER7=m
|
CONFIG_IP_NF_MATCH_LAYER7=m
|
||||||
# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set
|
# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set
|
||||||
|
@ -337,17 +353,6 @@ CONFIG_IP_NF_TARGET_TCPMSS=y
|
||||||
CONFIG_IP_NF_ARPTABLES=m
|
CONFIG_IP_NF_ARPTABLES=m
|
||||||
CONFIG_IP_NF_ARPFILTER=m
|
CONFIG_IP_NF_ARPFILTER=m
|
||||||
CONFIG_IP_NF_ARP_MANGLE=m
|
CONFIG_IP_NF_ARP_MANGLE=m
|
||||||
CONFIG_IP_NF_SET=m
|
|
||||||
CONFIG_IP_NF_SET_MAX=256
|
|
||||||
CONFIG_IP_NF_SET_HASHSIZE=1024
|
|
||||||
CONFIG_IP_NF_MATCH_SET=m
|
|
||||||
CONFIG_IP_NF_TARGET_SET=m
|
|
||||||
CONFIG_IP_NF_SET_IPMAP=m
|
|
||||||
CONFIG_IP_NF_SET_PORTMAP=m
|
|
||||||
CONFIG_IP_NF_SET_MACIPMAP=m
|
|
||||||
CONFIG_IP_NF_SET_IPHASH=m
|
|
||||||
CONFIG_IP_NF_SET_NETHASH=m
|
|
||||||
CONFIG_IP_NF_SET_IPTREE=m
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# IP: Virtual Server Configuration
|
# IP: Virtual Server Configuration
|
||||||
|
@ -361,6 +366,7 @@ CONFIG_IPV6=m
|
||||||
CONFIG_IP6_NF_QUEUE=m
|
CONFIG_IP6_NF_QUEUE=m
|
||||||
CONFIG_IP6_NF_IPTABLES=m
|
CONFIG_IP6_NF_IPTABLES=m
|
||||||
CONFIG_IP6_NF_MATCH_LIMIT=m
|
CONFIG_IP6_NF_MATCH_LIMIT=m
|
||||||
|
CONFIG_IP6_NF_MATCH_CONDITION=m
|
||||||
CONFIG_IP6_NF_MATCH_MAC=m
|
CONFIG_IP6_NF_MATCH_MAC=m
|
||||||
# CONFIG_IP6_NF_MATCH_RT is not set
|
# CONFIG_IP6_NF_MATCH_RT is not set
|
||||||
# CONFIG_IP6_NF_MATCH_OPTS is not set
|
# CONFIG_IP6_NF_MATCH_OPTS is not set
|
||||||
|
|
|
@ -0,0 +1,265 @@
|
||||||
|
--- linux/net/ipv4/netfilter/Config.in.org 2005-11-08 23:11:47.011929664 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/Config.in 2005-11-08 23:10:33.329131152 +0100
|
||||||
|
@@ -50,6 +50,7 @@
|
||||||
|
fi
|
||||||
|
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
|
||||||
|
dep_tristate ' Unclean match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_UNCLEAN $CONFIG_IP_NF_IPTABLES
|
||||||
|
+ dep_tristate ' String match support (EXPERIMENTAL) ' CONFIG_IP_NF_MATCH_STRING $CONFIG_IP_NF_IPTABLES
|
||||||
|
dep_tristate ' Owner match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_OWNER $CONFIG_IP_NF_IPTABLES
|
||||||
|
dep_tristate ' Layer 7 match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_LAYER7 $CONFIG_IP_NF_CONNTRACK
|
||||||
|
dep_mbool ' Layer 7 debugging output (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_LAYER7_DEBUG $CONFIG_IP_NF_MATCH_LAYER7
|
||||||
|
--- linux/net/ipv4/netfilter/Makefile.org 2005-11-08 23:11:57.214378656 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/Makefile 2005-11-08 23:11:20.980886984 +0100
|
||||||
|
@@ -97,6 +97,7 @@
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o
|
||||||
|
+obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o
|
||||||
|
--- linux/net/ipv4/netfilter/ipt_string.c 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/ipt_string.c 2005-11-08 23:08:51.531606728 +0100
|
||||||
|
@@ -0,0 +1,218 @@
|
||||||
|
+/* Kernel module to match a string into a packet.
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 2000 Emmanuel Roger <winfield@freegates.be>
|
||||||
|
+ *
|
||||||
|
+ * ChangeLog
|
||||||
|
+ * 19.02.2002: Gianni Tedesco <gianni@ecsc.co.uk>
|
||||||
|
+ * Fixed SMP re-entrancy problem using per-cpu data areas
|
||||||
|
+ * for the skip/shift tables.
|
||||||
|
+ * 02.05.2001: Gianni Tedesco <gianni@ecsc.co.uk>
|
||||||
|
+ * Fixed kernel panic, due to overrunning boyer moore string
|
||||||
|
+ * tables. Also slightly tweaked heuristic for deciding what
|
||||||
|
+ * search algo to use.
|
||||||
|
+ * 27.01.2001: Gianni Tedesco <gianni@ecsc.co.uk>
|
||||||
|
+ * Implemented Boyer Moore Sublinear search algorithm
|
||||||
|
+ * alongside the existing linear search based on memcmp().
|
||||||
|
+ * Also a quick check to decide which method to use on a per
|
||||||
|
+ * packet basis.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/smp.h>
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/skbuff.h>
|
||||||
|
+#include <linux/file.h>
|
||||||
|
+#include <net/sock.h>
|
||||||
|
+
|
||||||
|
+#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
+#include <linux/netfilter_ipv4/ipt_string.h>
|
||||||
|
+
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+
|
||||||
|
+struct string_per_cpu {
|
||||||
|
+ int *skip;
|
||||||
|
+ int *shift;
|
||||||
|
+ int *len;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct string_per_cpu *bm_string_data=NULL;
|
||||||
|
+
|
||||||
|
+/* Boyer Moore Sublinear string search - VERY FAST */
|
||||||
|
+char *search_sublinear (char *needle, char *haystack, int needle_len, int haystack_len)
|
||||||
|
+{
|
||||||
|
+ int M1, right_end, sk, sh;
|
||||||
|
+ int ended, j, i;
|
||||||
|
+
|
||||||
|
+ int *skip, *shift, *len;
|
||||||
|
+
|
||||||
|
+ /* use data suitable for this CPU */
|
||||||
|
+ shift=bm_string_data[smp_processor_id()].shift;
|
||||||
|
+ skip=bm_string_data[smp_processor_id()].skip;
|
||||||
|
+ len=bm_string_data[smp_processor_id()].len;
|
||||||
|
+
|
||||||
|
+ /* Setup skip/shift tables */
|
||||||
|
+ M1 = right_end = needle_len-1;
|
||||||
|
+ for (i = 0; i < BM_MAX_HLEN; i++) skip[i] = needle_len;
|
||||||
|
+ for (i = 0; needle[i]; i++) skip[needle[i]] = M1 - i;
|
||||||
|
+
|
||||||
|
+ for (i = 1; i < needle_len; i++) {
|
||||||
|
+ for (j = 0; j < needle_len && needle[M1 - j] == needle[M1 - i - j]; j++);
|
||||||
|
+ len[i] = j;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ shift[0] = 1;
|
||||||
|
+ for (i = 1; i < needle_len; i++) shift[i] = needle_len;
|
||||||
|
+ for (i = M1; i > 0; i--) shift[len[i]] = i;
|
||||||
|
+ ended = 0;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < needle_len; i++) {
|
||||||
|
+ if (len[i] == M1 - i) ended = i;
|
||||||
|
+ if (ended) shift[i] = ended;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Do the search*/
|
||||||
|
+ while (right_end < haystack_len)
|
||||||
|
+ {
|
||||||
|
+ for (i = 0; i < needle_len && haystack[right_end - i] == needle[M1 - i]; i++);
|
||||||
|
+ if (i == needle_len) {
|
||||||
|
+ return haystack+(right_end - M1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sk = skip[haystack[right_end - i]];
|
||||||
|
+ sh = shift[i];
|
||||||
|
+ right_end = max(right_end - i + sk, right_end + sh);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Linear string search based on memcmp() */
|
||||||
|
+char *search_linear (char *needle, char *haystack, int needle_len, int haystack_len)
|
||||||
|
+{
|
||||||
|
+ char *k = haystack + (haystack_len-needle_len);
|
||||||
|
+ char *t = haystack;
|
||||||
|
+
|
||||||
|
+ while ( t <= k ) {
|
||||||
|
+ if (memcmp(t, needle, needle_len) == 0)
|
||||||
|
+ return t;
|
||||||
|
+ t++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+match(const struct sk_buff *skb,
|
||||||
|
+ const struct net_device *in,
|
||||||
|
+ const struct net_device *out,
|
||||||
|
+ const void *matchinfo,
|
||||||
|
+ int offset,
|
||||||
|
+ const void *hdr,
|
||||||
|
+ u_int16_t datalen,
|
||||||
|
+ int *hotdrop)
|
||||||
|
+{
|
||||||
|
+ const struct ipt_string_info *info = matchinfo;
|
||||||
|
+ struct iphdr *ip = skb->nh.iph;
|
||||||
|
+ int hlen, nlen;
|
||||||
|
+ char *needle, *haystack;
|
||||||
|
+ proc_ipt_search search=search_linear;
|
||||||
|
+
|
||||||
|
+ if ( !ip ) return 0;
|
||||||
|
+
|
||||||
|
+ /* get lenghts, and validate them */
|
||||||
|
+ nlen=info->len;
|
||||||
|
+ hlen=ntohs(ip->tot_len)-(ip->ihl*4);
|
||||||
|
+ if ( nlen > hlen ) return 0;
|
||||||
|
+
|
||||||
|
+ needle=(char *)&info->string;
|
||||||
|
+ haystack=(char *)ip+(ip->ihl*4);
|
||||||
|
+
|
||||||
|
+ /* The sublinear search comes in to its own
|
||||||
|
+ * on the larger packets */
|
||||||
|
+ if ( (hlen>IPT_STRING_HAYSTACK_THRESH) &&
|
||||||
|
+ (nlen>IPT_STRING_NEEDLE_THRESH) ) {
|
||||||
|
+ if ( hlen < BM_MAX_HLEN ) {
|
||||||
|
+ search=search_sublinear;
|
||||||
|
+ }else{
|
||||||
|
+ if (net_ratelimit())
|
||||||
|
+ printk(KERN_INFO "ipt_string: Packet too big "
|
||||||
|
+ "to attempt sublinear string search "
|
||||||
|
+ "(%d bytes)\n", hlen );
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ((search(needle, haystack, nlen, hlen)!=NULL) ^ info->invert);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+checkentry(const char *tablename,
|
||||||
|
+ const struct ipt_ip *ip,
|
||||||
|
+ void *matchinfo,
|
||||||
|
+ unsigned int matchsize,
|
||||||
|
+ unsigned int hook_mask)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info)))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void string_freeup_data(void)
|
||||||
|
+{
|
||||||
|
+ int c;
|
||||||
|
+
|
||||||
|
+ if ( bm_string_data ) {
|
||||||
|
+ for(c=0; c<smp_num_cpus; c++) {
|
||||||
|
+ if ( bm_string_data[c].shift ) kfree(bm_string_data[c].shift);
|
||||||
|
+ if ( bm_string_data[c].skip ) kfree(bm_string_data[c].skip);
|
||||||
|
+ if ( bm_string_data[c].len ) kfree(bm_string_data[c].len);
|
||||||
|
+ }
|
||||||
|
+ kfree(bm_string_data);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct ipt_match string_match
|
||||||
|
+= { { NULL, NULL }, "string", &match, &checkentry, NULL, THIS_MODULE };
|
||||||
|
+
|
||||||
|
+static int __init init(void)
|
||||||
|
+{
|
||||||
|
+ int c;
|
||||||
|
+ size_t tlen;
|
||||||
|
+ size_t alen;
|
||||||
|
+
|
||||||
|
+ tlen=sizeof(struct string_per_cpu)*smp_num_cpus;
|
||||||
|
+ alen=sizeof(int)*BM_MAX_HLEN;
|
||||||
|
+
|
||||||
|
+ /* allocate array of structures */
|
||||||
|
+ if ( !(bm_string_data=kmalloc(tlen,GFP_KERNEL)) ) {
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memset(bm_string_data, 0, tlen);
|
||||||
|
+
|
||||||
|
+ /* allocate our skip/shift tables */
|
||||||
|
+ for(c=0; c<smp_num_cpus; c++) {
|
||||||
|
+ if ( !(bm_string_data[c].shift=kmalloc(alen, GFP_KERNEL)) )
|
||||||
|
+ goto alloc_fail;
|
||||||
|
+ if ( !(bm_string_data[c].skip=kmalloc(alen, GFP_KERNEL)) )
|
||||||
|
+ goto alloc_fail;
|
||||||
|
+ if ( !(bm_string_data[c].len=kmalloc(alen, GFP_KERNEL)) )
|
||||||
|
+ goto alloc_fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ipt_register_match(&string_match);
|
||||||
|
+
|
||||||
|
+alloc_fail:
|
||||||
|
+ string_freeup_data();
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit fini(void)
|
||||||
|
+{
|
||||||
|
+ ipt_unregister_match(&string_match);
|
||||||
|
+ string_freeup_data();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(init);
|
||||||
|
+module_exit(fini);
|
||||||
|
--- linux/include/linux/netfilter_ipv4/ipt_string.h 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux/include/linux/netfilter_ipv4/ipt_string.h 2005-11-08 23:09:45.219444936 +0100
|
||||||
|
@@ -0,0 +1,21 @@
|
||||||
|
+#ifndef _IPT_STRING_H
|
||||||
|
+#define _IPT_STRING_H
|
||||||
|
+
|
||||||
|
+/* *** PERFORMANCE TWEAK ***
|
||||||
|
+ * Packet size and search string threshold,
|
||||||
|
+ * above which sublinear searches is used. */
|
||||||
|
+#define IPT_STRING_HAYSTACK_THRESH 100
|
||||||
|
+#define IPT_STRING_NEEDLE_THRESH 20
|
||||||
|
+
|
||||||
|
+#define BM_MAX_NLEN 256
|
||||||
|
+#define BM_MAX_HLEN 1024
|
||||||
|
+
|
||||||
|
+typedef char *(*proc_ipt_search) (char *, char *, int, int);
|
||||||
|
+
|
||||||
|
+struct ipt_string_info {
|
||||||
|
+ char string[BM_MAX_NLEN];
|
||||||
|
+ u_int16_t invert;
|
||||||
|
+ u_int16_t len;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif /* _IPT_STRING_H */
|
|
@ -0,0 +1,417 @@
|
||||||
|
--- linux/net/ipv4/netfilter/Config.in.org 2005-11-13 15:53:59.457222512 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/Config.in 2005-11-13 15:56:25.241060000 +0100
|
||||||
|
@@ -11,6 +11,8 @@
|
||||||
|
dep_tristate ' Amanda protocol support' CONFIG_IP_NF_AMANDA $CONFIG_IP_NF_CONNTRACK
|
||||||
|
dep_tristate ' TFTP protocol support' CONFIG_IP_NF_TFTP $CONFIG_IP_NF_CONNTRACK
|
||||||
|
dep_tristate ' IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK
|
||||||
|
+ dep_tristate ' Connection tracking flow accounting' CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK
|
||||||
|
+ dep_tristate ' Connection byte counter support' CONFIG_IP_NF_MATCH_CONNBYTES $CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES
|
||||||
|
dep_tristate ' GRE protocol support' CONFIG_IP_NF_CT_PROTO_GRE $CONFIG_IP_NF_CONNTRACK
|
||||||
|
dep_tristate ' PPTP protocol support' CONFIG_IP_NF_PPTP $CONFIG_IP_NF_CT_PROTO_GRE
|
||||||
|
fi
|
||||||
|
--- linux/net/ipv4/netfilter/Makefile.org 2005-11-12 16:48:38.000000000 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/Makefile 2005-11-13 15:56:38.663019552 +0100
|
||||||
|
@@ -94,6 +94,7 @@
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
|
||||||
|
+obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
|
||||||
|
--- linux/net/ipv4/netfilter/ip_conntrack_amanda.c.org 2004-02-18 14:36:32.000000000 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/ip_conntrack_amanda.c 2005-11-13 15:40:00.000000000 +0100
|
||||||
|
@@ -75,7 +75,7 @@
|
||||||
|
|
||||||
|
/* increase the UDP timeout of the master connection as replies from
|
||||||
|
* Amanda clients to the server can be quite delayed */
|
||||||
|
- ip_ct_refresh(ct, master_timeout * HZ);
|
||||||
|
+ ip_ct_refresh_acct(ct,ctinfo,NULL, master_timeout * HZ);
|
||||||
|
|
||||||
|
/* Search for "CONNECT " string */
|
||||||
|
do {
|
||||||
|
--- linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c.org 2003-11-28 19:26:21.000000000 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2005-11-13 15:45:41.045992536 +0100
|
||||||
|
@@ -211,7 +211,7 @@
|
||||||
|
set_bit(IPS_ASSURED_BIT, &conntrack->status);
|
||||||
|
|
||||||
|
WRITE_UNLOCK(&tcp_lock);
|
||||||
|
- ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]);
|
||||||
|
+ ip_ct_refresh_acct(conntrack,ctinfo,iph, *tcp_timeouts[newconntrack]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NF_ACCEPT;
|
||||||
|
--- linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c.org 2003-11-28 19:26:21.000000000 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2005-11-13 15:47:38.348159896 +0100
|
||||||
|
@@ -47,16 +47,16 @@
|
||||||
|
/* Returns verdict for packet, and may modify conntracktype */
|
||||||
|
static int udp_packet(struct ip_conntrack *conntrack,
|
||||||
|
struct iphdr *iph, size_t len,
|
||||||
|
- enum ip_conntrack_info conntrackinfo)
|
||||||
|
+ enum ip_conntrack_info ctinfo)
|
||||||
|
{
|
||||||
|
/* If we've seen traffic both ways, this is some kind of UDP
|
||||||
|
stream. Extend timeout. */
|
||||||
|
if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
|
||||||
|
- ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream);
|
||||||
|
+ ip_ct_refresh_acct(conntrack,ctinfo,iph,ip_ct_udp_timeout_stream);
|
||||||
|
/* Also, more likely to be important, and not a probe */
|
||||||
|
set_bit(IPS_ASSURED_BIT, &conntrack->status);
|
||||||
|
} else
|
||||||
|
- ip_ct_refresh(conntrack, ip_ct_udp_timeout);
|
||||||
|
+ ip_ct_refresh_acct(conntrack,ctinfo,iph, ip_ct_udp_timeout);
|
||||||
|
|
||||||
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
--- linux/net/ipv4/netfilter/ip_conntrack_standalone.c.org 2005-11-12 16:48:38.000000000 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/ip_conntrack_standalone.c 2005-11-13 15:51:07.608347512 +0100
|
||||||
|
@@ -79,6 +79,18 @@
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if defined(CONFIG_IP_NF_CT_ACCT) || \
|
||||||
|
+ defined(CONFIG_IP_NF_CT_ACCT_MODULE)
|
||||||
|
+static unsigned int
|
||||||
|
+print_counters(char *buffer, struct ip_conntrack_counter *counter)
|
||||||
|
+{
|
||||||
|
+ return sprintf(buffer, "packets=%llu bytes=%llu ",
|
||||||
|
+ counter->packets, counter->bytes);
|
||||||
|
+}
|
||||||
|
+#else
|
||||||
|
+#define print_counters(x, y) 0
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static unsigned int
|
||||||
|
print_conntrack(char *buffer, struct ip_conntrack *conntrack)
|
||||||
|
{
|
||||||
|
@@ -98,11 +110,15 @@
|
||||||
|
len += print_tuple(buffer + len,
|
||||||
|
&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
|
||||||
|
proto);
|
||||||
|
+ len += print_counters(buffer + len,
|
||||||
|
+ &conntrack->counters[IP_CT_DIR_ORIGINAL]);
|
||||||
|
if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
|
||||||
|
len += sprintf(buffer + len, "[UNREPLIED] ");
|
||||||
|
len += print_tuple(buffer + len,
|
||||||
|
&conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
|
||||||
|
proto);
|
||||||
|
+ len += print_counters(buffer + len,
|
||||||
|
+ &conntrack->counters[IP_CT_DIR_REPLY]);
|
||||||
|
if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
|
||||||
|
len += sprintf(buffer + len, "[ASSURED] ");
|
||||||
|
len += sprintf(buffer + len, "use=%u ",
|
||||||
|
@@ -478,7 +494,7 @@
|
||||||
|
EXPORT_SYMBOL(ip_conntrack_helper_register);
|
||||||
|
EXPORT_SYMBOL(ip_conntrack_helper_unregister);
|
||||||
|
EXPORT_SYMBOL(ip_ct_iterate_cleanup);
|
||||||
|
-EXPORT_SYMBOL(ip_ct_refresh);
|
||||||
|
+EXPORT_SYMBOL(ip_ct_refresh_acct);
|
||||||
|
EXPORT_SYMBOL(ip_ct_find_proto);
|
||||||
|
EXPORT_SYMBOL(__ip_ct_find_proto);
|
||||||
|
EXPORT_SYMBOL(ip_ct_find_helper);
|
||||||
|
--- linux/net/ipv4/netfilter/ip_conntrack_proto_generic.c.org 2003-11-28 19:26:21.000000000 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/ip_conntrack_proto_generic.c 2005-11-13 15:44:20.734201784 +0100
|
||||||
|
@@ -41,9 +41,9 @@
|
||||||
|
/* Returns verdict for packet, or -1 for invalid. */
|
||||||
|
static int established(struct ip_conntrack *conntrack,
|
||||||
|
struct iphdr *iph, size_t len,
|
||||||
|
- enum ip_conntrack_info conntrackinfo)
|
||||||
|
+ enum ip_conntrack_info ctinfo)
|
||||||
|
{
|
||||||
|
- ip_ct_refresh(conntrack, ip_ct_generic_timeout);
|
||||||
|
+ ip_ct_refresh_acct(conntrack, ctinfo,iph,ip_ct_generic_timeout);
|
||||||
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
--- linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c.org 2003-11-28 19:26:21.000000000 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/ip_conntrack_proto_icmp.c 2005-11-13 15:44:50.733641176 +0100
|
||||||
|
@@ -82,7 +82,7 @@
|
||||||
|
ct->timeout.function((unsigned long)ct);
|
||||||
|
} else {
|
||||||
|
atomic_inc(&ct->proto.icmp.count);
|
||||||
|
- ip_ct_refresh(ct, ip_ct_icmp_timeout);
|
||||||
|
+ ip_ct_refresh_acct(ct,ctinfo,iph, ip_ct_icmp_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NF_ACCEPT;
|
||||||
|
--- linux/net/ipv4/netfilter/ip_conntrack_core.c.org 2005-11-12 16:48:38.000000000 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/ip_conntrack_core.c 2005-11-13 15:43:23.882844504 +0100
|
||||||
|
@@ -1196,22 +1196,40 @@
|
||||||
|
|
||||||
|
MOD_DEC_USE_COUNT;
|
||||||
|
}
|
||||||
|
+static inline void ct_add_counters(struct ip_conntrack *ct,
|
||||||
|
+ enum ip_conntrack_info ctinfo,
|
||||||
|
+ const struct iphdr *iph)
|
||||||
|
+{
|
||||||
|
+#if defined(CONFIG_IP_NF_CT_ACCT) || \
|
||||||
|
+ defined(CONFIG_IP_NF_CT_ACCT_MODULE)
|
||||||
|
+ if (iph) {
|
||||||
|
+ ct->counters[CTINFO2DIR(ctinfo)].packets++;
|
||||||
|
+ ct->counters[CTINFO2DIR(ctinfo)].bytes +=
|
||||||
|
+ ntohs(iph->tot_len);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
|
||||||
|
/* Refresh conntrack for this many jiffies. */
|
||||||
|
-void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies)
|
||||||
|
+void ip_ct_refresh_acct(struct ip_conntrack *ct,
|
||||||
|
+ enum ip_conntrack_info ctinfo,
|
||||||
|
+ const struct iphdr *iph,
|
||||||
|
+ unsigned long extra_jiffies)
|
||||||
|
{
|
||||||
|
IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
|
||||||
|
|
||||||
|
WRITE_LOCK(&ip_conntrack_lock);
|
||||||
|
/* If not in hash table, timer will not be active yet */
|
||||||
|
- if (!is_confirmed(ct))
|
||||||
|
+ if (!is_confirmed(ct)) {
|
||||||
|
ct->timeout.expires = extra_jiffies;
|
||||||
|
- else {
|
||||||
|
+ ct_add_counters(ct, ctinfo,iph);
|
||||||
|
+ } else {
|
||||||
|
/* Need del_timer for race avoidance (may already be dying). */
|
||||||
|
if (del_timer(&ct->timeout)) {
|
||||||
|
ct->timeout.expires = jiffies + extra_jiffies;
|
||||||
|
add_timer(&ct->timeout);
|
||||||
|
}
|
||||||
|
+ ct_add_counters(ct, ctinfo, iph);
|
||||||
|
}
|
||||||
|
WRITE_UNLOCK(&ip_conntrack_lock);
|
||||||
|
}
|
||||||
|
--- linux/include/linux/netfilter_ipv4/ip_conntrack.h.org 2005-11-12 16:48:38.000000000 +0100
|
||||||
|
+++ linux/include/linux/netfilter_ipv4/ip_conntrack.h 2005-11-13 15:39:04.000000000 +0100
|
||||||
|
@@ -164,6 +164,12 @@
|
||||||
|
union ip_conntrack_expect_help help;
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct ip_conntrack_counter
|
||||||
|
+{
|
||||||
|
+ u_int64_t packets;
|
||||||
|
+ u_int64_t bytes;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct ip_conntrack_helper;
|
||||||
|
|
||||||
|
struct ip_conntrack
|
||||||
|
@@ -181,6 +187,12 @@
|
||||||
|
/* Timer function; drops refcnt when it goes off. */
|
||||||
|
struct timer_list timeout;
|
||||||
|
|
||||||
|
+#if defined(CONFIG_IP_NF_CT_ACCT) || \
|
||||||
|
+ defined(CONFIG_IP_NF_CT_ACCT_MODULE)
|
||||||
|
+ /* Accounting Information (same cache line as other written members) */
|
||||||
|
+ struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* If we're expecting another related connection, this will be
|
||||||
|
in expected linked list */
|
||||||
|
struct list_head sibling_list;
|
||||||
|
@@ -264,8 +276,10 @@
|
||||||
|
const struct ip_conntrack_tuple *orig);
|
||||||
|
|
||||||
|
/* Refresh conntrack for this many jiffies */
|
||||||
|
-extern void ip_ct_refresh(struct ip_conntrack *ct,
|
||||||
|
- unsigned long extra_jiffies);
|
||||||
|
+extern void ip_ct_refresh_acct(struct ip_conntrack *ct,
|
||||||
|
+ enum ip_conntrack_info ctinfo,
|
||||||
|
+ const struct iphdr *iph,
|
||||||
|
+ unsigned long extra_jiffies);
|
||||||
|
|
||||||
|
/* These are for NAT. Icky. */
|
||||||
|
/* Call me when a conntrack is destroyed. */
|
||||||
|
--- linux/net/ipv4/netfilter/ipt_connbytes.c.org 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux/net/ipv4/netfilter/ipt_connbytes.c 2005-11-13 16:22:02.021433872 +0100
|
||||||
|
@@ -0,0 +1,163 @@
|
||||||
|
+/* Kernel module to match connection tracking byte counter.
|
||||||
|
+ * GPL (C) 2002 Martin Devera (devik@cdi.cz).
|
||||||
|
+ *
|
||||||
|
+ * 2004-07-20 Harald Welte <laforge at netfilter.org>
|
||||||
|
+ * - reimplemented to use per-connection accounting counters
|
||||||
|
+ * - add functionality to match number of packets
|
||||||
|
+ * - add functionality to match average packet size
|
||||||
|
+ * - add support to match directions seperately
|
||||||
|
+ *
|
||||||
|
+ * 2004-10-24 Piotr Chytla <pch at fouk.org>
|
||||||
|
+ * - Connbytes with per-connection accouting backported to 2.4
|
||||||
|
+ *
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/skbuff.h>
|
||||||
|
+#include <linux/types.h>
|
||||||
|
+#include <linux/netfilter_ipv4/ip_conntrack.h>
|
||||||
|
+#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
+#include <linux/netfilter_ipv4/ipt_connbytes.h>
|
||||||
|
+
|
||||||
|
+#include <asm/div64.h>
|
||||||
|
+
|
||||||
|
+static u_int64_t mydiv(u_int64_t arg1,u_int32_t arg2)
|
||||||
|
+{
|
||||||
|
+ do_div(arg1,arg2);
|
||||||
|
+ return arg1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+match(const struct sk_buff *skb,
|
||||||
|
+ const struct net_device *in,
|
||||||
|
+ const struct net_device *out,
|
||||||
|
+ const void *matchinfo,
|
||||||
|
+ int offset,
|
||||||
|
+ const void *hdr,
|
||||||
|
+ u_int16_t datalen,
|
||||||
|
+ int *hotdrop)
|
||||||
|
+{
|
||||||
|
+ static u_int64_t what;
|
||||||
|
+ const struct ipt_connbytes_info *sinfo = matchinfo;
|
||||||
|
+ enum ip_conntrack_info ctinfo;
|
||||||
|
+ struct ip_conntrack *ct;
|
||||||
|
+
|
||||||
|
+ if (!(ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo)))
|
||||||
|
+ return 0; /* no match */
|
||||||
|
+ switch (sinfo->what) {
|
||||||
|
+ case IPT_CONNBYTES_WHAT_PKTS:
|
||||||
|
+ switch (sinfo->direction) {
|
||||||
|
+ case IPT_CONNBYTES_DIR_ORIGINAL:
|
||||||
|
+ what = ct->counters[IP_CT_DIR_ORIGINAL].packets;
|
||||||
|
+ break;
|
||||||
|
+ case IPT_CONNBYTES_DIR_REPLY:
|
||||||
|
+ what = ct->counters[IP_CT_DIR_REPLY].packets;
|
||||||
|
+ break;
|
||||||
|
+ case IPT_CONNBYTES_DIR_BOTH:
|
||||||
|
+ what = ct->counters[IP_CT_DIR_ORIGINAL].packets;
|
||||||
|
+ what += ct->counters[IP_CT_DIR_REPLY].packets;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case IPT_CONNBYTES_WHAT_BYTES:
|
||||||
|
+ switch (sinfo->direction) {
|
||||||
|
+ case IPT_CONNBYTES_DIR_ORIGINAL:
|
||||||
|
+ what = ct->counters[IP_CT_DIR_ORIGINAL].bytes;
|
||||||
|
+ break;
|
||||||
|
+ case IPT_CONNBYTES_DIR_REPLY:
|
||||||
|
+ what = ct->counters[IP_CT_DIR_REPLY].bytes;
|
||||||
|
+ break;
|
||||||
|
+ case IPT_CONNBYTES_DIR_BOTH:
|
||||||
|
+ what = ct->counters[IP_CT_DIR_ORIGINAL].bytes;
|
||||||
|
+ what += ct->counters[IP_CT_DIR_REPLY].bytes;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case IPT_CONNBYTES_WHAT_AVGPKT:
|
||||||
|
+ switch (sinfo->direction) {
|
||||||
|
+ case IPT_CONNBYTES_DIR_ORIGINAL:
|
||||||
|
+ {
|
||||||
|
+ u_int32_t pkts32;
|
||||||
|
+
|
||||||
|
+ if (ct->counters[IP_CT_DIR_ORIGINAL].packets > 0xfffffffff)
|
||||||
|
+ pkts32 = 0xffffffff;
|
||||||
|
+ else
|
||||||
|
+ pkts32 = ct->counters[IP_CT_DIR_ORIGINAL].packets;
|
||||||
|
+ what = mydiv(ct->counters[IP_CT_DIR_ORIGINAL].bytes,pkts32);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case IPT_CONNBYTES_DIR_REPLY:
|
||||||
|
+ {
|
||||||
|
+ u_int32_t pkts32;
|
||||||
|
+
|
||||||
|
+ if (ct->counters[IP_CT_DIR_REPLY].packets > 0xffffffff)
|
||||||
|
+ pkts32 = 0xffffffff;
|
||||||
|
+ else
|
||||||
|
+ pkts32 = ct->counters[IP_CT_DIR_REPLY].packets;
|
||||||
|
+ what = mydiv(ct->counters[IP_CT_DIR_REPLY].bytes,pkts32);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case IPT_CONNBYTES_DIR_BOTH:
|
||||||
|
+ {
|
||||||
|
+ u_int64_t bytes;
|
||||||
|
+ u_int64_t pkts;
|
||||||
|
+ u_int32_t pkts32;
|
||||||
|
+ bytes = ct->counters[IP_CT_DIR_ORIGINAL].bytes +
|
||||||
|
+ ct->counters[IP_CT_DIR_REPLY].bytes;
|
||||||
|
+ pkts = ct->counters[IP_CT_DIR_ORIGINAL].packets +
|
||||||
|
+ ct->counters[IP_CT_DIR_REPLY].packets;
|
||||||
|
+ if (pkts > 0xffffffff)
|
||||||
|
+ pkts32 = 0xffffffff;
|
||||||
|
+ else
|
||||||
|
+ pkts32 = pkts;
|
||||||
|
+ what = mydiv(bytes,pkts);
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (sinfo->count.to)
|
||||||
|
+ return (what <= sinfo->count.to && what >= sinfo->count.from);
|
||||||
|
+ else
|
||||||
|
+ return (what >= sinfo->count.from);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int check(const char *tablename,
|
||||||
|
+ const struct ipt_ip *ip,
|
||||||
|
+ void *matchinfo,
|
||||||
|
+ unsigned int matchsize,
|
||||||
|
+ unsigned int hook_mask)
|
||||||
|
+{
|
||||||
|
+ const struct ipt_connbytes_info *sinfo = matchinfo;
|
||||||
|
+
|
||||||
|
+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info)))
|
||||||
|
+ return 0;
|
||||||
|
+ if (sinfo->what != IPT_CONNBYTES_WHAT_PKTS &&
|
||||||
|
+ sinfo->what != IPT_CONNBYTES_WHAT_BYTES &&
|
||||||
|
+ sinfo->what != IPT_CONNBYTES_WHAT_AVGPKT)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL &&
|
||||||
|
+ sinfo->direction != IPT_CONNBYTES_DIR_REPLY &&
|
||||||
|
+ sinfo->direction != IPT_CONNBYTES_DIR_BOTH)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct ipt_match state_match
|
||||||
|
+= { { NULL, NULL }, "connbytes", &match, &check, NULL, THIS_MODULE };
|
||||||
|
+
|
||||||
|
+static int __init init(void)
|
||||||
|
+{
|
||||||
|
+ return ipt_register_match(&state_match);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit fini(void)
|
||||||
|
+{
|
||||||
|
+ ipt_unregister_match(&state_match);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(init);
|
||||||
|
+module_exit(fini);
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
--- linux/include/linux/netfilter_ipv4/ipt_connbytes.h.org 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux/include/linux/netfilter_ipv4/ipt_connbytes.h 2005-11-13 16:11:24.567341624 +0100
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+#ifndef _IPT_CONNBYTES_H
|
||||||
|
+#define _IPT_CONNBYTES_H
|
||||||
|
+enum ipt_connbytes_what {
|
||||||
|
+ IPT_CONNBYTES_WHAT_PKTS,
|
||||||
|
+ IPT_CONNBYTES_WHAT_BYTES,
|
||||||
|
+ IPT_CONNBYTES_WHAT_AVGPKT,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+enum ipt_connbytes_direction {
|
||||||
|
+ IPT_CONNBYTES_DIR_ORIGINAL,
|
||||||
|
+ IPT_CONNBYTES_DIR_REPLY,
|
||||||
|
+ IPT_CONNBYTES_DIR_BOTH,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+struct ipt_connbytes_info
|
||||||
|
+{
|
||||||
|
+ struct {
|
||||||
|
+ u_int64_t from; /* count to be matched */
|
||||||
|
+ u_int64_t to; /* count to be matched */
|
||||||
|
+ } count;
|
||||||
|
+ u_int8_t what; /* ipt_connbytes_what */
|
||||||
|
+ u_int8_t direction; /* ipt_connbytes_direction */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif
|
|
@ -0,0 +1,625 @@
|
||||||
|
diff -ruN linux-2.4.30-old/Documentation/Configure.help linux-2.4.30-new/Documentation/Configure.help
|
||||||
|
--- linux-2.4.30-old/Documentation/Configure.help 2005-11-13 21:52:27.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/Documentation/Configure.help 2005-11-13 22:20:15.000000000 +0100
|
||||||
|
@@ -2979,6 +2979,14 @@
|
||||||
|
If you want to compile it as a module, say M here and read
|
||||||
|
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||||
|
|
||||||
|
+Condition variable match support
|
||||||
|
+CONFIG_IP_NF_MATCH_CONDITION
|
||||||
|
+ This option allows you to match firewall rules against condition
|
||||||
|
+ variables stored in the /proc/net/ipt_condition directory.
|
||||||
|
+
|
||||||
|
+ If you want to compile it as a module, say M here and read
|
||||||
|
+ Documentation/modules.txt. If unsure, say `N'.
|
||||||
|
+
|
||||||
|
conntrack match support
|
||||||
|
CONFIG_IP_NF_MATCH_CONNTRACK
|
||||||
|
This is a general conntrack match module, a superset of the state match.
|
||||||
|
@@ -3354,6 +3362,14 @@
|
||||||
|
If you want to compile it as a module, say M here and read
|
||||||
|
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||||
|
|
||||||
|
+Condition variable match support
|
||||||
|
+CONFIG_IP6_NF_MATCH_CONDITION
|
||||||
|
+ This option allows you to match firewall rules against condition
|
||||||
|
+ variables stored in the /proc/net/ipt_condition directory.
|
||||||
|
+
|
||||||
|
+ If you want to compile it as a module, say M here and read
|
||||||
|
+ Documentation/modules.txt. If unsure, say `N'.
|
||||||
|
+
|
||||||
|
Multiple port match support
|
||||||
|
CONFIG_IP6_NF_MATCH_MULTIPORT
|
||||||
|
Multiport matching allows you to match TCP or UDP packets based on
|
||||||
|
diff -ruN linux-2.4.30-old/include/linux/netfilter_ipv4/ipt_condition.h linux-2.4.30-new/include/linux/netfilter_ipv4/ipt_condition.h
|
||||||
|
--- linux-2.4.30-old/include/linux/netfilter_ipv4/ipt_condition.h 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/include/linux/netfilter_ipv4/ipt_condition.h 2005-11-13 22:20:14.000000000 +0100
|
||||||
|
@@ -0,0 +1,11 @@
|
||||||
|
+#ifndef __IPT_CONDITION_MATCH__
|
||||||
|
+#define __IPT_CONDITION_MATCH__
|
||||||
|
+
|
||||||
|
+#define CONDITION_NAME_LEN 32
|
||||||
|
+
|
||||||
|
+struct condition_info {
|
||||||
|
+ char name[CONDITION_NAME_LEN];
|
||||||
|
+ int invert;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff -ruN linux-2.4.30-old/include/linux/netfilter_ipv6/ip6t_condition.h linux-2.4.30-new/include/linux/netfilter_ipv6/ip6t_condition.h
|
||||||
|
--- linux-2.4.30-old/include/linux/netfilter_ipv6/ip6t_condition.h 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/include/linux/netfilter_ipv6/ip6t_condition.h 2005-11-13 22:20:14.000000000 +0100
|
||||||
|
@@ -0,0 +1,11 @@
|
||||||
|
+#ifndef __IP6T_CONDITION_MATCH__
|
||||||
|
+#define __IP6T_CONDITION_MATCH__
|
||||||
|
+
|
||||||
|
+#define CONDITION6_NAME_LEN 32
|
||||||
|
+
|
||||||
|
+struct condition6_info {
|
||||||
|
+ char name[CONDITION6_NAME_LEN];
|
||||||
|
+ int invert;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
diff -ruN linux-2.4.30-old/net/ipv4/netfilter/Config.in linux-2.4.30-new/net/ipv4/netfilter/Config.in
|
||||||
|
--- linux-2.4.30-old/net/ipv4/netfilter/Config.in 2005-11-13 21:52:27.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/net/ipv4/netfilter/Config.in 2005-11-13 22:20:15.000000000 +0100
|
||||||
|
@@ -43,6 +43,7 @@
|
||||||
|
dep_tristate ' netfilter MARK match support' CONFIG_IP_NF_MATCH_MARK $CONFIG_IP_NF_IPTABLES
|
||||||
|
dep_tristate ' Multiple port match support' CONFIG_IP_NF_MATCH_MULTIPORT $CONFIG_IP_NF_IPTABLES
|
||||||
|
dep_tristate ' TOS match support' CONFIG_IP_NF_MATCH_TOS $CONFIG_IP_NF_IPTABLES
|
||||||
|
+ dep_tristate ' condition match support' CONFIG_IP_NF_MATCH_CONDITION $CONFIG_IP_NF_IPTABLES
|
||||||
|
dep_tristate ' recent match support' CONFIG_IP_NF_MATCH_RECENT $CONFIG_IP_NF_IPTABLES
|
||||||
|
dep_tristate ' ECN match support' CONFIG_IP_NF_MATCH_ECN $CONFIG_IP_NF_IPTABLES
|
||||||
|
dep_tristate ' peer to peer traffic match support' CONFIG_IP_NF_MATCH_IPP2P $CONFIG_IP_NF_IPTABLES
|
||||||
|
diff -ruN linux-2.4.30-old/net/ipv4/netfilter/Makefile linux-2.4.30-new/net/ipv4/netfilter/Makefile
|
||||||
|
--- linux-2.4.30-old/net/ipv4/netfilter/Makefile 2005-11-13 21:52:27.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/net/ipv4/netfilter/Makefile 2005-11-13 22:20:15.000000000 +0100
|
||||||
|
@@ -94,6 +94,7 @@
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
|
||||||
|
+obj-$(CONFIG_IP_NF_MATCH_CONDITION) += ipt_condition.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
|
||||||
|
|
||||||
|
diff -ruN linux-2.4.30-old/net/ipv4/netfilter/ipt_condition.c linux-2.4.30-new/net/ipv4/netfilter/ipt_condition.c
|
||||||
|
--- linux-2.4.30-old/net/ipv4/netfilter/ipt_condition.c 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/net/ipv4/netfilter/ipt_condition.c 2005-11-13 22:20:14.000000000 +0100
|
||||||
|
@@ -0,0 +1,256 @@
|
||||||
|
+/*-------------------------------------------*\
|
||||||
|
+| Netfilter Condition Module |
|
||||||
|
+| |
|
||||||
|
+| Description: This module allows firewall |
|
||||||
|
+| rules to match using condition variables |
|
||||||
|
+| stored in /proc files. |
|
||||||
|
+| |
|
||||||
|
+| Author: Stephane Ouellette 2002-10-22 |
|
||||||
|
+| <ouellettes@videotron.ca> |
|
||||||
|
+| |
|
||||||
|
+| History: |
|
||||||
|
+| 2003-02-10 Second version with improved |
|
||||||
|
+| locking and simplified code. |
|
||||||
|
+| |
|
||||||
|
+| This software is distributed under the |
|
||||||
|
+| terms of the GNU GPL. |
|
||||||
|
+\*-------------------------------------------*/
|
||||||
|
+
|
||||||
|
+#include<linux/module.h>
|
||||||
|
+#include<linux/proc_fs.h>
|
||||||
|
+#include<linux/spinlock.h>
|
||||||
|
+#include<linux/string.h>
|
||||||
|
+#include<asm/atomic.h>
|
||||||
|
+#include<linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
+#include<linux/netfilter_ipv4/ipt_condition.h>
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#ifndef CONFIG_PROC_FS
|
||||||
|
+#error "Proc file system support is required for this module"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+MODULE_AUTHOR("Stephane Ouellette <ouellettes@videotron.ca>");
|
||||||
|
+MODULE_DESCRIPTION("Allows rules to match against condition variables");
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+struct condition_variable {
|
||||||
|
+ struct condition_variable *next;
|
||||||
|
+ struct proc_dir_entry *status_proc;
|
||||||
|
+ atomic_t refcount;
|
||||||
|
+ int enabled; /* TRUE == 1, FALSE == 0 */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static rwlock_t list_lock;
|
||||||
|
+static struct condition_variable *head = NULL;
|
||||||
|
+static struct proc_dir_entry *proc_net_condition = NULL;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+ipt_condition_read_info(char *buffer, char **start, off_t offset,
|
||||||
|
+ int length, int *eof, void *data)
|
||||||
|
+{
|
||||||
|
+ struct condition_variable *var =
|
||||||
|
+ (struct condition_variable *) data;
|
||||||
|
+
|
||||||
|
+ if (offset == 0) {
|
||||||
|
+ *start = buffer;
|
||||||
|
+ buffer[0] = (var->enabled) ? '1' : '0';
|
||||||
|
+ buffer[1] = '\n';
|
||||||
|
+ return 2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *eof = 1;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+ipt_condition_write_info(struct file *file, const char *buffer,
|
||||||
|
+ unsigned long length, void *data)
|
||||||
|
+{
|
||||||
|
+ struct condition_variable *var =
|
||||||
|
+ (struct condition_variable *) data;
|
||||||
|
+
|
||||||
|
+ if (length) {
|
||||||
|
+ /* Match only on the first character */
|
||||||
|
+ switch (buffer[0]) {
|
||||||
|
+ case '0':
|
||||||
|
+ var->enabled = 0;
|
||||||
|
+ break;
|
||||||
|
+ case '1':
|
||||||
|
+ var->enabled = 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return (int) length;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+match(const struct sk_buff *skb, const struct net_device *in,
|
||||||
|
+ const struct net_device *out, const void *matchinfo, int offset,
|
||||||
|
+ const void *hdr, u_int16_t datalen, int *hotdrop)
|
||||||
|
+{
|
||||||
|
+ const struct condition_info *info =
|
||||||
|
+ (const struct condition_info *) matchinfo;
|
||||||
|
+ struct condition_variable *var;
|
||||||
|
+ int condition_status = 0;
|
||||||
|
+
|
||||||
|
+ read_lock(&list_lock);
|
||||||
|
+
|
||||||
|
+ for (var = head; var; var = var->next) {
|
||||||
|
+ if (strcmp(info->name, var->status_proc->name) == 0) {
|
||||||
|
+ condition_status = var->enabled;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ read_unlock(&list_lock);
|
||||||
|
+
|
||||||
|
+ return condition_status ^ info->invert;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+checkentry(const char *tablename, const struct ipt_ip *ip,
|
||||||
|
+ void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
|
||||||
|
+{
|
||||||
|
+ struct condition_info *info = (struct condition_info *) matchinfo;
|
||||||
|
+ struct condition_variable *var, *newvar;
|
||||||
|
+
|
||||||
|
+ if (matchsize != IPT_ALIGN(sizeof(struct condition_info)))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /* The first step is to check if the condition variable already exists. */
|
||||||
|
+ /* Here, a read lock is sufficient because we won't change the list */
|
||||||
|
+ read_lock(&list_lock);
|
||||||
|
+
|
||||||
|
+ for (var = head; var; var = var->next) {
|
||||||
|
+ if (strcmp(info->name, var->status_proc->name) == 0) {
|
||||||
|
+ atomic_inc(&var->refcount);
|
||||||
|
+ read_unlock(&list_lock);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ read_unlock(&list_lock);
|
||||||
|
+
|
||||||
|
+ /* At this point, we need to allocate a new condition variable */
|
||||||
|
+ newvar = kmalloc(sizeof(struct condition_variable), GFP_KERNEL);
|
||||||
|
+
|
||||||
|
+ if (!newvar)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ /* Create the condition variable's proc file entry */
|
||||||
|
+ newvar->status_proc = create_proc_entry(info->name, 0644, proc_net_condition);
|
||||||
|
+
|
||||||
|
+ if (!newvar->status_proc) {
|
||||||
|
+ /*
|
||||||
|
+ * There are two possibilities:
|
||||||
|
+ * 1- Another condition variable with the same name has been created, which is valid.
|
||||||
|
+ * 2- There was a memory allocation error.
|
||||||
|
+ */
|
||||||
|
+ kfree(newvar);
|
||||||
|
+ read_lock(&list_lock);
|
||||||
|
+
|
||||||
|
+ for (var = head; var; var = var->next) {
|
||||||
|
+ if (strcmp(info->name, var->status_proc->name) == 0) {
|
||||||
|
+ atomic_inc(&var->refcount);
|
||||||
|
+ read_unlock(&list_lock);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ read_unlock(&list_lock);
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ atomic_set(&newvar->refcount, 1);
|
||||||
|
+ newvar->enabled = 0;
|
||||||
|
+ newvar->status_proc->owner = THIS_MODULE;
|
||||||
|
+ newvar->status_proc->data = newvar;
|
||||||
|
+ wmb();
|
||||||
|
+ newvar->status_proc->read_proc = ipt_condition_read_info;
|
||||||
|
+ newvar->status_proc->write_proc = ipt_condition_write_info;
|
||||||
|
+
|
||||||
|
+ write_lock(&list_lock);
|
||||||
|
+
|
||||||
|
+ newvar->next = head;
|
||||||
|
+ head = newvar;
|
||||||
|
+
|
||||||
|
+ write_unlock(&list_lock);
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+destroy(void *matchinfo, unsigned int matchsize)
|
||||||
|
+{
|
||||||
|
+ struct condition_info *info = (struct condition_info *) matchinfo;
|
||||||
|
+ struct condition_variable *var, *prev = NULL;
|
||||||
|
+
|
||||||
|
+ if (matchsize != IPT_ALIGN(sizeof(struct condition_info)))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ write_lock(&list_lock);
|
||||||
|
+
|
||||||
|
+ for (var = head; var && strcmp(info->name, var->status_proc->name);
|
||||||
|
+ prev = var, var = var->next);
|
||||||
|
+
|
||||||
|
+ if (var && atomic_dec_and_test(&var->refcount)) {
|
||||||
|
+ if (prev)
|
||||||
|
+ prev->next = var->next;
|
||||||
|
+ else
|
||||||
|
+ head = var->next;
|
||||||
|
+
|
||||||
|
+ write_unlock(&list_lock);
|
||||||
|
+ remove_proc_entry(var->status_proc->name, proc_net_condition);
|
||||||
|
+ kfree(var);
|
||||||
|
+ } else
|
||||||
|
+ write_unlock(&list_lock);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static struct ipt_match condition_match = {
|
||||||
|
+ .name = "condition",
|
||||||
|
+ .match = &match,
|
||||||
|
+ .checkentry = &checkentry,
|
||||||
|
+ .destroy = &destroy,
|
||||||
|
+ .me = THIS_MODULE
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int __init
|
||||||
|
+init(void)
|
||||||
|
+{
|
||||||
|
+ int errorcode;
|
||||||
|
+
|
||||||
|
+ rwlock_init(&list_lock);
|
||||||
|
+ proc_net_condition = proc_mkdir("ipt_condition", proc_net);
|
||||||
|
+
|
||||||
|
+ if (proc_net_condition) {
|
||||||
|
+ errorcode = ipt_register_match(&condition_match);
|
||||||
|
+
|
||||||
|
+ if (errorcode)
|
||||||
|
+ remove_proc_entry("ipt_condition", proc_net);
|
||||||
|
+ } else
|
||||||
|
+ errorcode = -EACCES;
|
||||||
|
+
|
||||||
|
+ return errorcode;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void __exit
|
||||||
|
+fini(void)
|
||||||
|
+{
|
||||||
|
+ ipt_unregister_match(&condition_match);
|
||||||
|
+ remove_proc_entry("ipt_condition", proc_net);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(init);
|
||||||
|
+module_exit(fini);
|
||||||
|
diff -ruN linux-2.4.30-old/net/ipv6/netfilter/Config.in linux-2.4.30-new/net/ipv6/netfilter/Config.in
|
||||||
|
--- linux-2.4.30-old/net/ipv6/netfilter/Config.in 2003-06-13 16:51:39.000000000 +0200
|
||||||
|
+++ linux-2.4.30-new/net/ipv6/netfilter/Config.in 2005-11-13 22:20:15.000000000 +0100
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
if [ "$CONFIG_IP6_NF_IPTABLES" != "n" ]; then
|
||||||
|
# The simple matches.
|
||||||
|
dep_tristate ' limit match support' CONFIG_IP6_NF_MATCH_LIMIT $CONFIG_IP6_NF_IPTABLES
|
||||||
|
+ dep_tristate ' condition match support' CONFIG_IP6_NF_MATCH_CONDITION $CONFIG_IP6_NF_IPTABLES
|
||||||
|
dep_tristate ' MAC address match support' CONFIG_IP6_NF_MATCH_MAC $CONFIG_IP6_NF_IPTABLES
|
||||||
|
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
|
||||||
|
dep_tristate ' Routing header match support (EXPERIMENTAL)' CONFIG_IP6_NF_MATCH_RT $CONFIG_IP6_NF_IPTABLES
|
||||||
|
diff -ruN linux-2.4.30-old/net/ipv6/netfilter/Makefile linux-2.4.30-new/net/ipv6/netfilter/Makefile
|
||||||
|
--- linux-2.4.30-old/net/ipv6/netfilter/Makefile 2003-06-13 16:51:39.000000000 +0200
|
||||||
|
+++ linux-2.4.30-new/net/ipv6/netfilter/Makefile 2005-11-13 22:20:15.000000000 +0100
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
# Link order matters here.
|
||||||
|
obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
|
||||||
|
obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o
|
||||||
|
+obj-$(CONFIG_IP6_NF_MATCH_CONDITION) += ip6t_condition.o
|
||||||
|
obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
|
||||||
|
obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o
|
||||||
|
obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
|
||||||
|
diff -ruN linux-2.4.30-old/net/ipv6/netfilter/ip6t_condition.c linux-2.4.30-new/net/ipv6/netfilter/ip6t_condition.c
|
||||||
|
--- linux-2.4.30-old/net/ipv6/netfilter/ip6t_condition.c 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/net/ipv6/netfilter/ip6t_condition.c 2005-11-13 22:20:14.000000000 +0100
|
||||||
|
@@ -0,0 +1,254 @@
|
||||||
|
+/*-------------------------------------------*\
|
||||||
|
+| Netfilter Condition Module for IPv6 |
|
||||||
|
+| |
|
||||||
|
+| Description: This module allows firewall |
|
||||||
|
+| rules to match using condition variables |
|
||||||
|
+| stored in /proc files. |
|
||||||
|
+| |
|
||||||
|
+| Author: Stephane Ouellette 2003-02-10 |
|
||||||
|
+| <ouellettes@videotron.ca> |
|
||||||
|
+| |
|
||||||
|
+| This software is distributed under the |
|
||||||
|
+| terms of the GNU GPL. |
|
||||||
|
+\*-------------------------------------------*/
|
||||||
|
+
|
||||||
|
+#include<linux/module.h>
|
||||||
|
+#include<linux/proc_fs.h>
|
||||||
|
+#include<linux/spinlock.h>
|
||||||
|
+#include<linux/string.h>
|
||||||
|
+#include<asm/atomic.h>
|
||||||
|
+#include<linux/netfilter_ipv6/ip6_tables.h>
|
||||||
|
+#include<linux/netfilter_ipv6/ip6t_condition.h>
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#ifndef CONFIG_PROC_FS
|
||||||
|
+#error "Proc file system support is required for this module"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+MODULE_AUTHOR("Stephane Ouellette <ouellettes@videotron.ca>");
|
||||||
|
+MODULE_DESCRIPTION("Allows rules to match against condition variables");
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+struct condition_variable {
|
||||||
|
+ struct condition_variable *next;
|
||||||
|
+ struct proc_dir_entry *status_proc;
|
||||||
|
+ atomic_t refcount;
|
||||||
|
+ int enabled; /* TRUE == 1, FALSE == 0 */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static rwlock_t list_lock;
|
||||||
|
+static struct condition_variable *head = NULL;
|
||||||
|
+static struct proc_dir_entry *proc_net_condition = NULL;
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+ipt_condition_read_info(char *buffer, char **start, off_t offset,
|
||||||
|
+ int length, int *eof, void *data)
|
||||||
|
+{
|
||||||
|
+ struct condition_variable *var =
|
||||||
|
+ (struct condition_variable *) data;
|
||||||
|
+
|
||||||
|
+ if (offset == 0) {
|
||||||
|
+ *start = buffer;
|
||||||
|
+ buffer[0] = (var->enabled) ? '1' : '0';
|
||||||
|
+ buffer[1] = '\n';
|
||||||
|
+ return 2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *eof = 1;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+ipt_condition_write_info(struct file *file, const char *buffer,
|
||||||
|
+ unsigned long length, void *data)
|
||||||
|
+{
|
||||||
|
+ struct condition_variable *var =
|
||||||
|
+ (struct condition_variable *) data;
|
||||||
|
+
|
||||||
|
+ if (length) {
|
||||||
|
+ /* Match only on the first character */
|
||||||
|
+ switch (buffer[0]) {
|
||||||
|
+ case '0':
|
||||||
|
+ var->enabled = 0;
|
||||||
|
+ break;
|
||||||
|
+ case '1':
|
||||||
|
+ var->enabled = 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return (int) length;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+match(const struct sk_buff *skb, const struct net_device *in,
|
||||||
|
+ const struct net_device *out, const void *matchinfo, int offset,
|
||||||
|
+ const void *hdr, u_int16_t datalen, int *hotdrop)
|
||||||
|
+{
|
||||||
|
+ const struct condition6_info *info =
|
||||||
|
+ (const struct condition6_info *) matchinfo;
|
||||||
|
+ struct condition_variable *var;
|
||||||
|
+ int condition_status = 0;
|
||||||
|
+
|
||||||
|
+ read_lock(&list_lock);
|
||||||
|
+
|
||||||
|
+ for (var = head; var; var = var->next) {
|
||||||
|
+ if (strcmp(info->name, var->status_proc->name) == 0) {
|
||||||
|
+ condition_status = var->enabled;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ read_unlock(&list_lock);
|
||||||
|
+
|
||||||
|
+ return condition_status ^ info->invert;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+checkentry(const char *tablename, const struct ip6t_ip6 *ip,
|
||||||
|
+ void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
|
||||||
|
+{
|
||||||
|
+ struct condition6_info *info =
|
||||||
|
+ (struct condition6_info *) matchinfo;
|
||||||
|
+ struct condition_variable *var, *newvar;
|
||||||
|
+
|
||||||
|
+ if (matchsize != IP6T_ALIGN(sizeof(struct condition6_info)))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /* The first step is to check if the condition variable already exists. */
|
||||||
|
+ /* Here, a read lock is sufficient because we won't change the list */
|
||||||
|
+ read_lock(&list_lock);
|
||||||
|
+
|
||||||
|
+ for (var = head; var; var = var->next) {
|
||||||
|
+ if (strcmp(info->name, var->status_proc->name) == 0) {
|
||||||
|
+ atomic_inc(&var->refcount);
|
||||||
|
+ read_unlock(&list_lock);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ read_unlock(&list_lock);
|
||||||
|
+
|
||||||
|
+ /* At this point, we need to allocate a new condition variable */
|
||||||
|
+ newvar = kmalloc(sizeof(struct condition_variable), GFP_KERNEL);
|
||||||
|
+
|
||||||
|
+ if (!newvar)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ /* Create the condition variable's proc file entry */
|
||||||
|
+ newvar->status_proc = create_proc_entry(info->name, 0644, proc_net_condition);
|
||||||
|
+
|
||||||
|
+ if (!newvar->status_proc) {
|
||||||
|
+ /*
|
||||||
|
+ * There are two possibilities:
|
||||||
|
+ * 1- Another condition variable with the same name has been created, which is valid.
|
||||||
|
+ * 2- There was a memory allocation error.
|
||||||
|
+ */
|
||||||
|
+ kfree(newvar);
|
||||||
|
+ read_lock(&list_lock);
|
||||||
|
+
|
||||||
|
+ for (var = head; var; var = var->next) {
|
||||||
|
+ if (strcmp(info->name, var->status_proc->name) == 0) {
|
||||||
|
+ atomic_inc(&var->refcount);
|
||||||
|
+ read_unlock(&list_lock);
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ read_unlock(&list_lock);
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ atomic_set(&newvar->refcount, 1);
|
||||||
|
+ newvar->enabled = 0;
|
||||||
|
+ newvar->status_proc->owner = THIS_MODULE;
|
||||||
|
+ newvar->status_proc->data = newvar;
|
||||||
|
+ wmb();
|
||||||
|
+ newvar->status_proc->read_proc = ipt_condition_read_info;
|
||||||
|
+ newvar->status_proc->write_proc = ipt_condition_write_info;
|
||||||
|
+
|
||||||
|
+ write_lock(&list_lock);
|
||||||
|
+
|
||||||
|
+ newvar->next = head;
|
||||||
|
+ head = newvar;
|
||||||
|
+
|
||||||
|
+ write_unlock(&list_lock);
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+destroy(void *matchinfo, unsigned int matchsize)
|
||||||
|
+{
|
||||||
|
+ struct condition6_info *info =
|
||||||
|
+ (struct condition6_info *) matchinfo;
|
||||||
|
+ struct condition_variable *var, *prev = NULL;
|
||||||
|
+
|
||||||
|
+ if (matchsize != IP6T_ALIGN(sizeof(struct condition6_info)))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ write_lock(&list_lock);
|
||||||
|
+
|
||||||
|
+ for (var = head; var && strcmp(info->name, var->status_proc->name);
|
||||||
|
+ prev = var, var = var->next);
|
||||||
|
+
|
||||||
|
+ if (var && atomic_dec_and_test(&var->refcount)) {
|
||||||
|
+ if (prev)
|
||||||
|
+ prev->next = var->next;
|
||||||
|
+ else
|
||||||
|
+ head = var->next;
|
||||||
|
+
|
||||||
|
+ write_unlock(&list_lock);
|
||||||
|
+ remove_proc_entry(var->status_proc->name, proc_net_condition);
|
||||||
|
+ kfree(var);
|
||||||
|
+ } else
|
||||||
|
+ write_unlock(&list_lock);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static struct ip6t_match condition_match = {
|
||||||
|
+ .name = "condition",
|
||||||
|
+ .match = &match,
|
||||||
|
+ .checkentry = &checkentry,
|
||||||
|
+ .destroy = &destroy,
|
||||||
|
+ .me = THIS_MODULE
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int __init
|
||||||
|
+init(void)
|
||||||
|
+{
|
||||||
|
+ int errorcode;
|
||||||
|
+
|
||||||
|
+ rwlock_init(&list_lock);
|
||||||
|
+ proc_net_condition = proc_mkdir("ip6t_condition", proc_net);
|
||||||
|
+
|
||||||
|
+ if (proc_net_condition) {
|
||||||
|
+ errorcode = ipt_register_match(&condition_match);
|
||||||
|
+
|
||||||
|
+ if (errorcode)
|
||||||
|
+ remove_proc_entry("ip6t_condition", proc_net);
|
||||||
|
+ } else
|
||||||
|
+ errorcode = -EACCES;
|
||||||
|
+
|
||||||
|
+ return errorcode;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void __exit
|
||||||
|
+fini(void)
|
||||||
|
+{
|
||||||
|
+ ipt_unregister_match(&condition_match);
|
||||||
|
+ remove_proc_entry("ip6t_condition", proc_net);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(init);
|
||||||
|
+module_exit(fini);
|
|
@ -0,0 +1,147 @@
|
||||||
|
diff -ruN linux-2.4.30-old/Documentation/Configure.help linux-2.4.30-new/Documentation/Configure.help
|
||||||
|
--- linux-2.4.30-old/Documentation/Configure.help 2005-11-13 22:30:42.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/Documentation/Configure.help 2005-11-13 22:31:17.000000000 +0100
|
||||||
|
@@ -2888,6 +2888,13 @@
|
||||||
|
If you want to compile it as a module, say M here and read
|
||||||
|
<file:Documentation/modules.txt>. If unsure, say `N'.
|
||||||
|
|
||||||
|
+quota match support
|
||||||
|
+CONFIG_IP_NF_MATCH_QUOTA
|
||||||
|
+ This match implements network quotas.
|
||||||
|
+
|
||||||
|
+ If you want to compile it as a module, say M here and read
|
||||||
|
+ Documentation/modules.txt. If unsure, say `N'.
|
||||||
|
+
|
||||||
|
skb->pkt_type packet match support
|
||||||
|
CONFIG_IP_NF_MATCH_PKTTYPE
|
||||||
|
This patch allows you to match packet in accrodance
|
||||||
|
diff -ruN linux-2.4.30-old/include/linux/netfilter_ipv4/ipt_quota.h linux-2.4.30-new/include/linux/netfilter_ipv4/ipt_quota.h
|
||||||
|
--- linux-2.4.30-old/include/linux/netfilter_ipv4/ipt_quota.h 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/include/linux/netfilter_ipv4/ipt_quota.h 2005-11-13 22:31:17.000000000 +0100
|
||||||
|
@@ -0,0 +1,12 @@
|
||||||
|
+#ifndef _IPT_QUOTA_H
|
||||||
|
+#define _IPT_QUOTA_H
|
||||||
|
+
|
||||||
|
+/* print debug info in both kernel/netfilter module & iptable library */
|
||||||
|
+//#define DEBUG_IPT_QUOTA
|
||||||
|
+
|
||||||
|
+struct ipt_quota_info {
|
||||||
|
+ u_int64_t quota;
|
||||||
|
+ struct ipt_quota_info *master;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#endif /*_IPT_QUOTA_H*/
|
||||||
|
diff -ruN linux-2.4.30-old/net/ipv4/netfilter/Config.in linux-2.4.30-new/net/ipv4/netfilter/Config.in
|
||||||
|
--- linux-2.4.30-old/net/ipv4/netfilter/Config.in 2005-11-13 22:30:42.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/net/ipv4/netfilter/Config.in 2005-11-13 22:31:17.000000000 +0100
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
|
||||||
|
# The simple matches.
|
||||||
|
dep_tristate ' limit match support' CONFIG_IP_NF_MATCH_LIMIT $CONFIG_IP_NF_IPTABLES
|
||||||
|
+ dep_tristate ' quota match support' CONFIG_IP_NF_MATCH_QUOTA $CONFIG_IP_NF_IPTABLES
|
||||||
|
|
||||||
|
dep_tristate ' IP set support' CONFIG_IP_NF_SET $CONFIG_IP_NF_IPTABLES
|
||||||
|
if [ "$CONFIG_IP_NF_SET" != "n" ]; then
|
||||||
|
diff -ruN linux-2.4.30-old/net/ipv4/netfilter/Makefile linux-2.4.30-new/net/ipv4/netfilter/Makefile
|
||||||
|
--- linux-2.4.30-old/net/ipv4/netfilter/Makefile 2005-11-13 22:30:42.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/net/ipv4/netfilter/Makefile 2005-11-13 22:31:17.000000000 +0100
|
||||||
|
@@ -74,6 +74,7 @@
|
||||||
|
# matches
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
|
||||||
|
+obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
|
||||||
|
obj-$(CONFIG_IP_NF_MATCH_SET) += ipt_set.o
|
||||||
|
obj-$(CONFIG_IP_NF_TARGET_SET) += ipt_SET.o
|
||||||
|
diff -ruN linux-2.4.30-old/net/ipv4/netfilter/ipt_quota.c linux-2.4.30-new/net/ipv4/netfilter/ipt_quota.c
|
||||||
|
--- linux-2.4.30-old/net/ipv4/netfilter/ipt_quota.c 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ linux-2.4.30-new/net/ipv4/netfilter/ipt_quota.c 2005-11-13 22:31:17.000000000 +0100
|
||||||
|
@@ -0,0 +1,88 @@
|
||||||
|
+/*
|
||||||
|
+ * netfilter module to enforce network quotas
|
||||||
|
+ *
|
||||||
|
+ * Sam Johnston <samj@samj.net>
|
||||||
|
+ *
|
||||||
|
+ * 30/01/05: Fixed on SMP --Pablo Neira <pablo@eurodev.net>
|
||||||
|
+ */
|
||||||
|
+#include <linux/module.h>
|
||||||
|
+#include <linux/skbuff.h>
|
||||||
|
+#include <linux/spinlock.h>
|
||||||
|
+#include <linux/interrupt.h>
|
||||||
|
+
|
||||||
|
+#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
+#include <linux/netfilter_ipv4/ipt_quota.h>
|
||||||
|
+
|
||||||
|
+MODULE_LICENSE("GPL");
|
||||||
|
+
|
||||||
|
+static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+match(const struct sk_buff *skb,
|
||||||
|
+ const struct net_device *in,
|
||||||
|
+ const struct net_device *out,
|
||||||
|
+ const void *matchinfo,
|
||||||
|
+ int offset, const void *hdr, u_int16_t datalen, int *hotdrop)
|
||||||
|
+{
|
||||||
|
+ struct ipt_quota_info *q =
|
||||||
|
+ ((struct ipt_quota_info *) matchinfo)->master;
|
||||||
|
+
|
||||||
|
+ spin_lock_bh("a_lock);
|
||||||
|
+
|
||||||
|
+ if (q->quota >= datalen) {
|
||||||
|
+ /* we can afford this one */
|
||||||
|
+ q->quota -= datalen;
|
||||||
|
+ spin_unlock_bh("a_lock);
|
||||||
|
+
|
||||||
|
+#ifdef DEBUG_IPT_QUOTA
|
||||||
|
+ printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
|
||||||
|
+#endif
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* so we do not allow even small packets from now on */
|
||||||
|
+ q->quota = 0;
|
||||||
|
+
|
||||||
|
+#ifdef DEBUG_IPT_QUOTA
|
||||||
|
+ printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ spin_unlock_bh("a_lock);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+checkentry(const char *tablename,
|
||||||
|
+ const struct ipt_ip *ip,
|
||||||
|
+ void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
|
||||||
|
+{
|
||||||
|
+ /* TODO: spinlocks? sanity checks? */
|
||||||
|
+ struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
|
||||||
|
+
|
||||||
|
+ if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /* For SMP, we only want to use one set of counters. */
|
||||||
|
+ q->master = q;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct ipt_match quota_match
|
||||||
|
+ = { {NULL, NULL}, "quota", &match, &checkentry, NULL, THIS_MODULE };
|
||||||
|
+
|
||||||
|
+static int __init
|
||||||
|
+init(void)
|
||||||
|
+{
|
||||||
|
+ return ipt_register_match("a_match);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void __exit
|
||||||
|
+fini(void)
|
||||||
|
+{
|
||||||
|
+ ipt_unregister_match("a_match);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+module_init(init);
|
||||||
|
+module_exit(fini);
|
||||||
|
+
|
|
@ -12,14 +12,18 @@ IPKG_KMOD_IPT_CONNTRACK-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK
|
||||||
IPKG_KMOD_IPT_CONNTRACK-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state
|
IPKG_KMOD_IPT_CONNTRACK-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state
|
||||||
|
|
||||||
IPKG_KMOD_IPT_EXTRA-m :=
|
IPKG_KMOD_IPT_EXTRA-m :=
|
||||||
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_CONDITION) += ipt_condition
|
||||||
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes
|
||||||
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit
|
||||||
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG
|
||||||
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_MULTIPORT) += multiport
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_MULTIPORT) += multiport
|
||||||
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner
|
||||||
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev
|
||||||
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype
|
||||||
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota
|
||||||
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent
|
||||||
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT
|
||||||
|
IPKG_KMOD_IPT_EXTRA-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string
|
||||||
|
|
||||||
IPKG_KMOD_IPT_FILTER-m :=
|
IPKG_KMOD_IPT_FILTER-m :=
|
||||||
IPKG_KMOD_IPT_FILTER-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p
|
IPKG_KMOD_IPT_FILTER-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p
|
||||||
|
@ -81,14 +85,18 @@ IPKG_IPTABLES_MOD_CONNTRACK-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper
|
||||||
IPKG_IPTABLES_MOD_CONNTRACK-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state
|
IPKG_IPTABLES_MOD_CONNTRACK-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state
|
||||||
|
|
||||||
IPKG_IPTABLES_MOD_EXTRA-m :=
|
IPKG_IPTABLES_MOD_EXTRA-m :=
|
||||||
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_CONDITION) += ipt_condition
|
||||||
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes
|
||||||
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit
|
||||||
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG
|
||||||
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport
|
||||||
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner
|
||||||
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev
|
||||||
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype
|
||||||
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota
|
||||||
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent
|
||||||
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT
|
||||||
|
IPKG_IPTABLES_MOD_EXTRA-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string
|
||||||
|
|
||||||
IPKG_IPTABLES_MOD_FILTER-m :=
|
IPKG_IPTABLES_MOD_FILTER-m :=
|
||||||
IPKG_IPTABLES_MOD_FILTER-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p
|
IPKG_IPTABLES_MOD_FILTER-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p
|
||||||
|
|
Loading…
Reference in New Issue