
jengelh at computergmbh
Aug 20, 2007, 12:19 PM
Post #1 of 1
(481 views)
Permalink
|
Hi, this is xt_time, posted for reference and discussion. Not perfect yet, but a start. <<< ipt_time from POM-ng augmented by: * xtables * ipv6 support It does have timezone support, BTW. --- include/linux/netfilter/xt_time.h | 26 +++++ net/netfilter/Kconfig | 15 +++ net/netfilter/Makefile | 1 net/netfilter/xt_time.c | 183 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 225 insertions(+) Index: linux-2.6.22.3/include/linux/netfilter/xt_time.h =================================================================== --- /dev/null +++ linux-2.6.22.3/include/linux/netfilter/xt_time.h @@ -0,0 +1,26 @@ +#ifndef _XT_TIME_H +#define _XT_TIME_H 1 + +enum { + XT_TIME_MONDAY = 1 << 1, + XT_TIME_TUESDAY = 1 << 2, + XT_TIME_WEDNESDAY = 1 << 3, + XT_TIME_THURSDAY = 1 << 4, + XT_TIME_FRIDAY = 1 << 5, + XT_TIME_SATURDAY = 1 << 6, + XT_TIME_SUNDAY = 1 << 7, +}; + +struct xt_time_info { + u_int8_t days_match; /* 1 bit per day. -SMTWTFS */ + u_int16_t time_start; /* 0 < time_start < 23*60+59 = 1439 */ + u_int16_t time_stop; /* 0:0 < time_stat < 23:59 */ + + /* FIXME: Keep this one for userspace iptables binary compability: */ + u_int8_t kerneltime; /* ignore skb time (and use kerneltime) or not. */ + + time_t date_start; + time_t date_stop; +}; + +#endif /* _XT_TIME_H */ Index: linux-2.6.22.3/net/netfilter/Kconfig =================================================================== --- linux-2.6.22.3.orig/net/netfilter/Kconfig +++ linux-2.6.22.3/net/netfilter/Kconfig @@ -635,6 +635,21 @@ config NETFILTER_XT_MATCH_TCPMSS To compile it as a module, choose M here. If unsure, say N. +config NETFILTER_XT_MATCH_TIME + tristate '"time" match support' + depends on NETFILTER_XTABLES + ---help--- + This option adds a "time" match, which allows you to match based on + the packet arrival time/date (arrival time/date at the machine which + netfilter is running on) or departure time/date (for locally + generated packets). + + If you say Y here, try `iptables -m time --help` for + more information. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say N. + config NETFILTER_XT_MATCH_HASHLIMIT tristate '"hashlimit" match support' depends on NETFILTER_XTABLES && (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n) Index: linux-2.6.22.3/net/netfilter/Makefile =================================================================== --- linux-2.6.22.3.orig/net/netfilter/Makefile +++ linux-2.6.22.3/net/netfilter/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o +obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o Index: linux-2.6.22.3/net/netfilter/xt_time.c =================================================================== --- /dev/null +++ linux-2.6.22.3/net/netfilter/xt_time.c @@ -0,0 +1,183 @@ +/* + * xt_time + * Copyright © Jan Engelhardt <jengelh [at] gmx>, 2007 + * + * based on ipt_time by Fabrice MARIE <fabrice [at] netfilter> + * This is a module which is used for time matching + * It is using some modified code from dietlibc (localtime() function) + * that you can find at http://www.fefe.de/dietlibc/ + * This file is distributed under the terms of the GNU General Public + * License (GPL). Copies of the GPL can be obtained from gnu.org/gpl. + */ +#include <linux/ktime.h> +#include <linux/module.h> +#include <linux/skbuff.h> +#include <linux/netfilter/x_tables.h> +#include <linux/netfilter/xt_time.h> + +struct tm { + int tm_min; /* Minutes. [0-59] */ + int tm_hour; /* Hours. [0-23] */ + int tm_mday; /* Day. [1-31] */ + int tm_mon; /* Month. [0-11] */ + int tm_year; /* Year - 1900. */ + int tm_wday; /* Day of week. [0-6] */ + int tm_yday; /* Days in year.[0-365] */ +}; + +/* The localtime() function is borowed and modified from dietlibc */ +static void localtime(const u_int32_t time, struct tm *r) +{ + u_int32_t i, timep; + extern struct timezone sys_tz; + static const unsigned int __spm[] = { + 0, + 31, + 31+28, + 31+28+31, + 31+28+31+30, + 31+28+31+30+31, + 31+28+31+30+31+30, + 31+28+31+30+31+30+31, + 31+28+31+30+31+30+31+31, + 31+28+31+30+31+30+31+31+30, + 31+28+31+30+31+30+31+31+30+31, + 31+28+31+30+31+30+31+31+30+31+30, + }; + u_int32_t work; + + timep = time - 60 * sys_tz.tz_minuteswest; + work = timep % 86400; /* 1d = 86400s */ + work /= 60; + r->tm_min = work % 60; + r->tm_hour = work / 60; + work = timep / 86400; + r->tm_wday = (4 + work) % 7; + for (i = 1970; ; ++i) { + time_t k = (!(i % 4) && ((i % 100) || !(i % 400))) ? 366 : 365; + if (work > k) + work -= k; + else + break; + } + r->tm_year = i - 1900; + for (i = 11; i && __spm[i] > work; --i) + ; + r->tm_mon = i; + r->tm_mday = work - __spm[i] + 1; +} + +static const u_int8_t days_of_week[] = { + 0, + XT_TIME_MONDAY, + XT_TIME_TUESDAY, + XT_TIME_WEDNESDAY, + XT_TIME_THURSDAY, + XT_TIME_FRIDAY, + XT_TIME_SATURDAY, + XT_TIME_SUNDAY, +}; + +static int xt_time_match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct xt_match *match, const void *matchinfo, + int offset, unsigned int protoff, int *hotdrop) +{ + const struct xt_time_info *info = matchinfo; + struct tm current_time; + unsigned int packet_time; + struct timeval stamp; + + /* We might not have a timestamp, get one */ + if (skb->tstamp.tv64 == 0) + __net_timestamp((struct sk_buff *)skb); + + skb_get_timestamp(skb, &stamp); + + /* First we make sure we are in the date start-stop boundaries */ + if (stamp.tv_sec < info->date_start || stamp.tv_sec > info->date_stop) + /* We are outside the date boundaries */ + return false; + + /* Transform the timestamp of the packet, in a human readable form */ + localtime(stamp.tv_sec, ¤t_time); + + /* check if we match this timestamp, we start by the days... */ + if (!(info->days_match & days_of_week[current_time.tm_wday])) + /* the day does not match */ + return false; + + /* + * Check the time now, both vesions: + * "start < stop" and "start > stop" (midnight cross) + */ + packet_time = current_time.tm_hour * 60 + current_time.tm_min; + printk(KERN_WARNING "stamp: %lu, pkt_time: %u, tstart: %u, tstop: %u\n", + stamp.tv_sec, + packet_time, info->time_start, info->time_stop); + if (info->time_start < info->time_stop) { + if (packet_time < info->time_start || + packet_time > info->time_stop) + return false; + } else { + if (packet_time < info->time_start && + packet_time > info->time_stop) + return false; + } + + return true; +} + +static int xt_time_check(const char *tablename, const void *ip, + const struct xt_match *match, void *matchinfo, + unsigned int hook_mask) +{ + struct xt_time_info *info = matchinfo; + + /* xt_time's granularity is a minute, hence 24*60 = 1day */ + if (info->time_start >= 24 * 60 || info->time_stop >= 24 * 60) { + printk(KERN_WARNING KBUILD_MODNAME ": invalid argument - " + "start or stop time greater than 23:59h\n"); + return false; + } + + return true; +} + +static struct xt_match xt_time_reg[] __read_mostly = { + { + .name = "time", + .family = AF_INET, + .match = xt_time_match, + .matchsize = sizeof(struct xt_time_info), + .checkentry = xt_time_check, + .me = THIS_MODULE, + }, + { + .name = "time", + .family = AF_INET6, + .match = xt_time_match, + .matchsize = sizeof(struct xt_time_info), + .checkentry = xt_time_check, + .me = THIS_MODULE, + }, +}; + +static int __init xt_time_init(void) +{ + return xt_register_matches(xt_time_reg, ARRAY_SIZE(xt_time_reg)); +} + +static void __exit xt_time_exit(void) +{ + xt_unregister_matches(xt_time_reg, ARRAY_SIZE(xt_time_reg)); +} + +module_init(xt_time_init); +module_exit(xt_time_exit); +MODULE_AUTHOR("Jan Engelhardt <jengelh [at] computergmbh>"); +MODULE_DESCRIPTION("netfilter time match"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("ipt_time"); +MODULE_ALIAS("ip6t_time");
|