summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorlaforge <laforge>2003-08-24 08:07:57 +0000
committerlaforge <laforge>2003-08-24 08:07:57 +0000
commit82abdf38ef4989c0b9038b5f87c6bd2a46304966 (patch)
tree4016d9174d43837713804590f24a4409b127f882 /extensions
parente7cad2679a4864fcfc6ef6f49a714db4f1d002a6 (diff)
add TCPLAG target (patch was lost on notebook drive)
Diffstat (limited to 'extensions')
-rwxr-xr-xextensions/.TCPLAG-test2
-rw-r--r--extensions/libipt_TCPLAG.c228
2 files changed, 230 insertions, 0 deletions
diff --git a/extensions/.TCPLAG-test b/extensions/.TCPLAG-test
new file mode 100755
index 0000000..248f128
--- /dev/null
+++ b/extensions/.TCPLAG-test
@@ -0,0 +1,2 @@
+#! /bin/sh
+[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_TCPLAG.c ] && echo TCPLAG
diff --git a/extensions/libipt_TCPLAG.c b/extensions/libipt_TCPLAG.c
new file mode 100644
index 0000000..27361e7
--- /dev/null
+++ b/extensions/libipt_TCPLAG.c
@@ -0,0 +1,228 @@
+/* libipt_TCPLAG.c -- module for iptables to interface with TCPLAG target
+ * Copyright (C) 2002 Telford Tendys <telford@triode.net.au>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Shared library add-on to iptables for TCPLAG target control
+ *
+ * This allows installation and removal of the TCPLAG target
+ * Note that there is a lot more commentary in this file than
+ * the average libipt target (i.e. more than none) but these
+ * are just my deductions based on examination of the source
+ * and
+ */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <getopt.h>
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_TCPLAG.h>
+
+/*
+ * This merely dumps out text for the user
+ * (saves keeping the manpage up to date)
+ */
+static void help( void )
+{
+ printf( "TCPLAG options:\n"
+ " --log-level=n Set the syslog level to n (integer 0 to 7)\n\n"
+ " --log-prefix=xx Prefix log messages with xx\n" );
+}
+
+/*
+ * See "man getopt_long" for an explanation of this structure
+ *
+ * If one of our options DOES happen to come up then we get
+ * a callback into parse(), our vals must not overlap with any
+ * normal iptables short options (I think) because there is only
+ * one actual options handler and it can't tell whose options it
+ * is really looking at unless they are all distinct.
+ *
+ * These are exactly the same as the LOG target options
+ * and have the same purpose.
+ */
+static const struct option opts[] =
+{
+ { "log-level", 1, 0, '!' },
+ { "log-prefix", 1, 0, '#' },
+ { 0 }
+};
+
+/*
+ * This gives us a chance to install some initial values in
+ * our own private data structure (which is at t->data).
+ * Probably we could fiddle with t->tflags too but there is
+ * no great advantage in doing so.
+ *
+ * TODO: Find documentation for the above flags which
+ * can be ored into nfcache...
+ *
+ * NFC_IP6_DST_PT
+ * NFC_IP6_PROTO_UNKNOWN
+ * NFC_IP6_SRC_PT
+ * NFC_IP6_TCPFLAGS
+ * NFC_IP_DST_PT
+ * NFC_IP_SRC_PT
+ * NFC_IP_TOS
+ * NFC_UNKNOWN -- This one seems safest
+ */
+static void init( struct ipt_entry_target *t, unsigned int *nfcache )
+{
+ struct ipt_tcplag *el = (struct ipt_tcplag *)t->data;
+ memset( el, 0, sizeof( struct ipt_tcplag ));
+ el->level = 4; /* Default to warning level */
+ strcpy( el->prefix, "TCPLAG:" ); /* Give a reasonable default prefix */
+ *nfcache |= NFC_UNKNOWN;
+}
+
+/*
+ * It doesn't take much thought to see how little thought has gone into
+ * this particular API. However, to add to that I'd just like to say that
+ * it can be made to work and small miracles are still miracles.
+ *
+ * The input parameters are as follows:
+ *
+ * c -- the 'val' from opts[] above, could possibly be something
+ * we cannot recognise in which case return(0).
+ * If we do recognise it then return(1).
+ *
+ * argv -- in case we want to take parameters from the command line,
+ * not sure how to safely ensure that the parameter that
+ * we want to take will really exist, presumably getopt_long()
+ * will have already checked such things (what about optional
+ * parameters huh?).
+ *
+ * invert -- if the option parameter had '!' in front of it, usually this
+ * would inversion of the matching sense but I don't think it
+ * is useful in the case of targets.
+ *
+ * flags -- always (*target)->tflags for those who feel it is better
+ * to access this field indirectly <shrug> starts of
+ * zero for a fresh target, gets fed into final_check().
+ *
+ * entry -- apparently useless
+ *
+ * target -- the record that holds data about this target,
+ * most importantly, our private data is (*target)->data
+ * (this has already been malloced for us).
+ */
+static int parse( int c, char **argv, int invert, unsigned int *flags,
+ const struct ipt_entry *entry, struct ipt_entry_target **target )
+{
+ struct ipt_tcplag *el = (struct ipt_tcplag *)( *target )->data;
+/*
+ * Yeah, we could complain about options being issued twice but
+ * is it really worth the trouble? Will it make the world a better place?
+ */
+ switch( c )
+ {
+/*
+ * I really can't be bothered with the syslog naming convention,
+ * it isn't terribly useful anyhow.
+ */
+ case '!':
+ el->level = strtol( optarg, 0, 10 );
+ return( 1 );
+/*
+ * 15 chars should be plenty
+ */
+ case '#':
+ strncpy( el->prefix, optarg, 15 );
+ el->prefix[ 14 ] = 0; /* Force termination */
+ return( 1 );
+ }
+ return( 0 );
+}
+
+/*
+ * This gets given the (*target)->tflags value from
+ * the parse() above and it gets called after all the
+ * parsing of options is completed. Thus if one option
+ * requires another option you can test the flags and
+ * decide whether everything is in order.
+ *
+ * If there is a problem then do something like:
+ * exit_error( PARAMETER_PROBLEM, "foobar parameters detected in TCPLAG target");
+ *
+ * In this case, no errors are possible
+ */
+static void final_check( unsigned int flags ) { }
+/*
+ * This print is for the purpose of user-readable display
+ * such as what "iptables -L" would give. The notes in
+ * iptables.h say that target could possibly be a null pointer
+ * but coding of the various libipt_XX.c modules suggests
+ * that it is safe to presume target is correctly initialised.
+ */
+static void print(const struct ipt_ip *ip, const struct ipt_entry_target *target, int numeric)
+{
+ const struct ipt_tcplag *el = (const struct ipt_tcplag *)target->data;
+ printf("TCPLAG <%d>", el->level );
+ if( el->prefix[ 0 ])
+ {
+ printf( "%s", el->prefix );
+ }
+}
+
+/*
+ * As above but command-line style printout
+ * (machine-readable for restoring table)
+ */
+static void save( const struct ipt_ip *ip, const struct ipt_entry_target *target )
+{
+ const struct ipt_tcplag *el = (const struct ipt_tcplag *)target->data;
+ printf("TCPLAG --log-level=%d", el->level );
+ if( el->prefix[ 0 ])
+ {
+/*
+ * FIXME: Should have smarter quoting
+ */
+ printf( " --log-prefix='%s'", el->prefix );
+ }
+}
+
+/*
+ * The version must match the iptables version exactly
+ * which is a big pain, could use `iptables -V` in makefile
+ * but we can't guarantee compatibility with all iptables
+ * so we are stuck with only supporting one particular version.
+ */
+static struct iptables_target targ =
+{
+next: 0,
+name: "TCPLAG",
+version: "1.2.3",
+size: IPT_ALIGN( sizeof( struct ipt_tcplag )),
+userspacesize: IPT_ALIGN( sizeof( struct ipt_tcplag )),
+help: &help,
+init: &init,
+parse: &parse,
+final_check: &final_check,
+print: &print,
+save: &save,
+extra_opts: opts
+};
+
+/*
+ * Always nervous trusting _init() but oh well that is the standard
+ * so have to go ahead and use it. This registers your target into
+ * the list of available targets so that your options become available.
+ */
+void _init( void ) { register_target( &targ ); }