xt_time 20070820

Jan Engelhardt jengelh at computergmbh.de
Mon Aug 20 21:19:35 CEST 2007


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


More information about the netfilter-devel mailing list