]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xt_string: string extension case insensitive matching
authorJoonwoo Park <joonwpark81@gmail.com>
Mon, 7 Jul 2008 11:32:25 +0000 (13:32 +0200)
committerPatrick McHardy <kaber@trash.net>
Mon, 7 Jul 2008 11:32:25 +0000 (13:32 +0200)
The string extension can search patterns case insensitively with
--icase option. A new revision 1 was added, in the meantime invert
of xt_string_info was moved into flags as a flag.

Signed-off-by: Joonwoo Park <joonwpark81@gmail.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
extensions/libxt_string.c
include/linux/netfilter/xt_string.h

index 5eec44baa0e6232fb1f9e112d724521aa40808c2..61b5bb56aaadbecffda2e763ac489e96f35a88aa 100644 (file)
@@ -37,7 +37,8 @@ static void string_help(void)
 "string match options:\n"
 "--from                       Offset to start searching from\n"
 "--to                         Offset to stop searching\n"
-"--algo                              Algorithm\n"
+"--algo                       Algorithm\n"
+"--icase                      Ignore case (default: 0)\n"
 "[!] --string string          Match a string in a packet\n"
 "[!] --hex-string string      Match a hex string in a packet\n");
 }
@@ -48,6 +49,7 @@ static const struct option string_opts[] = {
        { "algo", 1, NULL, '3' },
        { "string", 1, NULL, '4' },
        { "hex-string", 1, NULL, '5' },
+       { "icase", 0, NULL, '6' },
        { .name = NULL }
 };
 
@@ -162,6 +164,7 @@ parse_hex_string(const char *s, struct xt_string_info *info)
 #define ALGO   0x2
 #define FROM   0x4
 #define TO     0x8
+#define ICASE  0x10
 
 /* Function which parses command options; returns true if it
    ate an option */
@@ -169,7 +172,9 @@ static int
 string_parse(int c, char **argv, int invert, unsigned int *flags,
              const void *entry, struct xt_entry_match **match)
 {
-       struct xt_string_info *stringinfo = (struct xt_string_info *)(*match)->data;
+       struct xt_string_info *stringinfo =
+           (struct xt_string_info *)(*match)->data;
+       const int revision = (*match)->u.user.revision;
 
        switch (c) {
        case '1':
@@ -199,8 +204,12 @@ string_parse(int c, char **argv, int invert, unsigned int *flags,
                                   "Can't specify multiple --string");
                check_inverse(optarg, &invert, &optind, 0);
                parse_string(argv[optind-1], stringinfo);
-               if (invert)
-                       stringinfo->invert = 1;
+               if (invert) {
+                       if (revision == 0)
+                               stringinfo->u.v0.invert = 1;
+                       else
+                               stringinfo->u.v1.flags |= XT_STRING_FLAG_INVERT;
+               }
                stringinfo->patlen=strlen((char *)&stringinfo->pattern);
                *flags |= STRING;
                break;
@@ -212,11 +221,24 @@ string_parse(int c, char **argv, int invert, unsigned int *flags,
 
                check_inverse(optarg, &invert, &optind, 0);
                parse_hex_string(argv[optind-1], stringinfo);  /* sets length */
-               if (invert)
-                       stringinfo->invert = 1;
+               if (invert) {
+                       if (revision == 0)
+                               stringinfo->u.v0.invert = 1;
+                       else
+                               stringinfo->u.v1.flags |= XT_STRING_FLAG_INVERT;
+               }
                *flags |= STRING;
                break;
 
+       case '6':
+               if (revision == 0)
+                       exit_error(VERSION_PROBLEM,
+                                  "Kernel doesn't support --icase");
+
+               stringinfo->u.v1.flags |= XT_STRING_FLAG_IGNORECASE;
+               *flags |= ICASE;
+               break;
+
        default:
                return 0;
        }
@@ -287,12 +309,15 @@ string_print(const void *ip, const struct xt_entry_match *match, int numeric)
 {
        const struct xt_string_info *info =
            (const struct xt_string_info*) match->data;
+       const int revision = match->u.user.revision;
+       int invert = (revision == 0 ? info->u.v0.invert :
+                                   info->u.v1.flags & XT_STRING_FLAG_INVERT);
 
        if (is_hex_string(info->pattern, info->patlen)) {
-               printf("STRING match %s", (info->invert) ? "!" : "");
+               printf("STRING match %s", invert ? "!" : "");
                print_hex_string(info->pattern, info->patlen);
        } else {
-               printf("STRING match %s", (info->invert) ? "!" : "");
+               printf("STRING match %s", invert ? "!" : "");
                print_string(info->pattern, info->patlen);
        }
        printf("ALGO name %s ", info->algo);
@@ -300,6 +325,8 @@ string_print(const void *ip, const struct xt_entry_match *match, int numeric)
                printf("FROM %u ", info->from_offset);
        if (info->to_offset != 0)
                printf("TO %u ", info->to_offset);
+       if (revision > 0 && info->u.v1.flags & XT_STRING_FLAG_IGNORECASE)
+               printf("ICASE ");
 }
 
 
@@ -308,12 +335,15 @@ static void string_save(const void *ip, const struct xt_entry_match *match)
 {
        const struct xt_string_info *info =
            (const struct xt_string_info*) match->data;
+       const int revision = match->u.user.revision;
+       int invert = (revision == 0 ? info->u.v0.invert :
+                                   info->u.v1.flags & XT_STRING_FLAG_INVERT);
 
        if (is_hex_string(info->pattern, info->patlen)) {
-               printf("--hex-string %s", (info->invert) ? "! ": "");
+               printf("--hex-string %s", (invert) ? "! ": "");
                print_hex_string(info->pattern, info->patlen);
        } else {
-               printf("--string %s", (info->invert) ? "! ": "");
+               printf("--string %s", (invert) ? "! ": "");
                print_string(info->pattern, info->patlen);
        }
        printf("--algo %s ", info->algo);
@@ -321,11 +351,30 @@ static void string_save(const void *ip, const struct xt_entry_match *match)
                printf("--from %u ", info->from_offset);
        if (info->to_offset != 0)
                printf("--to %u ", info->to_offset);
+       if (revision > 0 && info->u.v1.flags & XT_STRING_FLAG_IGNORECASE)
+               printf("--icase ");
 }
 
 
 static struct xtables_match string_match = {
     .name              = "string",
+    .revision          = 0,
+    .family            = AF_UNSPEC,
+    .version           = XTABLES_VERSION,
+    .size              = XT_ALIGN(sizeof(struct xt_string_info)),
+    .userspacesize     = offsetof(struct xt_string_info, config),
+    .help              = string_help,
+    .init              = string_init,
+    .parse             = string_parse,
+    .final_check       = string_check,
+    .print             = string_print,
+    .save              = string_save,
+    .extra_opts                = string_opts,
+};
+
+static struct xtables_match string_match_v1 = {
+    .name              = "string",
+    .revision          = 1,
     .family            = AF_UNSPEC,
     .version           = XTABLES_VERSION,
     .size              = XT_ALIGN(sizeof(struct xt_string_info)),
@@ -342,4 +391,5 @@ static struct xtables_match string_match = {
 void _init(void)
 {
        xtables_register_match(&string_match);
+       xtables_register_match(&string_match_v1);
 }
index bb21dd1aee2d3ec610e73fb39a219bcd39af92d9..f1c182fd149f01b9295fca785f2b442ff0277f8f 100644 (file)
@@ -4,6 +4,11 @@
 #define XT_STRING_MAX_PATTERN_SIZE 128
 #define XT_STRING_MAX_ALGO_NAME_SIZE 16
 
+enum {
+       XT_STRING_FLAG_INVERT           = 0x01,
+       XT_STRING_FLAG_IGNORECASE       = 0x02
+};
+
 struct xt_string_info
 {
        u_int16_t from_offset;
@@ -11,7 +16,15 @@ struct xt_string_info
        char      algo[XT_STRING_MAX_ALGO_NAME_SIZE];
        char      pattern[XT_STRING_MAX_PATTERN_SIZE];
        u_int8_t  patlen;
-       u_int8_t  invert;
+       union {
+               struct {
+                       u_int8_t invert;
+               } v0;
+
+               struct {
+                       u_int8_t flags;
+               } v1;
+       } u;
 
        /* Used internally by the kernel */
        struct ts_config __attribute__((aligned(8))) *config;