From d47faf0a067db68e8e7e5c7ee9c43f1052d79419 Mon Sep 17 00:00:00 2001 From: laforge Date: Sun, 25 Mar 2001 19:25:41 +0000 Subject: added new time match, added new ipv4options match --- extensions/libipt_time.c | 287 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 extensions/libipt_time.c (limited to 'extensions/libipt_time.c') diff --git a/extensions/libipt_time.c b/extensions/libipt_time.c new file mode 100644 index 0000000..07af0f4 --- /dev/null +++ b/extensions/libipt_time.c @@ -0,0 +1,287 @@ +/* Shared library add-on to iptables to add TIME matching support. */ +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Function which prints out usage message. */ +static void +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", +NETFILTER_VERSION); +} + +static struct option opts[] = { + { "timestart", 1, 0, '1' }, + { "timestop", 1, 0, '2' }, + { "days", 1, 0, '3'}, + {0} +}; + +/* Initialize the match. */ +static void +init(struct ipt_entry_match *m, unsigned int *nfcache) +{ + /* caching not yet implemented */ + *nfcache |= NFC_UNKNOWN; +} + + +/** + * param: part1, a pointer on a string 2 chars maximum long string, that will contain the hours. + * param: part2, a pointer on a string 2 chars maximum long string, that will contain the minutes. + * param: str_2_parse, the string to parse. + * return: 1 if ok, 0 if error. + */ +static int +split_time(char **part1, char **part2, const char *str_2_parse) +{ + unsigned short int i,j; + char *rpart1 = *part1; + char *rpart2 = *part2; + + /* Check the length of the string */ + if (strlen(str_2_parse) > 5) + return 0; + /* parse the first part until the ':' */ + for (i=0; i<2; i++) + { + if (str_2_parse[i] != ':') { + rpart1[i] = str_2_parse[i]; + } + } + if (str_2_parse[i] != ':') + ++i; + /* parse the second part */ + j=++i; + for (i=j; i<5; i++) + { + rpart2[i-j] = str_2_parse[i]; + } + /* if we are here, format should be ok. */ + return 1; +} + +static void +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); + + if (split_time(&hours, &minutes, time) == 1) + { + *hour = string_to_number(hours, 0, 23); + *minute = string_to_number(minutes, 0, 59); + } + if ((*hour != (-1)) && (*minute != (-1))) { + free(hours); + free(minutes); + return; + } + + /* If we are here, there was a problem ..*/ + exit_error(PARAMETER_PROBLEM, + "invalid time `%s' specified, should be HH:MM format", time); +} + +/* return 1->ok, return 0->error */ +static int +parse_day(int *days, int from, int to, const char *string) +{ + char *dayread; + char *days_str[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + unsigned short int days_of_week[7] = {64, 32, 16, 8, 4, 2, 1}; + unsigned int i; + + dayread = (char *)malloc(4); + bzero(dayread, 4); + if ((to-from) != 3) { + free(dayread); + return 0; + } + for (i=from; idata; + int hours, minutes, days; + + switch (c) + { + /* timestart */ + case '1': + if (invert) + exit_error(PARAMETER_PROBLEM, + "unexpected '!' with --timestart"); + if (*flags & IPT_TIME_START) + exit_error(PARAMETER_PROBLEM, + "Can't specify --timestart twice"); + parse_time_string(&hours, &minutes, optarg); + timeinfo->hour_start = hours; + timeinfo->minute_start = minutes; + *flags |= IPT_TIME_START; + break; + /* timestop */ + case '2': + if (invert) + exit_error(PARAMETER_PROBLEM, + "unexpected '!' with --timestop"); + if (*flags & IPT_TIME_STOP) + exit_error(PARAMETER_PROBLEM, + "Can't specify --timestop twice"); + parse_time_string(&hours, &minutes, optarg); + timeinfo->hour_stop = hours; + timeinfo->minute_stop = minutes; + *flags |= IPT_TIME_STOP; + break; + + /* days */ + case '3': + if (invert) + exit_error(PARAMETER_PROBLEM, + "unexpected '!' with --days"); + if (*flags & IPT_TIME_DAYS) + exit_error(PARAMETER_PROBLEM, + "Can't specify --days twice"); + parse_days_string(&days, optarg); + timeinfo->days_match = days; + *flags |= IPT_TIME_DAYS; + break; + default: + return 0; + } + return 1; +} + +/* Final check; must have specified --time-start --time-stop --days. */ +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 `--time-start --time-stop and --days'"); +} + + +static void +print_days(int daynum) +{ + char *days[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + unsigned short int days_of_week[7] = {64, 32, 16, 8, 4, 2, 1}; + unsigned short int i, nbdays=0; + + for (i=0; i<7; i++) { + if ((days_of_week[i] & daynum) == days_of_week[i]) + { + if (nbdays>0) + printf(",%s", days[i]); + else + printf("%s", days[i]); + ++nbdays; + } + } +} + +/* Prints out the matchinfo. */ +static void +print(const struct ipt_ip *ip, + const struct ipt_entry_match *match, + int numeric) +{ + struct ipt_time_info *time = ((struct ipt_time_info *)match->data); + printf(" TIME from %d:%d to %d:%d on ", + time->hour_start, time->minute_start, + time->hour_stop, time->minute_stop); + print_days(time->days_match); + printf(" "); +} + +/* Saves the data in parsable form to stdout. */ +static void +save(const struct ipt_ip *ip, const struct ipt_entry_match *match) +{ + struct ipt_time_info *time = ((struct ipt_time_info *)match->data); + + printf(" --timestart %.2d:%.2d --timestop %.2d:%.2d --days ", + time->hour_start, time->minute_start, + time->hour_stop, time->minute_stop); + print_days(time->days_match); + printf(" "); +} + +struct iptables_match timestruct += { NULL, + "time", + NETFILTER_VERSION, + IPT_ALIGN(sizeof(struct ipt_time_info)), + IPT_ALIGN(sizeof(struct ipt_time_info)), + &help, + &init, + &parse, + &final_check, + &print, + &save, + opts +}; + +void _init(void) +{ + register_match(×truct); +} -- cgit v1.2.3