diff options
author | Jinkun Jang <jinkun.jang@samsung.com> | 2013-03-13 01:42:55 +0900 |
---|---|---|
committer | Jinkun Jang <jinkun.jang@samsung.com> | 2013-03-13 01:42:55 +0900 |
commit | cb06be6ecc10920c73293799689ce9803262a922 (patch) | |
tree | 5d21c5f26a156067e733c9faa79782ecc26196e9 /extensions/libxt_length.c | |
parent | dbc5ef4889caa206f4d47d83345357780ceef73e (diff) | |
download | iptables-2.2_release.tar.gz iptables-2.2_release.tar.bz2 iptables-2.2_release.zip |
Tizen 2.1 basesubmit/tizen_2.2/20130714.145952submit/tizen_2.1/20130424.225212accepted/tizen_2.1/20130425.0251492.2_release2.1b_releasetizen_2.1
Diffstat (limited to 'extensions/libxt_length.c')
-rw-r--r-- | extensions/libxt_length.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/extensions/libxt_length.c b/extensions/libxt_length.c new file mode 100644 index 0000000..96e8b6c --- /dev/null +++ b/extensions/libxt_length.c @@ -0,0 +1,133 @@ +/* Shared library add-on to iptables to add packet length matching support. */ +#include <stdio.h> +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <getopt.h> + +#include <xtables.h> +#include <linux/netfilter/xt_length.h> + +static void length_help(void) +{ + printf( +"length match options:\n" +"[!] --length length[:length] Match packet length against value or range\n" +" of values (inclusive)\n"); +} + +static const struct option length_opts[] = { + { "length", 1, NULL, '1' }, + { .name = NULL } +}; + +static u_int16_t +parse_length(const char *s) +{ + unsigned int len; + + if (!xtables_strtoui(s, NULL, &len, 0, UINT32_MAX)) + xtables_error(PARAMETER_PROBLEM, "length invalid: \"%s\"\n", s); + else + return len; +} + +/* If a single value is provided, min and max are both set to the value */ +static void +parse_lengths(const char *s, struct xt_length_info *info) +{ + char *buffer; + char *cp; + + buffer = strdup(s); + if ((cp = strchr(buffer, ':')) == NULL) + info->min = info->max = parse_length(buffer); + else { + *cp = '\0'; + cp++; + + info->min = buffer[0] ? parse_length(buffer) : 0; + info->max = cp[0] ? parse_length(cp) : 0xFFFF; + } + free(buffer); + + if (info->min > info->max) + xtables_error(PARAMETER_PROBLEM, + "length min. range value `%u' greater than max. " + "range value `%u'", info->min, info->max); + +} + +static int +length_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) +{ + struct xt_length_info *info = (struct xt_length_info *)(*match)->data; + + switch (c) { + case '1': + if (*flags) + xtables_error(PARAMETER_PROBLEM, + "length: `--length' may only be " + "specified once"); + xtables_check_inverse(optarg, &invert, &optind, 0, argv); + parse_lengths(optarg, info); + if (invert) + info->invert = 1; + *flags = 1; + break; + + default: + return 0; + } + return 1; +} + +static void length_check(unsigned int flags) +{ + if (!flags) + xtables_error(PARAMETER_PROBLEM, + "length: You must specify `--length'"); +} + +static void +length_print(const void *ip, const struct xt_entry_match *match, int numeric) +{ + const struct xt_length_info *info = (void *)match->data; + + printf("length %s", info->invert ? "!" : ""); + if (info->min == info->max) + printf("%u ", info->min); + else + printf("%u:%u ", info->min, info->max); +} + +static void length_save(const void *ip, const struct xt_entry_match *match) +{ + const struct xt_length_info *info = (void *)match->data; + + printf("%s--length ", info->invert ? "! " : ""); + if (info->min == info->max) + printf("%u ", info->min); + else + printf("%u:%u ", info->min, info->max); +} + +static struct xtables_match length_match = { + .family = NFPROTO_UNSPEC, + .name = "length", + .version = XTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_length_info)), + .userspacesize = XT_ALIGN(sizeof(struct xt_length_info)), + .help = length_help, + .parse = length_parse, + .final_check = length_check, + .print = length_print, + .save = length_save, + .extra_opts = length_opts, +}; + +void _init(void) +{ + xtables_register_match(&length_match); +} |