1 /* Shared library add-on to iptables to add TIME matching support. */
9 #include <linux/netfilter_ipv4/ipt_time.h>
12 static int globaldays;
14 /* Function which prints out usage message. */
20 " --timestart value --timestop value --days listofdays\n"
21 " timestart value : HH:MM\n"
22 " timestop value : HH:MM\n"
23 " listofdays value: a list of days to apply -> ie. Mon,Tue,Wed,Thu,Fri. Case sensitive\n",
27 static struct option opts[] = {
28 { "timestart", 1, 0, '1' },
29 { "timestop", 1, 0, '2' },
34 /* Initialize the match. */
36 init(struct ipt_entry_match *m, unsigned int *nfcache)
38 /* caching not yet implemented */
39 *nfcache |= NFC_UNKNOWN;
44 * param: part1, a pointer on a string 2 chars maximum long string, that will contain the hours.
45 * param: part2, a pointer on a string 2 chars maximum long string, that will contain the minutes.
46 * param: str_2_parse, the string to parse.
47 * return: 1 if ok, 0 if error.
50 split_time(char **part1, char **part2, const char *str_2_parse)
52 unsigned short int i,j=0;
53 char *rpart1 = *part1;
54 char *rpart2 = *part2;
55 unsigned char found_column = 0;
57 /* Check the length of the string */
58 if (strlen(str_2_parse) > 5)
60 /* parse the first part until the ':' */
63 if (str_2_parse[i] == ':')
66 rpart1[i] = str_2_parse[i];
71 /* parse the second part */
72 for (; i<strlen(str_2_parse); i++)
74 rpart2[i-j] = str_2_parse[i];
76 /* if we are here, format should be ok. */
81 parse_time_string(unsigned int *hour, unsigned int *minute, const char *time)
86 hours = (char *)malloc(3);
87 minutes = (char *)malloc(3);
88 bzero((void *)hours, 3);
89 bzero((void *)minutes, 3);
91 if (split_time(&hours, &minutes, time) == 1)
93 /* if the number starts with 0, replace it with a space else
94 this string_to_number will interpret it as octal !! */
95 if ((hours[0] == '0') && (hours[1] != '\0'))
97 if ((minutes[0] == '0') && (minutes[1] != '\0'))
100 if((string_to_number(hours, 0, 23, hour) == -1) ||
101 (string_to_number(minutes, 0, 59, minute) == -1)) {
102 *hour = *minute = (-1);
105 if ((*hour != (-1)) && (*minute != (-1))) {
111 /* If we are here, there was a problem ..*/
112 exit_error(PARAMETER_PROBLEM,
113 "invalid time `%s' specified, should be HH:MM format", time);
116 /* return 1->ok, return 0->error */
118 parse_day(int *days, int from, int to, const char *string)
121 char *days_str[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
122 unsigned short int days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
125 dayread = (char *)malloc(4);
127 if ((to-from) != 3) {
131 for (i=from; i<to; i++)
132 dayread[i-from] = string[i];
134 if (strcmp(dayread, days_str[i]) == 0)
136 *days |= days_of_week[i];
140 /* if we are here, we didn't read a valid day */
146 parse_days_string(int *days, const char *daystring)
150 char *err = "invalid days `%s' specified, should be Sun,Mon,Tue... format";
152 len = strlen(daystring);
154 exit_error(PARAMETER_PROBLEM, err, daystring);
157 if (parse_day(days, i, i+3, daystring) == 0)
158 exit_error(PARAMETER_PROBLEM, err, daystring);
163 #define IPT_TIME_START 0x01
164 #define IPT_TIME_STOP 0x02
165 #define IPT_TIME_DAYS 0x04
168 /* Function which parses command options; returns true if it
171 parse(int c, char **argv, int invert, unsigned int *flags,
172 const struct ipt_entry *entry,
173 unsigned int *nfcache,
174 struct ipt_entry_match **match)
176 struct ipt_time_info *timeinfo = (struct ipt_time_info *)(*match)->data;
184 exit_error(PARAMETER_PROBLEM,
185 "unexpected '!' with --timestart");
186 if (*flags & IPT_TIME_START)
187 exit_error(PARAMETER_PROBLEM,
188 "Can't specify --timestart twice");
189 parse_time_string(&hours, &minutes, optarg);
190 timeinfo->time_start = (hours * 60) + minutes;
191 *flags |= IPT_TIME_START;
196 exit_error(PARAMETER_PROBLEM,
197 "unexpected '!' with --timestop");
198 if (*flags & IPT_TIME_STOP)
199 exit_error(PARAMETER_PROBLEM,
200 "Can't specify --timestop twice");
201 parse_time_string(&hours, &minutes, optarg);
202 timeinfo->time_stop = (hours * 60) + minutes;
203 *flags |= IPT_TIME_STOP;
209 exit_error(PARAMETER_PROBLEM,
210 "unexpected '!' with --days");
211 if (*flags & IPT_TIME_DAYS)
212 exit_error(PARAMETER_PROBLEM,
213 "Can't specify --days twice");
214 parse_days_string(&globaldays, optarg);
215 timeinfo->days_match = globaldays;
216 *flags |= IPT_TIME_DAYS;
224 /* Final check; must have specified --timestart --timestop --days. */
226 final_check(unsigned int flags)
228 if (flags != (IPT_TIME_START | IPT_TIME_STOP | IPT_TIME_DAYS))
229 exit_error(PARAMETER_PROBLEM,
230 "TIME match: You must specify `--timestart --timestop and --days'");
235 print_days(int daynum)
237 char *days[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
238 unsigned short int days_of_week[7] = {64, 32, 16, 8, 4, 2, 1};
239 unsigned short int i, nbdays=0;
241 for (i=0; i<7; i++) {
242 if ((days_of_week[i] & daynum) == days_of_week[i])
245 printf(",%s", days[i]);
247 printf("%s", days[i]);
254 divide_time(int fulltime, int *hours, int *minutes)
256 *hours = fulltime / 60;
257 *minutes = fulltime % 60;
260 /* Prints out the matchinfo. */
262 print(const struct ipt_ip *ip,
263 const struct ipt_entry_match *match,
266 struct ipt_time_info *time = ((struct ipt_time_info *)match->data);
267 int hour_start, hour_stop, minute_start, minute_stop;
269 divide_time(time->time_start, &hour_start, &minute_start);
270 divide_time(time->time_stop, &hour_stop, &minute_stop);
271 printf(" TIME from %d:%d to %d:%d on ",
272 hour_start, minute_start,
273 hour_stop, minute_stop);
274 print_days(time->days_match);
278 /* Saves the data in parsable form to stdout. */
280 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
282 struct ipt_time_info *time = ((struct ipt_time_info *)match->data);
283 int hour_start, hour_stop, minute_start, minute_stop;
285 divide_time(time->time_start, &hour_start, &minute_start);
286 divide_time(time->time_stop, &hour_stop, &minute_stop);
287 printf(" --timestart %.2d:%.2d --timestop %.2d:%.2d --days ",
288 hour_start, minute_start,
289 hour_stop, minute_stop);
290 print_days(time->days_match);
295 struct iptables_match timestruct
299 IPT_ALIGN(sizeof(struct ipt_time_info)),
300 IPT_ALIGN(sizeof(struct ipt_time_info)),
312 register_match(×truct);