[PATCH] childlevel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> - Please decouple the 'childlevel' match and submit it seperately.  We
>   could even submit it to the kernel soon.

Here you go.

(This module adds support for matching on the "childlevel" of a
connection.  Most connections have childlevel 0.  Child connections such
as FTP data or IRC-DCC have childlevel 1.  Children of children have
childlevel 2, and so on.  iptables usage: "-m childlevel --level [!] n")

-matthew
diff -Naur iptables-1.2.9-stock/extensions/.childlevel-test iptables-1.2.9-childlevel/extensions/.childlevel-test
--- iptables-1.2.9-stock/extensions/.childlevel-test	1969-12-31 18:00:00.000000000 -0600
+++ iptables-1.2.9-childlevel/extensions/.childlevel-test	2004-02-16 10:47:17.279087176 -0600
@@ -0,0 +1,2 @@
+#! /bin/sh
+[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_childlevel.h ] && echo childlevel
diff -Naur iptables-1.2.9-stock/extensions/libipt_childlevel.c iptables-1.2.9-childlevel/extensions/libipt_childlevel.c
--- iptables-1.2.9-stock/extensions/libipt_childlevel.c	1969-12-31 18:00:00.000000000 -0600
+++ iptables-1.2.9-childlevel/extensions/libipt_childlevel.c	2004-02-16 11:12:47.613535776 -0600
@@ -0,0 +1,122 @@
+/* 
+   Shared library add-on to iptables to add layer 7 matching support. 
+
+   http://l7-filter.sf.net
+  
+   By Matthew Strait <quadong@xxxxxxxxxxxx>, Dec 2003.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either version
+   2 of the License, or (at your option) any later version.
+   http://www.gnu.org/licenses/gpl.txt
+*/
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <dirent.h>
+
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ipt_childlevel.h>
+
+/* Function which prints out usage message. */
+static void help(void)
+{
+	printf(
+	"CHILDLEVEL match v%s options:\n"
+	"--level <n>  : Match childlevel n (0 == master)\n",
+	IPTABLES_VERSION);
+	fputc('\n', stdout);
+}
+
+static struct option opts[] = {
+	{ .name = "level", .has_arg = 1, .flag = 0, .val = '1' },
+	{ .name = 0 }
+};
+
+/* Initialize the match. */
+static void init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+	*nfcache |= NFC_UNKNOWN;
+}
+
+/* Function which parses command options; returns true if it ate an option */
+static int parse(int c, char **argv, int invert, unsigned int *flags,
+      const struct ipt_entry *entry, unsigned int *nfcache,
+      struct ipt_entry_match **match)
+{
+	struct ipt_childlevel_info *childlevelinfo = 
+		(struct ipt_childlevel_info *)(*match)->data;
+
+	switch (c) {
+	case '1':
+		check_inverse(optarg, &invert, &optind, 0);
+		childlevelinfo->childlevel = atoi(argv[optind-1]);
+		if (invert)
+			childlevelinfo->invert = 1;
+		*flags = 1;
+		break;
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Final check; must have specified --level. */
+static void final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM,
+			   "CHILDLEVEL match: You must specify `--level'");
+}
+
+static void print_protocol(int n, int invert, int numeric)
+{
+	fputs("childlevel ", stdout);
+	if (invert) fputc('!', stdout);
+	printf("%d ", n);
+}
+
+/* Prints out the matchinfo. */
+static void print(const struct ipt_ip *ip,
+      const struct ipt_entry_match *match,
+      int numeric)
+{
+	printf("CHILDLEVEL ");
+
+	print_protocol(((struct ipt_childlevel_info *)match->data)->childlevel,
+		  ((struct ipt_childlevel_info *)match->data)->invert, numeric);
+}
+/* Saves the union ipt_matchinfo in parsable form to stdout. */
+static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+{
+        const struct ipt_childlevel_info *info =
+            (const struct ipt_childlevel_info*) match->data;
+
+        printf("--childlevel %s%d ", (info->invert) ? "! ": "", info->childlevel);
+}
+
+static struct iptables_match childlevel = { 
+    .name          = "childlevel",
+    .version       = IPTABLES_VERSION,
+    .size          = IPT_ALIGN(sizeof(struct ipt_childlevel_info)),
+    .userspacesize = IPT_ALIGN(sizeof(struct ipt_childlevel_info)),
+    .help          = &help,
+    .init          = &init,
+    .parse         = &parse,
+    .final_check   = &final_check,
+    .print         = &print,
+    .save          = &save,
+    .extra_opts    = opts
+};
+
+void _init(void)
+{
+	register_match(&childlevel);
+}
diff -Naur iptables-1.2.9-stock/iptables.8 iptables-1.2.9-childlevel/iptables.8
--- iptables-1.2.9-stock/iptables.8	2003-06-30 11:16:54.000000000 -0500
+++ iptables-1.2.9-childlevel/iptables.8	2004-02-16 10:48:20.874419216 -0600
@@ -382,6 +382,13 @@
 This module matches the SPIs in AH header of IPSec packets.
 .TP
 .BR "--ahspi " "[!] \fIspi\fP[:\fIspi\fP]"
+.SS childlevel
+This is an experimental module.  It matches on whether the 
+packet is part of a master connection
+or one of its children (or grandchildren, etc).  For instance, most 
+packets are level 0.  FTP data transfer is level 1.
+.TP
+.BR "--childlevel " "[!] \fIlevel\fP"
 .SS conntrack
 This module, when combined with connection tracking, allows access to
 more connection tracking information than the "state" match.
diff -Naur linux-2.6.2-stock/include/linux/netfilter_ipv4/ipt_childlevel.h linux-2.6.2-childlevel/include/linux/netfilter_ipv4/ipt_childlevel.h
--- linux-2.6.2-stock/include/linux/netfilter_ipv4/ipt_childlevel.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.2-childlevel/include/linux/netfilter_ipv4/ipt_childlevel.h	2004-02-16 10:09:34.000000000 -0600
@@ -0,0 +1,22 @@
+/* 
+  By Matthew Strait <quadong@xxxxxxxxxxxx>, Dec 2003.
+  http://l7-filter.sf.net
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License
+  as published by the Free Software Foundation; either version
+  2 of the License, or (at your option) any later version.
+  http://www.gnu.org/licenses/gpl.txt
+*/
+
+#ifndef _IPT_CHILDLEVEL_H
+#define _IPT_CHILDLEVEL_H
+
+typedef char *(*proc_ipt_search) (u_int32_t, u_int8_t);
+
+struct ipt_childlevel_info {
+    u_int32_t childlevel; 
+    u_int8_t invert;
+};
+
+#endif /* _IPT_CHILDLEVEL_H */
diff -Naur linux-2.6.2-stock/net/ipv4/netfilter/Kconfig linux-2.6.2-childlevel/net/ipv4/netfilter/Kconfig
--- linux-2.6.2-stock/net/ipv4/netfilter/Kconfig	2004-02-15 19:52:12.000000000 -0600
+++ linux-2.6.2-childlevel/net/ipv4/netfilter/Kconfig	2004-02-15 20:05:59.000000000 -0600
@@ -115,6 +115,21 @@
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config IP_NF_MATCH_CHILDLEVEL
+	tristate "Child Level match support (EXPERIMENTAL)"
+	depends on IP_NF_IPTABLES && IP_NF_CONNTRACK && EXPERIMENTAL
+	help
+	 Say Y if you want to be able to classify packets based on whether
+	 they belong to a master connection or a child connection.  Examples
+	 of child connections are the data stream of FTP and IRC-DCC.
+
+	 In iptables, "-m childlevel --level 0" will match master connections.
+	 '-m childlevel --level 1" will match first generation children of 
+	 masters.  As of iptables 1.2.9, this requires a patch to iptables to
+	 work.
+
+	 To compile it as a module, choose M here.  If unsure, say N.
+
 config IP_NF_MATCH_PKTTYPE
 	tristate "Packet type match support"
 	depends on IP_NF_IPTABLES
diff -Naur linux-2.6.2-stock/net/ipv4/netfilter/Makefile linux-2.6.2-childlevel/net/ipv4/netfilter/Makefile
--- linux-2.6.2-stock/net/ipv4/netfilter/Makefile	2004-02-15 19:52:12.000000000 -0600
+++ linux-2.6.2-childlevel/net/ipv4/netfilter/Makefile	2004-02-16 10:11:53.000000000 -0600
@@ -66,6 +66,8 @@
 
 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
 
+obj-$(CONFIG_IP_NF_MATCH_CHILDLEVEL) += ipt_childlevel.o
+
 # targets
 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
 obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
diff -Naur linux-2.6.2-stock/net/ipv4/netfilter/ipt_childlevel.c linux-2.6.2-childlevel/net/ipv4/netfilter/ipt_childlevel.c
--- linux-2.6.2-stock/net/ipv4/netfilter/ipt_childlevel.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.2-childlevel/net/ipv4/netfilter/ipt_childlevel.c	2004-02-15 19:58:01.000000000 -0600
@@ -0,0 +1,76 @@
+/* 
+  Kernel module to match the childlevel of a connection.
+  i.e. The ftp control stream is childlevel 0.
+       The ftp data stream is childlevel 1.
+  
+  By Matthew Strait <quadong@xxxxxxxxxxxx>, Dec 2003.
+  http://l7-filter.sf.net
+
+  This program is free software; you can redistribute it and/or
+  modify it under the terms of the GNU General Public License
+  as published by the Free Software Foundation; either version
+  2 of the License, or (at your option) any later version.
+  http://www.gnu.org/licenses/gpl.txt
+*/
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+
+#include <linux/netfilter_ipv4/ipt_childlevel.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+
+MODULE_AUTHOR("Matthew Strait <quadong@xxxxxxxxxxxx>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Childlevel match module");
+
+static int match(const struct sk_buff *skb,    const struct net_device *in,
+                 const struct net_device *out, const void *matchinfo,
+                 int offset,                   int *hotdrop)
+{
+	struct ipt_childlevel_info * info = (struct ipt_childlevel_info *)matchinfo;
+        enum ip_conntrack_info ctinfo;
+        struct ip_conntrack * conntrack;
+	int childlevel = 0;
+
+        if(!(conntrack = ip_conntrack_get((struct sk_buff *)skb, &ctinfo))){
+                printk(KERN_ERR "Netfilter: childlevel: error getting conntrack, giving up.\n");
+		return 0;
+        }
+	
+        while (master_ct(conntrack) != NULL){
+		childlevel++;
+                conntrack = master_ct(conntrack);
+	}
+
+    	return ( (childlevel == info->childlevel) ^ 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_childlevel_info))) 
+               return 0;
+       return 1;
+}
+
+static struct ipt_match childlevel_match = { 
+	.name = "childlevel", 
+	.match = &match, 
+	.checkentry = &checkentry, 
+	.me = THIS_MODULE 
+};
+
+static int __init init(void)
+{
+	return ipt_register_match(&childlevel_match);
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_match(&childlevel_match);
+}
+
+module_init(init);
+module_exit(fini);

[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux