From 82abdf38ef4989c0b9038b5f87c6bd2a46304966 Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 24 Aug 2003 08:07:57 +0000 Subject: add TCPLAG target (patch was lost on notebook drive) --- extensions/.TCPLAG-test | 2 + extensions/libipt_TCPLAG.c | 228 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100755 extensions/.TCPLAG-test create mode 100644 extensions/libipt_TCPLAG.c 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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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 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 ); } -- cgit v1.2.3