From cc9b061e7ccb9e568b3fad6c6c578c75ce9f0cfb Mon Sep 17 00:00:00 2001 From: laforge Date: Wed, 17 Oct 2001 08:08:26 +0000 Subject: nth match extension by Rick Wagner --- extensions/libipt_nth.c | 78 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/extensions/libipt_nth.c b/extensions/libipt_nth.c index efeb71b..d0c4a77 100644 --- a/extensions/libipt_nth.c +++ b/extensions/libipt_nth.c @@ -6,6 +6,11 @@ ftp://prep.ai.mit.edu/pub/gnu/GPL 2001-07-17 Fabrice MARIE : initial development. + 2001-09-20 Richard Wagner (rwagner@cloudnet.com) + * added support for multiple counters + * added support for matching on individual packets + in the counter cycle + */ #include @@ -25,17 +30,24 @@ help(void) { printf( "nth v%s options:\n" -" --every Nth Match every Nth packet.\n\n", -" [--start] counter Initialize the counter at the number 'counter'\n" -" instead of 0. Must be of the form :\n" -" 0 <= counter <= (nth-1)" -" Example if nth=2 : 0 <= counter <= 1\n\n" -NETFILTER_VERSION); +" --every Nth Match every Nth packet\n" +" [--counter] num Use counter 0-%u (default:0)\n" +" [--start] num Initialize the counter at the number 'num'\n" +" instead of 0. Must be between 0 and Nth-1\n" +" [--packet] num Match on 'num' packet. Must be between 0\n" +" and Nth-1.\n\n" +" If --packet is used for a counter than\n" +" there must be Nth number of --packet\n" +" rules, covering all values between 0 and\n" +" Nth-1 inclusively.\n", +NETFILTER_VERSION, IPT_NTH_NUM_COUNTERS-1); } static struct option opts[] = { { "every", 1, 0, '1' }, { "start", 1, 0, '2' }, + { "counter", 1, 0, '3' }, + { "packet", 1, 0, '4' }, { 0 } }; @@ -49,6 +61,8 @@ init(struct ipt_entry_match *m, unsigned int *nfcache) #define IPT_NTH_OPT_EVERY 0x01 #define IPT_NTH_OPT_NOT_EVERY 0x02 #define IPT_NTH_OPT_START 0x04 +#define IPT_NTH_OPT_COUNTER 0x08 +#define IPT_NTH_OPT_PACKET 0x10 /* Function which parses command options; returns true if it ate an option */ @@ -86,6 +100,11 @@ parse(int c, char **argv, int invert, unsigned int *flags, /* assign the values */ nthinfo->every = num-1; nthinfo->startat = 0; + nthinfo->packet = 0xFF; + if(!(*flags & IPT_NTH_OPT_EVERY)) + { + nthinfo->counter = 0; + } if (invert) { *flags |= IPT_NTH_OPT_NOT_EVERY; @@ -115,6 +134,42 @@ parse(int c, char **argv, int invert, unsigned int *flags, *flags |= IPT_NTH_OPT_START; nthinfo->startat = num; break; + case '3': + /* check for common mistakes... */ + if (invert) + exit_error(PARAMETER_PROBLEM, + "Can't specify with ! --counter"); + if (*flags & IPT_NTH_OPT_COUNTER) + exit_error(PARAMETER_PROBLEM, + "Can't specify --counter twice"); + if (string_to_number(optarg, 0, IPT_NTH_NUM_COUNTERS-1, &num) == -1) + exit_error(PARAMETER_PROBLEM, + "bad --counter `%s', must between 0 and %u", optarg, IPT_NTH_NUM_COUNTERS-1); + /* assign the values */ + *flags |= IPT_NTH_OPT_COUNTER; + nthinfo->counter = num; + break; + case '4': + /* check for common mistakes... */ + if (!((*flags & IPT_NTH_OPT_EVERY) || + (*flags & IPT_NTH_OPT_NOT_EVERY))) + exit_error(PARAMETER_PROBLEM, + "Can't specify --packet before --every"); + if ((*flags & IPT_NTH_OPT_NOT_EVERY)) + exit_error(PARAMETER_PROBLEM, + "Can't specify --packet with ! --every"); + if (invert) + exit_error(PARAMETER_PROBLEM, + "Can't specify with ! --packet"); + if (*flags & IPT_NTH_OPT_PACKET) + exit_error(PARAMETER_PROBLEM, + "Can't specify --packet twice"); + if (string_to_number(optarg, 0, nthinfo->every, &num) == -1) + exit_error(PARAMETER_PROBLEM, + "bad --packet `%s', must between 0 and %u", optarg, nthinfo->every); + *flags |= IPT_NTH_OPT_PACKET; + nthinfo->packet = num; + break; default: return 0; } @@ -138,8 +193,12 @@ print(const struct ipt_ip *ip, if (nthinfo->not == 1) printf(" !"); printf("every %uth ", (nthinfo->every +1)); + if (nthinfo->counter != 0) + printf("counter #%u ", (nthinfo->counter)); + if (nthinfo->packet != 0xFF) + printf("packet #%u ", nthinfo->packet); if (nthinfo->startat != 0) - printf(" start at %u ", nthinfo->startat); + printf("start at %u ", nthinfo->startat); } /* Saves the union ipt_targinfo in parsable form to stdout. */ @@ -152,8 +211,11 @@ save(const struct ipt_ip *ip, const struct ipt_entry_match *match) if (nthinfo->not == 1) printf("! "); printf("--every %u ", (nthinfo->every +1)); + printf("--counter %u ", (nthinfo->counter)); if (nthinfo->startat != 0) - printf(" --start %u", nthinfo->startat ); + printf("--start %u ", nthinfo->startat ); + if (nthinfo->packet != 0xFF) + printf("--packet %u ", nthinfo->packet ); } struct iptables_match nth -- cgit v1.2.3