From 5ea4bcb45a70f79a8df53caddeeeccfa90d735ae Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 25 Mar 2001 19:25:41 +0000 Subject: added new time match, added new ipv4options match --- extensions/.ipv4options-test | 3 + extensions/.time-test | 3 + extensions/Makefile | 2 +- extensions/libipt_ipv4options.c | 238 +++++++++++++++++++++++++++++++++ extensions/libipt_time.c | 287 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 532 insertions(+), 1 deletion(-) create mode 100755 extensions/.ipv4options-test create mode 100755 extensions/.time-test create mode 100644 extensions/libipt_ipv4options.c create mode 100644 extensions/libipt_time.c (limited to 'extensions') diff --git a/extensions/.ipv4options-test b/extensions/.ipv4options-test new file mode 100755 index 00000000..134ab09e --- /dev/null +++ b/extensions/.ipv4options-test @@ -0,0 +1,3 @@ +#!/bin/sh +# True if ipv4options is applied. +[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_ipv4options.h ] && echo ipv4options diff --git a/extensions/.time-test b/extensions/.time-test new file mode 100755 index 00000000..7f0390e2 --- /dev/null +++ b/extensions/.time-test @@ -0,0 +1,3 @@ +#!/bin/sh +# True if time is applied. +[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_time.h ] && echo time diff --git a/extensions/Makefile b/extensions/Makefile index be607e92..481e5fc1 100644 --- a/extensions/Makefile +++ b/extensions/Makefile @@ -1,6 +1,6 @@ #! /usr/bin/make -PF_EXT_SLIB:=tcp udp icmp mac limit standard REJECT LOG unclean state multiport tos TOS mark MARK owner SNAT DNAT MASQUERADE REDIRECT MIRROR +PF_EXT_SLIB:=tcp udp icmp mac limit standard REJECT LOG unclean state multiport tos TOS mark MARK owner SNAT DNAT MASQUERADE REDIRECT MIRROR SAME PF6_EXT_SLIB:=tcp udp icmp standard MARK mark # The following may not be present, but compile them anyway. diff --git a/extensions/libipt_ipv4options.c b/extensions/libipt_ipv4options.c new file mode 100644 index 00000000..7f3a5eb5 --- /dev/null +++ b/extensions/libipt_ipv4options.c @@ -0,0 +1,238 @@ +/* Shared library add-on to iptables to add ipv4 options matching support. */ +#include +#include +#include +#include +#include + +#include +#include + +/* Function which prints out usage message. */ +static void +help(void) +{ + printf( +"IPV4OPTIONS v%s options:\n" +" --ssrr (match strict source routing flag)\n" +" --lsrr (match loose source routing flag)\n" +" --no-srr (match packets with no source routing)\n\n" +" [!] --rr (match record route flag)\n\n" +" [!] --ts (match timestamp flag)\n\n", +NETFILTER_VERSION); +} + +static struct option opts[] = { + { "ssrr", 0, 0, '1' }, + { "lsrr", 0, 0, '2' }, + { "no-srr", 0, 0, '3'}, + { "rr", 0, 0, '4'}, + { "ts", 0, 0, '5'}, + {0} +}; + +/* Initialize the match. */ +static void +init(struct ipt_entry_match *m, unsigned int *nfcache) +{ + /* caching not yet implemented */ + *nfcache |= NFC_UNKNOWN; +} + +/* Function which parses command options; returns true if it + ate an option */ +static int +parse(int c, char **argv, int invert, unsigned int *flags, + const struct ipt_entry *entry, + unsigned int *nfcache, + struct ipt_entry_match **match) +{ + struct ipt_ipv4options_info *info = (struct ipt_ipv4options_info *)(*match)->data; + + switch (c) + { + /* strict-source-routing */ + case '1': + if (invert) + exit_error(PARAMETER_PROBLEM, + "ipv4options: unexpected `!' with --ssrr"); + if (*flags & IPT_IPV4OPTION_MATCH_SSRR) + exit_error(PARAMETER_PROBLEM, + "Can't specify --ssrr twice"); + if (*flags & IPT_IPV4OPTION_MATCH_LSRR) + exit_error(PARAMETER_PROBLEM, + "Can't specify --ssrr with --lsrr"); + if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) + exit_error(PARAMETER_PROBLEM, + "Can't specify --ssrr with --no-srr"); + + info->options |= IPT_IPV4OPTION_MATCH_SSRR; + *flags |= IPT_IPV4OPTION_MATCH_SSRR; + break; + + /* loose-source-routing */ + case '2': + if (invert) + exit_error(PARAMETER_PROBLEM, + "ipv4options: unexpected `!' with --lsrr"); + if (*flags & IPT_IPV4OPTION_MATCH_SSRR) + exit_error(PARAMETER_PROBLEM, + "Can't specify --lsrr twice"); + if (*flags & IPT_IPV4OPTION_MATCH_LSRR) + exit_error(PARAMETER_PROBLEM, + "Can't specify --lsrr with --ssrr"); + if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) + exit_error(PARAMETER_PROBLEM, + "Can't specify --lsrr with --no-srr"); + info->options |= IPT_IPV4OPTION_MATCH_LSRR; + *flags |= IPT_IPV4OPTION_MATCH_LSRR; + break; + + /* no-source-routing */ + case '3': + if (invert) + exit_error(PARAMETER_PROBLEM, + "ipv4options: unexpected `!' with --no-srr"); + if (*flags & IPT_IPV4OPTION_DONT_MATCH_SRR) + exit_error(PARAMETER_PROBLEM, + "Can't specify --no-srr twice"); + if (*flags & IPT_IPV4OPTION_MATCH_SSRR) + exit_error(PARAMETER_PROBLEM, + "Can't specify --no-srr with --ssrr"); + if (*flags & IPT_IPV4OPTION_MATCH_LSRR) + exit_error(PARAMETER_PROBLEM, + "Can't specify --no-srr with --lsrr"); + info->options |= IPT_IPV4OPTION_DONT_MATCH_SRR; + *flags |= IPT_IPV4OPTION_DONT_MATCH_SRR; + break; + + /* record-route */ + case '4': + if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_RR)) + exit_error(PARAMETER_PROBLEM, + "Can't specify --rr twice"); + if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR)) + exit_error(PARAMETER_PROBLEM, + "Can't specify ! --rr twice"); + if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_RR)) + exit_error(PARAMETER_PROBLEM, + "Can't specify --rr with ! --rr"); + if (invert && (*flags & IPT_IPV4OPTION_MATCH_RR)) + exit_error(PARAMETER_PROBLEM, + "Can't specify ! --rr with --rr"); + if (invert) { + info->options |= IPT_IPV4OPTION_DONT_MATCH_RR; + *flags |= IPT_IPV4OPTION_DONT_MATCH_RR; + } + else { + info->options |= IPT_IPV4OPTION_MATCH_RR; + *flags |= IPT_IPV4OPTION_MATCH_RR; + } + break; + + /* timestamp */ + case '5': + if ((!invert) && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP)) + exit_error(PARAMETER_PROBLEM, + "Can't specify --ts twice"); + if (invert && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)) + exit_error(PARAMETER_PROBLEM, + "Can't specify ! --ts twice"); + if ((!invert) && (*flags & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP)) + exit_error(PARAMETER_PROBLEM, + "Can't specify --ts with ! --ts"); + if (invert && (*flags & IPT_IPV4OPTION_MATCH_TIMESTAMP)) + exit_error(PARAMETER_PROBLEM, + "Can't specify ! --ts with --ts"); + if (invert) { + info->options |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP; + *flags |= IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP; + } + else { + info->options |= IPT_IPV4OPTION_MATCH_TIMESTAMP; + *flags |= IPT_IPV4OPTION_MATCH_TIMESTAMP; + } + break; + + default: + return 0; + } + return 1; +} + +static void +final_check(unsigned int flags) +{ + if (flags == 0) + exit_error(PARAMETER_PROBLEM, + "ipv4options match: you must specify some parameters. See iptables -m ipv4options --help for help.'"); +} + +/* Prints out the matchinfo. */ +static void +print(const struct ipt_ip *ip, + const struct ipt_entry_match *match, + int numeric) +{ + struct ipt_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data); + + printf(" IPV4OPTS"); + if (info->options & IPT_IPV4OPTION_MATCH_SSRR) + printf(" SSRR"); + else if (info->options & IPT_IPV4OPTION_MATCH_LSRR) + printf(" LSRR"); + else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) + printf(" !SRR"); + if (info->options & IPT_IPV4OPTION_MATCH_RR) + printf(" RR"); + else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR) + printf(" !RR"); + if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) + printf(" TS"); + else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) + printf(" !TS"); + 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_ipv4options_info *info = ((struct ipt_ipv4options_info *)match->data); + + if (info->options & IPT_IPV4OPTION_MATCH_SSRR) + printf(" --ssrr"); + else if (info->options & IPT_IPV4OPTION_MATCH_LSRR) + printf(" --lsrr"); + else if (info->options & IPT_IPV4OPTION_DONT_MATCH_SRR) + printf(" --no-srr"); + if (info->options & IPT_IPV4OPTION_MATCH_RR) + printf(" --rr"); + else if (info->options & IPT_IPV4OPTION_DONT_MATCH_RR) + printf(" ! --rr"); + if (info->options & IPT_IPV4OPTION_MATCH_TIMESTAMP) + printf(" --ts"); + else if (info->options & IPT_IPV4OPTION_DONT_MATCH_TIMESTAMP) + printf(" ! --ts"); + printf(" "); +} + +struct iptables_match ipv4options_struct += { NULL, + "ipv4options", + NETFILTER_VERSION, + IPT_ALIGN(sizeof(struct ipt_ipv4options_info)), + IPT_ALIGN(sizeof(struct ipt_ipv4options_info)), + &help, + &init, + &parse, + &final_check, + &print, + &save, + opts +}; + +void _init(void) +{ + register_match(&ipv4options_struct); +} diff --git a/extensions/libipt_time.c b/extensions/libipt_time.c new file mode 100644 index 00000000..07af0f49 --- /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