34257ee93cf308adb344934be867c9244061e2a0
[openwrt.git] / target / linux / generic-2.6 / patches / 105-netfilter_time.patch
1 diff -urN linux-2.6.15-rc6.orig/net/ipv4/netfilter/ipt_time.c linux-2.6.15-rc6/net/ipv4/netfilter/ipt_time.c
2 --- linux-2.6.15-rc6.orig/net/ipv4/netfilter/ipt_time.c 1970-01-01 01:00:00.000000000 +0100
3 +++ linux-2.6.15-rc6/net/ipv4/netfilter/ipt_time.c      2006-01-07 13:02:59.000000000 +0100
4 @@ -0,0 +1,178 @@
5 +/*
6 +  This is a module which is used for time matching
7 +  It is using some modified code from dietlibc (localtime() function)
8 +  that you can find at http://www.fefe.de/dietlibc/
9 +  This file is distributed under the terms of the GNU General Public
10 +  License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL
11 +  2001-05-04 Fabrice MARIE <fabrice@netfilter.org> : initial development.
12 +  2001-21-05 Fabrice MARIE <fabrice@netfilter.org> : bug fix in the match code,
13 +     thanks to "Zeng Yu" <zengy@capitel.com.cn> for bug report.
14 +  2001-26-09 Fabrice MARIE <fabrice@netfilter.org> : force the match to be in LOCAL_IN or PRE_ROUTING only.
15 +  2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack,
16 +     added Nguyen Dang Phuoc Dong <dongnd@tlnet.com.vn> patch to support timezones.
17 +  2004-05-02 Fabrice : added support for date matching, from an idea of Fabien COELHO.
18 +*/
19 +
20 +#include <linux/module.h>
21 +#include <linux/skbuff.h>
22 +#include <linux/netfilter_ipv4/ip_tables.h>
23 +#include <linux/netfilter_ipv4/ipt_time.h>
24 +#include <linux/time.h>
25 +
26 +MODULE_AUTHOR("Fabrice MARIE <fabrice@netfilter.org>");
27 +MODULE_DESCRIPTION("Match arrival timestamp/date");
28 +MODULE_LICENSE("GPL");
29 +
30 +struct tm
31 +{
32 +       int tm_sec;                   /* Seconds.     [0-60] (1 leap second) */
33 +       int tm_min;                   /* Minutes.     [0-59] */
34 +       int tm_hour;                  /* Hours.       [0-23] */
35 +       int tm_mday;                  /* Day.         [1-31] */
36 +       int tm_mon;                   /* Month.       [0-11] */
37 +       int tm_year;                  /* Year - 1900.  */
38 +       int tm_wday;                  /* Day of week. [0-6] */
39 +       int tm_yday;                  /* Days in year.[0-365] */
40 +       int tm_isdst;                 /* DST.         [-1/0/1]*/
41 +
42 +       long int tm_gmtoff;           /* we don't care, we count from GMT */
43 +       const char *tm_zone;          /* we don't care, we count from GMT */
44 +};
45 +
46 +void
47 +localtime(const u32 time, struct tm *r);
48 +
49 +static int
50 +match(const struct sk_buff *skb,
51 +      const struct net_device *in,
52 +      const struct net_device *out,
53 +      const void *matchinfo,
54 +      int offset,
55 +      int *hotdrop)
56 +{
57 +       const struct ipt_time_info *info = matchinfo;   /* match info for rule */
58 +       struct tm currenttime;                          /* time human readable */
59 +       u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
60 +       u_int16_t packet_time;
61 +
62 +       /* We might not have a timestamp, get one */
63 +       if (skb->tstamp.off_sec == 0)
64 +               __net_timestamp((struct sk_buff *)skb);
65 +
66 +       /* First we make sure we are in the date start-stop boundaries */
67 +       if ((skb->tstamp.off_sec < info->date_start) || (skb->tstamp.off_sec > info->date_stop))
68 +               return 0; /* We are outside the date boundaries */
69 +
70 +       /* Transform the timestamp of the packet, in a human readable form */
71 +       localtime(skb->tstamp.off_sec, &currenttime);
72 +
73 +       /* check if we match this timestamp, we start by the days... */
74 +       if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday])
75 +               return 0; /* the day doesn't match */
76 +
77 +       /* ... check the time now */
78 +       packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min;
79 +       if ((packet_time < info->time_start) || (packet_time > info->time_stop))
80 +               return 0;
81 +
82 +       /* here we match ! */
83 +       return 1;
84 +}
85 +
86 +static int
87 +checkentry(const char *tablename,
88 +           const struct ipt_ip *ip,
89 +           void *matchinfo,
90 +           unsigned int matchsize,
91 +           unsigned int hook_mask)
92 +{
93 +       struct ipt_time_info *info = matchinfo;   /* match info for rule */
94 +
95 +       /* First, check that we are in the correct hooks */
96 +       if (hook_mask
97 +            & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
98 +       {
99 +               printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n");
100 +               return 0;
101 +       }
102 +
103 +       /* Check the size */
104 +       if (matchsize != IPT_ALIGN(sizeof(struct ipt_time_info)))
105 +               return 0;
106 +       /* Now check the coherence of the data ... */
107 +       if ((info->time_start > 1439) ||        /* 23*60+59 = 1439*/
108 +           (info->time_stop  > 1439))
109 +       {
110 +               printk(KERN_WARNING "ipt_time: invalid argument\n");
111 +               return 0;
112 +       }
113 +
114 +       return 1;
115 +}
116 +
117 +static struct ipt_match time_match = {
118 +       .name = "time",
119 +       .match = &match,
120 +       .checkentry = &checkentry,
121 +       .me = THIS_MODULE
122 +};
123 +
124 +static int __init init(void)
125 +{
126 +       printk("ipt_time loading\n");
127 +       return ipt_register_match(&time_match);
128 +}
129 +
130 +static void __exit fini(void)
131 +{
132 +       ipt_unregister_match(&time_match);
133 +       printk("ipt_time unloaded\n");
134 +}
135 +
136 +module_init(init);
137 +module_exit(fini);
138 +
139 +
140 +/* The part below is borowed and modified from dietlibc */
141 +
142 +/* seconds per day */
143 +#define SPD 24*60*60
144 +
145 +void
146 +localtime(const u32 time, struct tm *r) {
147 +       u32 i, timep;
148 +       extern struct timezone sys_tz;
149 +       const unsigned int __spm[12] =
150 +               { 0,
151 +                 (31),
152 +                 (31+28),
153 +                 (31+28+31),
154 +                 (31+28+31+30),
155 +                 (31+28+31+30+31),
156 +                 (31+28+31+30+31+30),
157 +                 (31+28+31+30+31+30+31),
158 +                 (31+28+31+30+31+30+31+31),
159 +                 (31+28+31+30+31+30+31+31+30),
160 +                 (31+28+31+30+31+30+31+31+30+31),
161 +                 (31+28+31+30+31+30+31+31+30+31+30),
162 +               };
163 +       register u32 work;
164 +
165 +       timep = time - (sys_tz.tz_minuteswest * 60);
166 +       work=timep%(SPD);
167 +       r->tm_sec=work%60; work/=60;
168 +       r->tm_min=work%60; r->tm_hour=work/60;
169 +       work=timep/(SPD);
170 +       r->tm_wday=(4+work)%7;
171 +       for (i=1970; ; ++i) {
172 +               register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365;
173 +               if (work>k)
174 +                       work-=k;
175 +               else
176 +                       break;
177 +       }
178 +       r->tm_year=i-1900;
179 +       for (i=11; i && __spm[i]>work; --i) ;
180 +       r->tm_mon=i;
181 +       r->tm_mday=work-__spm[i]+1;
182 +}
183 diff -urN linux-2.6.15-rc6.orig/net/ipv4/netfilter/Kconfig linux-2.6.15-rc6/net/ipv4/netfilter/Kconfig
184 --- linux-2.6.15-rc6.orig/net/ipv4/netfilter/Kconfig    2006-01-07 13:00:21.000000000 +0100
185 +++ linux-2.6.15-rc6/net/ipv4/netfilter/Kconfig 2006-01-07 13:05:07.000000000 +0100
186 @@ -278,6 +278,22 @@
187  
188           To compile it as a module, choose M here.  If unsure, say N.
189  
190 +         
191 +config IP_NF_MATCH_TIME
192 +       tristate  'TIME match support'
193 +       depends on IP_NF_IPTABLES
194 +       help
195 +         This option adds a `time' match, which allows you
196 +         to match based on the packet arrival time/date
197 +         (arrival time/date at the machine which netfilter is running on) or
198 +         departure time/date (for locally generated packets).
199 +         
200 +         If you say Y here, try iptables -m time --help for more information.
201 +         If you want to compile it as a module, say M here and read
202 +         
203 +         Documentation/modules.txt.  If unsure, say `N'.
204 +
205 +
206  config IP_NF_MATCH_RECENT
207         tristate "recent match support"
208         depends on IP_NF_IPTABLES
209 diff -urN linux-2.6.15-rc6.orig/net/ipv4/netfilter/Makefile linux-2.6.15-rc6/net/ipv4/netfilter/Makefile
210 --- linux-2.6.15-rc6.orig/net/ipv4/netfilter/Makefile   2006-01-07 13:00:21.000000000 +0100
211 +++ linux-2.6.15-rc6/net/ipv4/netfilter/Makefile        2006-01-07 13:03:50.000000000 +0100
212 @@ -58,6 +58,7 @@
213  obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
214  obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
215  obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
216 +obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o
217  obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
218  obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
219  obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o
220 diff -urN linux-2.6.15-rc6.orig/include/linux/netfilter_ipv4/ipt_time.h linux-2.6.15-rc6/include/linux/netfilter_ipv4/ipt_time.h
221 --- linux-2.6.15-rc6.orig/include/linux/netfilter_ipv4/ipt_time.h       1970-01-01 01:00:00.000000000 +0100
222 +++ linux-2.6.15-rc6/include/linux/netfilter_ipv4/ipt_time.h    2006-01-07 13:02:14.000000000 +0100
223 @@ -0,0 +1,18 @@
224 +#ifndef __ipt_time_h_included__
225 +#define __ipt_time_h_included__
226 +
227 +
228 +struct ipt_time_info {
229 +       u_int8_t  days_match;   /* 1 bit per day. -SMTWTFS                      */
230 +       u_int16_t time_start;   /* 0 < time_start < 23*60+59 = 1439             */
231 +       u_int16_t time_stop;    /* 0:0 < time_stat < 23:59                      */
232 +
233 +                               /* FIXME: Keep this one for userspace iptables binary compability: */
234 +       u_int8_t  kerneltime;   /* ignore skb time (and use kerneltime) or not. */
235 +
236 +       time_t    date_start;
237 +       time_t    date_stop;
238 +};
239 +
240 +
241 +#endif /* __ipt_time_h_included__ */