Mailing List Archive

xt_time 20070820
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@gmx.de>, 2007
+ *
+ * based on ipt_time by Fabrice MARIE <fabrice@netfilter.org>
+ * 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, &current_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@computergmbh.de>");
+MODULE_DESCRIPTION("netfilter time match");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_time");
+MODULE_ALIAS("ip6t_time");