summaryrefslogtreecommitdiffstats
path: root/extensions/libipt_time.c
diff options
context:
space:
mode:
authorJoszef Kadlecsik <kadlec@blackhole.kfki.hu>2004-05-05 10:10:33 +0000
committerJoszef Kadlecsik <kadlec@blackhole.kfki.hu>2004-05-05 10:10:33 +0000
commitdb503f9a45f2a765ef63834a2c9416ccf59385af (patch)
tree2ccef3d601bc9cf51e8c5e891b18ad1320df6fd5 /extensions/libipt_time.c
parent7737eec010d91eef238271294f1f21cba8122c74 (diff)
Fabrice's time match update + Tom Eastep's conntrack mach fix applied (JK)
Diffstat (limited to 'extensions/libipt_time.c')
-rw-r--r--extensions/libipt_time.c313
1 files changed, 273 insertions, 40 deletions
diff --git a/extensions/libipt_time.c b/extensions/libipt_time.c
index b59fa990..8b6077a6 100644
--- a/extensions/libipt_time.c
+++ b/extensions/libipt_time.c
@@ -18,10 +18,26 @@ help(void)
{
printf(
"TIME v%s options:\n"
-" --timestart value --timestop value --days listofdays\n"
-" timestart value : HH:MM\n"
-" timestop value : HH:MM\n"
-" listofdays value: a list of days to apply -> ie. Mon,Tue,Wed,Thu,Fri. Case sensitive\n",
+" [ --timestart value ] [ --timestop value] [ --days listofdays ] [ --datestart value ] [ --datestop value ]\n"
+" timestart value : HH:MM (default 00:00)\n"
+" timestop value : HH:MM (default 23:59)\n"
+" listofdays value: a list of days to apply\n"
+" from Mon,Tue,Wed,Thu,Fri,Sat,Sun\n"
+" Coma speparated, no space, case sensitive.\n"
+" Defaults to all days.\n"
+" datestart value : YYYY[:MM[:DD[:hh[:mm[:ss]]]]]\n"
+" If any of month, day, hour, minute or second is\n"
+" not specified, then defaults to their smallest\n"
+" 1900 <= YYYY < 2037\n"
+" 1 <= MM <= 12\n"
+" 1 <= DD <= 31\n"
+" 0 <= hh <= 23\n"
+" 0 <= mm <= 59\n"
+" 0 <= ss <= 59\n"
+" datestop value : YYYY[:MM[:DD[:hh[:mm[:ss]]]]]\n"
+" If the whole option is ommited, default to never stop\n"
+" If any of month, day, hour, minute or second is\n"
+" not specified, then default to their smallest\n",
IPTABLES_VERSION);
}
@@ -29,6 +45,8 @@ static struct option opts[] = {
{ "timestart", 1, 0, '1' },
{ "timestop", 1, 0, '2' },
{ "days", 1, 0, '3'},
+ { "datestart", 1, 0, '4' },
+ { "datestop", 1, 0, '5' },
{0}
};
@@ -36,9 +54,18 @@ static struct option opts[] = {
static void
init(struct ipt_entry_match *m, unsigned int *nfcache)
{
+ struct ipt_time_info *info = (struct ipt_time_info *)m->data;
+ globaldays = 0;
/* caching not yet implemented */
*nfcache |= NFC_UNKNOWN;
- globaldays = 0;
+ /* By default, we match on everyday */
+ info->days_match = 127;
+ /* By default, we match on every hour:min of the day */
+ info->time_start = 0;
+ info->time_stop = 1439; /* (23*60+59 = 1439 */
+ /* By default, we don't have any date-begin or date-end boundaries */
+ info->date_start = 0;
+ info->date_stop = LONG_MAX;
}
/**
@@ -78,36 +105,45 @@ split_time(char **part1, char **part2, const char *str_2_parse)
return 1;
}
+static int
+parse_number(char *str, int num_min, int num_max, int *number)
+{
+ /* if the number starts with 0, replace it with a space else
+ string_to_number() will interpret it as octal !! */
+ if (strlen(str) == 0)
+ return 0;
+
+ if ((str[0] == '0') && (str[1] != '\0'))
+ str[0] = ' ';
+
+ return string_to_number(str, num_min, num_max, number);
+}
+
static void
-parse_time_string(unsigned int *hour, unsigned int *minute, const char *time)
+parse_time_string(int *hour, int *minute, const char *time)
{
char *hours;
char *minutes;
-
hours = (char *)malloc(3);
minutes = (char *)malloc(3);
- bzero((void *)hours, 3);
- bzero((void *)minutes, 3);
+ memset(hours, 0, 3);
+ memset(minutes, 0, 3);
- if (split_time(&hours, &minutes, time) == 1)
+ if (split_time((char **)&hours, (char **)&minutes, time) == 1)
{
- /* if the number starts with 0, replace it with a space else
- this string_to_number will interpret it as octal !! */
- if ((hours[0] == '0') && (hours[1] != '\0'))
- hours[0] = ' ';
- if ((minutes[0] == '0') && (minutes[1] != '\0'))
- minutes[0] = ' ';
-
- if((string_to_number(hours, 0, 23, hour) == -1) ||
- (string_to_number(minutes, 0, 59, minute) == -1)) {
- *hour = *minute = (-1);
+ *hour = 0;
+ *minute = 0;
+ if ((parse_number((char *)hours, 0, 23, hour) != -1) &&
+ (parse_number((char *)minutes, 0, 59, minute) != -1))
+ {
+ free(hours);
+ free(minutes);
+ return;
}
}
- if ((*hour != (-1)) && (*minute != (-1))) {
- free(hours);
- free(minutes);
- return;
- }
+
+ free(hours);
+ free(minutes);
/* If we are here, there was a problem ..*/
exit_error(PARAMETER_PROBLEM,
@@ -161,10 +197,139 @@ parse_days_string(int *days, const char *daystring)
}
}
+static int
+parse_date_field(const char *str_to_parse, int str_to_parse_s, int start_pos,
+ char *dest, int *next_pos)
+{
+ unsigned char found_value = 0;
+ unsigned char found_column = 0;
+ int i;
+
+ for (i=0; i<2; i++)
+ {
+ if ((i+start_pos) >= str_to_parse_s) /* don't exit boundaries of the string.. */
+ break;
+ if (str_to_parse[i+start_pos] == ':')
+ found_column = 1;
+ else
+ {
+ found_value = 1;
+ dest[i] = str_to_parse[i+start_pos];
+ }
+ }
+ if (found_value == 0)
+ return 0;
+ *next_pos = i + start_pos;
+ if (found_column == 0)
+ ++(*next_pos);
+ return 1;
+}
+
+static int
+split_date(char *year, char *month, char *day,
+ char *hour, char *minute, char *second,
+ const char *str_to_parse)
+{
+ int i;
+ unsigned char found_column = 0;
+ int str_to_parse_s = strlen(str_to_parse);
+
+ /* Check the length of the string */
+ if ((str_to_parse_s > 19) || /* YYYY:MM:DD:HH:MM:SS */
+ (str_to_parse_s < 4)) /* YYYY*/
+ return 0;
+
+ /* Clear the buffers */
+ memset(year, 0, 4);
+ memset(month, 0, 2);
+ memset(day, 0, 2);
+ memset(hour, 0, 2);
+ memset(minute, 0, 2);
+ memset(second, 0, 2);
+
+ /* parse the year YYYY */
+ found_column = 0;
+ for (i=0; i<5; i++)
+ {
+ if (i >= str_to_parse_s)
+ break;
+ if (str_to_parse[i] == ':')
+ {
+ found_column = 1;
+ break;
+ }
+ else
+ year[i] = str_to_parse[i];
+ }
+ if (found_column == 1)
+ ++i;
+
+ /* parse the month if it exists */
+ if (! parse_date_field(str_to_parse, str_to_parse_s, i, month, &i))
+ return 1;
+
+ if (! parse_date_field(str_to_parse, str_to_parse_s, i, day, &i))
+ return 1;
+
+ if (! parse_date_field(str_to_parse, str_to_parse_s, i, hour, &i))
+ return 1;
+
+ if (! parse_date_field(str_to_parse, str_to_parse_s, i, minute, &i))
+ return 1;
+
+ parse_date_field(str_to_parse, str_to_parse_s, i, second, &i);
+
+ /* if we are here, format should be ok. */
+ return 1;
+}
+
+static time_t
+parse_date_string(const char *str_to_parse)
+{
+ char year[5];
+ char month[3];
+ char day[3];
+ char hour[3];
+ char minute[3];
+ char second[3];
+ struct tm t;
+ time_t temp_time;
+
+ memset(year, 0, 5);
+ memset(month, 0, 3);
+ memset(day, 0, 3);
+ memset(hour, 0, 3);
+ memset(minute, 0, 3);
+ memset(second, 0, 3);
+
+ if (split_date(year, month, day, hour, minute, second, str_to_parse) == 1)
+ {
+ memset((void *)&t, 0, sizeof(struct tm));
+ t.tm_isdst = -1;
+ t.tm_mday = 1;
+ if (!((parse_number(year, 1900, 2037, &(t.tm_year)) == -1) ||
+ (parse_number(month, 1, 12, &(t.tm_mon)) == -1) ||
+ (parse_number(day, 1, 31, &(t.tm_mday)) == -1) ||
+ (parse_number(hour, 0, 9999, &(t.tm_hour)) == -1) ||
+ (parse_number(minute, 0, 59, &(t.tm_min)) == -1) ||
+ (parse_number(second, 0, 59, &(t.tm_sec)) == -1)))
+ {
+ t.tm_year -= 1900;
+ --(t.tm_mon);
+ temp_time = mktime(&t);
+ if (temp_time != -1)
+ return temp_time;
+ }
+ }
+ exit_error(PARAMETER_PROBLEM,
+ "invalid date `%s' specified, should be YYYY[:MM[:DD[:hh[:mm[:ss]]]]] format", str_to_parse);
+}
+
#define IPT_TIME_START 0x01
#define IPT_TIME_STOP 0x02
#define IPT_TIME_DAYS 0x04
-
+#define IPT_DATE_START 0x08
+#define IPT_DATE_STOP 0x10
/* Function which parses command options; returns true if it
ate an option */
@@ -176,6 +341,7 @@ parse(int c, char **argv, int invert, unsigned int *flags,
{
struct ipt_time_info *timeinfo = (struct ipt_time_info *)(*match)->data;
int hours, minutes;
+ time_t temp_date;
switch (c)
{
@@ -216,19 +382,43 @@ parse(int c, char **argv, int invert, unsigned int *flags,
timeinfo->days_match = globaldays;
*flags |= IPT_TIME_DAYS;
break;
+
+ /* datestart */
+ case '4':
+ if (invert)
+ exit_error(PARAMETER_PROBLEM,
+ "unexpected '!' with --datestart");
+ if (*flags & IPT_DATE_START)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --datestart twice");
+ temp_date = parse_date_string(optarg);
+ timeinfo->date_start = temp_date;
+ *flags |= IPT_DATE_START;
+ break;
+
+ /* datestop*/
+ case '5':
+ if (invert)
+ exit_error(PARAMETER_PROBLEM,
+ "unexpected '!' with --datestop");
+ if (*flags & IPT_DATE_STOP)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify --datestop twice");
+ temp_date = parse_date_string(optarg);
+ timeinfo->date_stop = temp_date;
+ *flags |= IPT_DATE_STOP;
+ break;
default:
return 0;
}
return 1;
}
-/* Final check; must have specified --timestart --timestop --days. */
+/* Final check */
static void
final_check(unsigned int flags)
{
- if (flags != (IPT_TIME_START | IPT_TIME_STOP | IPT_TIME_DAYS))
- exit_error(PARAMETER_PROBLEM,
- "TIME match: You must specify `--timestart --timestop and --days'");
+ /* Nothing to do */
}
@@ -249,6 +439,7 @@ print_days(int daynum)
++nbdays;
}
}
+ printf(" ");
}
static void
@@ -258,6 +449,22 @@ divide_time(int fulltime, int *hours, int *minutes)
*minutes = fulltime % 60;
}
+static void
+print_date(time_t date, char *command)
+{
+ /* If it's default value, don't print..*/
+ if (((date == 0) || (date == LONG_MAX)) && (command != NULL))
+ return;
+ struct tm *t;
+ t = localtime(&date);
+ if (command != NULL)
+ printf("%s %d:%d:%d:%d:%d:%d ", command, (t->tm_year + 1900), (t->tm_mon + 1),
+ t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+ else
+ printf("%d-%d-%d %d:%d:%d ", (t->tm_year + 1900), (t->tm_mon + 1),
+ t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+}
+
/* Prints out the matchinfo. */
static void
print(const struct ipt_ip *ip,
@@ -269,11 +476,26 @@ print(const struct ipt_ip *ip,
divide_time(time->time_start, &hour_start, &minute_start);
divide_time(time->time_stop, &hour_stop, &minute_stop);
- printf(" TIME from %d:%d to %d:%d on ",
- hour_start, minute_start,
- hour_stop, minute_stop);
- print_days(time->days_match);
- printf(" ");
+ printf("TIME ");
+ if (time->time_start != 0)
+ printf("from %d:%d ", hour_start, minute_start);
+ if (time->time_stop != 1439) /* 23*60+59 = 1439 */
+ printf("to %d:%d ", hour_stop, minute_stop);
+ printf("on ");
+ if (time->days_match == 127)
+ printf("all days ");
+ else
+ print_days(time->days_match);
+ if (time->date_start != 0)
+ {
+ printf("starting from ");
+ print_date(time->date_start, NULL);
+ }
+ if (time->date_stop != LONG_MAX)
+ {
+ printf("until date ");
+ print_date(time->date_stop, NULL);
+ }
}
/* Saves the data in parsable form to stdout. */
@@ -285,11 +507,22 @@ save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
divide_time(time->time_start, &hour_start, &minute_start);
divide_time(time->time_stop, &hour_stop, &minute_stop);
- printf(" --timestart %.2d:%.2d --timestop %.2d:%.2d --days ",
- hour_start, minute_start,
- hour_stop, minute_stop);
- print_days(time->days_match);
- printf(" ");
+ if (time->time_start != 0)
+ printf("--timestart %.2d:%.2d ",
+ hour_start, minute_start);
+
+ if (time->time_stop != 1439) /* 23*60+59 = 1439 */
+ printf("--timestop %.2d:%.2d ",
+ hour_stop, minute_stop);
+
+ if (time->days_match != 127)
+ {
+ printf("--days ");
+ print_days(time->days_match);
+ printf(" ");
+ }
+ print_date(time->date_start, "--datestart");
+ print_date(time->date_stop, "--datestop");
}
/* have to use offsetof() instead of IPT_ALIGN(), since kerneltime must not