--- /dev/null 2004-09-23 01:18:13.000000000 +0200 +++ net/ipv4/netfilter/ipt_ctexpire.c 2005-01-02 01:15:04.000000000 +0100 @@ -0,0 +1,132 @@ +/* ctexpire modification match for IP tables + * (C) 2004 by Richard Zheng + * + * 020105 -- converted to match. Pablo Neira Ayuso + * + * Version: 1.1 + * + * This software is distributed under the terms of GNU GPL version 2 + */ + +#include +#include +#include +#include + +#include +#include +#include + +MODULE_AUTHOR("Richard Zheng "); +MODULE_DESCRIPTION("IP tables ctexpire modification module"); +MODULE_LICENSE("GPL"); + +static int +ipt_ctexpire_match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop) +{ + const struct ipt_ctexpire_info *info = matchinfo; + unsigned long new_expires = 0UL; + enum ip_conntrack_info ctinfo; + struct ip_conntrack *ct = ip_conntrack_get(skb, &ctinfo); + + if (ct == NULL) + return 0; + + IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct); + + new_expires = info->expires*HZ; + +#ifdef EXTRADEBUG + DEBUGP(KERN_WARNING "ctexpire: fired = %s, mode %d, value %ld\n", + !is_confirmed(ct) ? "no" : "yes", info->mode, info->expires); + unsigned long enter = ct->timeout.expires; +#endif + + switch (info->mode) { + case IPT_CTEXPIRE_SET: + break; + case IPT_CTEXPIRE_INC: + /* If not in hash table, timer will not be active yet */ + if (!is_confirmed(ct)) + /* TODO should we check if counter overflow? + * other kernel function didn't check this */ + new_expires += ct->timeout.expires; + else + new_expires += ct->timeout.expires - jiffies; + break; + case IPT_CTEXPIRE_DEC: + /* If not in hash table, timer will not be active yet */ + if (!is_confirmed(ct)) { + new_expires = (ct->timeout.expires <= new_expires) ? + 0 : (ct->timeout.expires - new_expires); + } else { + new_expires = + (ct->timeout.expires - jiffies <= new_expires) ? + 0 : (ct->timeout.expires - jiffies - new_expires); + } + break; + default: + /* Shouldn't happen */ + break; + } + + + ip_ct_refresh_acct(ct, 0, NULL, new_expires); + +#ifdef EXTRADEBUG + printk(KERN_WARNING + "ctexpire: enter = %ld/%ld, exit = %ld/%ld, diff = %ld\n", + enter, enter-jiffies, ct->timeout.expires, + ct->timeout.expires-jiffies, ct->timeout.expires - enter); +#endif + + return 0; +} + +static int +ipt_ctexpire_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_ctexpire_info))) { + printk(KERN_WARNING "ctexpire: targinfosize %u != %Zu\n", + matchsize, + IPT_ALIGN(sizeof(struct ipt_ctexpire_info))); + return 0; + } + + if (strcmp(tablename, "raw") == 0) { + printk(KERN_WARNING "ctexpire can't be used in the raw' table"); + return 0; + } + + return 1; +} + +static struct ipt_match ipt_ctexpire = { + .name = "ctexpire", + .match = ipt_ctexpire_match, + .checkentry = ipt_ctexpire_checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ipt_register_match(&ipt_ctexpire); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&ipt_ctexpire); +} + +module_init(init); +module_exit(fini); + --- /dev/null 2004-09-23 01:18:13.000000000 +0200 +++ include/linux/netfilter_ipv4/ipt_ctexpire.h 2005-01-02 00:18:18.000000000 +0100 @@ -0,0 +1,19 @@ +/* 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; + unsigned long expires; +}; +#endif