1diff -uNr original/linux/include/linux/netfilter_ipv4/ipt_time.h linux/include/linux/netfilter_ipv4/ipt_time.h 2--- original/linux/include/linux/netfilter_ipv4/ipt_time.h Thu Jan 1 07:30:00 1970 3+++ linux/include/linux/netfilter_ipv4/ipt_time.h Thu Dec 6 12:27:04 2001 4@@ -0,0 +1,13 @@ 5+#ifndef __ipt_time_h_included__ 6+#define __ipt_time_h_included__ 7+ 8+ 9+struct ipt_time_info { 10+ u_int8_t days_match; /* 1 bit per day. -SMTWTFS */ 11+ u_int16_t time_start; /* 0 < time_start < 23*60+59 = 1439 */ 12+ u_int16_t time_stop; /* 0:0 < time_stat < 23:59 */ 13+ u_int8_t kerneltime; /* ignore skb time (and use kerneltime) or not. */ 14+}; 15+ 16+ 17+#endif /* __ipt_time_h_included__ */ 18diff -uNr original/linux/net/ipv4/netfilter/ipt_time.c linux/net/ipv4/netfilter/ipt_time.c 19--- original/linux/net/ipv4/netfilter/ipt_time.c Thu Jan 1 07:30:00 1970 20+++ linux/net/ipv4/netfilter/ipt_time.c Thu Dec 6 13:02:14 2001 21@@ -0,0 +1,185 @@ 22+/* 23+ This is a module which is used for time matching 24+ It is using some modified code from dietlibc (localtime() function) 25+ that you can find at http://www.fefe.de/dietlibc/ 26+ This file is distributed under the terms of the GNU General Public 27+ License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL 28+ 2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development. 29+ 2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code, 30+ thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report. 31+ 2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only. 32+ 2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack, 33+ added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones. 34+*/ 35+ 36+#include <linux/module.h> 37+#include <linux/skbuff.h> 38+#include <linux/netfilter_ipv4/ip_tables.h> 39+#include <linux/netfilter_ipv4/ipt_time.h> 40+#include <linux/time.h> 41+ 42+MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>"); 43+MODULE_DESCRIPTION("Match arrival timestamp"); 44+MODULE_LICENSE("GPL"); 45+ 46+struct tm 47+{ 48+ int tm_sec; /* Seconds. [0-60] (1 leap second) */ 49+ int tm_min; /* Minutes. [0-59] */ 50+ int tm_hour; /* Hours. [0-23] */ 51+ int tm_mday; /* Day. [1-31] */ 52+ int tm_mon; /* Month. [0-11] */ 53+ int tm_year; /* Year - 1900. */ 54+ int tm_wday; /* Day of week. [0-6] */ 55+ int tm_yday; /* Days in year.[0-365] */ 56+ int tm_isdst; /* DST. [-1/0/1]*/ 57+ 58+ long int tm_gmtoff; /* we don't care, we count from GMT */ 59+ const char *tm_zone; /* we don't care, we count from GMT */ 60+}; 61+ 62+void 63+localtime(const time_t *timepr, struct tm *r); 64+ 65+static int 66+match(const struct sk_buff *skb, 67+ const struct net_device *in, 68+ const struct net_device *out, 69+ const void *matchinfo, 70+ int offset, 71+ const void *hdr, 72+ u_int16_t datalen, 73+ int *hotdrop) 74+{ 75+ const struct ipt_time_info *info = matchinfo; /* match info for rule */ 76+ struct tm currenttime; /* time human readable */ 77+ u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1}; 78+ u_int16_t packet_time; 79+ struct timeval kerneltimeval; 80+ time_t packet_local_time; 81+ 82+ /* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */ 83+ if (info->kerneltime) 84+ { 85+ do_gettimeofday(&kerneltimeval); 86+ packet_local_time = kerneltimeval.tv_sec; 87+ } 88+ else 89+ packet_local_time = skb->stamp.tv_sec; 90+ 91+ /* Transform the timestamp of the packet, in a human readable form */ 92+ localtime(&packet_local_time, ¤ttime); 93+ 94+ /* check if we match this timestamp, we start by the days... */ 95+ if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday]) 96+ return 0; /* the day doesn't match */ 97+ 98+ /* ... check the time now */ 99+ packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min; 100+ if ((packet_time < info->time_start) || (packet_time > info->time_stop)) 101+ return 0; 102+ 103+ /* here we match ! */ 104+ return 1; 105+} 106+ 107+static int 108+checkentry(const char *tablename, 109+ const struct ipt_ip *ip, 110+ void *matchinfo, 111+ unsigned int matchsize, 112+ unsigned int hook_mask) 113+{ 114+ struct ipt_time_info *info = matchinfo; /* match info for rule */ 115+ 116+ /* First, check that we are in the correct hook */ 117+ /* PRE_ROUTING, LOCAL_IN or FROWARD */ 118+ if (hook_mask 119+ & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))) 120+ { 121+ printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n"); 122+ return 0; 123+ } 124+ /* we use the kerneltime if we are in forward or output */ 125+ info->kerneltime = 1; 126+ if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))) 127+ /* if not, we use the skb time */ 128+ info->kerneltime = 0; 129+ 130+ /* Check the size */ 131+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info))) 132+ return 0; 133+ /* Now check the coherence of the data ... */ 134+ if ((info->time_start > 1439) || /* 23*60+59 = 1439*/ 135+ (info->time_stop > 1439)) 136+ { 137+ printk(KERN_WARNING "ipt_time: invalid argument\n"); 138+ return 0; 139+ } 140+ 141+ return 1; 142+} 143+ 144+static struct ipt_match time_match 145+= { { NULL, NULL }, "time", &match, &checkentry, NULL, THIS_MODULE }; 146+ 147+static int __init init(void) 148+{ 149+ printk("ipt_time loading\n"); 150+ return ipt_register_match(&time_match); 151+} 152+ 153+static void __exit fini(void) 154+{ 155+ ipt_unregister_match(&time_match); 156+ printk("ipt_time unloaded\n"); 157+} 158+ 159+module_init(init); 160+module_exit(fini); 161+ 162+ 163+/* The part below is borowed and modified from dietlibc */ 164+ 165+/* seconds per day */ 166+#define SPD 24*60*60 167+ 168+void 169+localtime(const time_t *timepr, struct tm *r) { 170+ time_t i; 171+ time_t timep; 172+ extern struct timezone sys_tz; 173+ const unsigned int __spm[12] = 174+ { 0, 175+ (31), 176+ (31+28), 177+ (31+28+31), 178+ (31+28+31+30), 179+ (31+28+31+30+31), 180+ (31+28+31+30+31+30), 181+ (31+28+31+30+31+30+31), 182+ (31+28+31+30+31+30+31+31), 183+ (31+28+31+30+31+30+31+31+30), 184+ (31+28+31+30+31+30+31+31+30+31), 185+ (31+28+31+30+31+30+31+31+30+31+30), 186+ }; 187+ register time_t work; 188+ 189+ timep = (*timepr) - (sys_tz.tz_minuteswest * 60); 190+ work=timep%(SPD); 191+ r->tm_sec=work%60; work/=60; 192+ r->tm_min=work%60; r->tm_hour=work/60; 193+ work=timep/(SPD); 194+ r->tm_wday=(4+work)%7; 195+ for (i=1970; ; ++i) { 196+ register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365; 197+ if (work>k) 198+ work-=k; 199+ else 200+ break; 201+ } 202+ r->tm_year=i-1900; 203+ for (i=11; i && __spm[i]>work; --i) ; 204+ r->tm_mon=i; 205+ r->tm_mday=work-__spm[i]+1; 206+} 207