Index: include/linux/netfilter_ipv4/ipt_ctexpire.h =================================================================== --- include/linux/netfilter_ipv4/ipt_ctexpire.h (revision 0) +++ include/linux/netfilter_ipv4/ipt_ctexpire.h (revision 0) @@ -0,0 +1,23 @@ +/* CTEXPIRE modification module for IP tables + * (C) 2004 by Richard Zheng */ + +#ifndef _IPT_CTEXPIRE_H +#define _IPT_CTEXPIRE_H + +enum { + IPT_CTEXPIRE_SET = 0, + IPT_CTEXPIRE_INC, + IPT_CTEXPIRE_DEC +}; + +#define IPT_CTEXPIRE_MAXMODE IPT_CTEXPIRE_DEC + +struct ipt_ctexpire_info { + u_int8_t mode; +#ifdef KERNEL_64_USERSPACE_32 + unsigned long long expires; +#else + unsigned long expires; +#endif +}; +#endif Index: extensions/libipt_ctexpire.c =================================================================== --- extensions/libipt_ctexpire.c (revision 0) +++ extensions/libipt_ctexpire.c (revision 0) @@ -0,0 +1,199 @@ +/* Shared library add-on to iptables for the ctexpire match + * (C) 2004 by Richard Zheng + * + * $Id: libipt_ctexpire.c,v 1.0 2004/12/01 16:08:16 richard Exp $ + * + * 020105 Converted to match -- Pablo Neira Ayuso + * + * This program is distributed under the terms of GNU GPL version 2 + */ +#include +#include +#include +#include +#include +#include + +#include +#include "../include/linux/netfilter_ipv4/ipt_ctexpire.h" + +#define IPT_CTEXPIRE_USED 1 + +static void init(struct ipt_entry_match *t, unsigned int *nfcache) +{ +} + +static void help(void) +{ + printf( +"ctexpire match v%s options\n" +" --ctexpire-set value Set conntrack expire to \n" +" --ctexpire-dec value Decrement conntrack expire by \n" +" --ctexpire-inc value Increment conntrack expire by \n" +, IPTABLES_VERSION); +} + +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_ctexpire_info *info = + (struct ipt_ctexpire_info *) (*match)->data; +#ifdef KERNEL_64_USERSPACE_32 + unsigned long long value, HZ_value; +#else + unsigned long value, HZ_value; +#endif + + if (*flags & IPT_CTEXPIRE_USED) { + exit_error(PARAMETER_PROBLEM, + "Can't specify conntrack expire option twice"); + } + + if (!optarg) + exit_error(PARAMETER_PROBLEM, + "ctexpire: You must specify a value"); + + if (check_inverse(optarg, &invert, NULL, 0)) + exit_error(PARAMETER_PROBLEM, + "ctexpire: unexpected `!'"); + +#ifdef KERNEL_64_USERSPACE_32 + if (string_to_number_ll(optarg, 0, 0, &value) == -1) + exit_error(PARAMETER_PROBLEM, + "expire value invalid: `%s'\n", optarg); +#else + if (string_to_number_l(optarg, 0, 0, &value) == -1) + exit_error(PARAMETER_PROBLEM, + "expire value invalid: `%s'\n", optarg); +#endif + + HZ_value = value*HZ; + + if (HZ_value < value) { + /* if user specified value is too big, + * *HZ can overflow the counter + */ + exit_error(PARAMETER_PROBLEM, + "expire value too big, will overflow counter: `%s'\n", optarg); + } + + switch (c) { + case '1': + info->mode = IPT_CTEXPIRE_SET; + break; + + case '2': + if (value == 0) { + exit_error(PARAMETER_PROBLEM, + "ctexpire: decreasing by 0?"); + } + + info->mode = IPT_CTEXPIRE_DEC; + break; + + case '3': + if (value == 0) { + exit_error(PARAMETER_PROBLEM, + "ctexpire: increasing by 0?"); + } + + info->mode = IPT_CTEXPIRE_INC; + break; + + default: + return 0; + + } + + info->expires = value; + *flags |= IPT_CTEXPIRE_USED; + + return 1; +} + +static void final_check(unsigned int flags) +{ + if (!(flags & IPT_CTEXPIRE_USED)) + exit_error(PARAMETER_PROBLEM, + "ctexpire: You must specify an action"); +} + +static void save(const struct ipt_ip *ip, + const struct ipt_entry_match *match) +{ + const struct ipt_ctexpire_info *info = + (struct ipt_ctexpire_info *) match->data; + + switch (info->mode) { + case IPT_CTEXPIRE_SET: + printf("--ctexpire-set "); + break; + case IPT_CTEXPIRE_DEC: + printf("--ctexpire-dec "); + break; + + case IPT_CTEXPIRE_INC: + printf("--ctexpire-inc "); + break; + } +#ifdef KERNEL_64_USERSPACE_32 + printf("%llu ", info->expires); +#else + printf("%lu ", info->expires); +#endif +} + +static void print(const struct ipt_ip *ip, + const struct ipt_entry_match *match, int numeric) +{ + const struct ipt_ctexpire_info *info = + (struct ipt_ctexpire_info *) match->data; + + printf("ctexpire "); + switch (info->mode) { + case IPT_CTEXPIRE_SET: + printf("set to "); + break; + case IPT_CTEXPIRE_DEC: + printf("decrement by "); + break; + case IPT_CTEXPIRE_INC: + printf("increment by "); + break; + } +#ifdef KERNEL_64_USERSPACE_32 + printf("%llu ", info->expires); +#else + printf("%lu ", info->expires); +#endif +} + +static struct option opts[] = { + { "ctexpire-set", 1, 0, '1' }, + { "ctexpire-dec", 1, 0, '2' }, + { "ctexpire-inc", 1, 0, '3' }, + { 0 } +}; + +static +struct iptables_match ipt_ctexpire = { + .name = "ctexpire", + .version = IPTABLES_VERSION, + .size = IPT_ALIGN(sizeof(struct ipt_ctexpire_info)), + .userspacesize = IPT_ALIGN(sizeof(struct ipt_ctexpire_info)), + .help = help, + .init = init, + .parse = parse, + .final_check = final_check, + .print = print, + .save = save, + .extra_opts = opts +}; + +void _init(void) +{ + register_match(&ipt_ctexpire); +}