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/libipt_ipv4options.c | 238 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 extensions/libipt_ipv4options.c (limited to 'extensions/libipt_ipv4options.c') 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); +} -- cgit v1.2.3