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