From: Pablo Neira <pablo@eurodev.net>
To: Netfilter Development Mailinglist <netfilter-devel@lists.netfilter.org>
Cc: Harald Welte <laforge@netfilter.org>, Patrick McHardy <kaber@trash.net>
Subject: [PATCH 2/2] string match userspace part
Date: Sat, 20 Aug 2005 18:08:50 +0200 [thread overview]
Message-ID: <43075592.2080704@eurodev.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 236 bytes --]
Here attached the iptables part. It's based on the previous
implementation with some modifications to:
- add functionality to match packets by using window offsets
- add functionality to select the string matching algorithm
--
Pablo
[-- Attachment #2: string.patch --]
[-- Type: text/x-patch, Size: 7820 bytes --]
Index: extensions/libipt_string.c
===================================================================
--- extensions/libipt_string.c (revision 3906)
+++ extensions/libipt_string.c (working copy)
@@ -2,6 +2,11 @@
*
* Copyright (C) 2000 Emmanuel Roger <winfield@freegates.be>
*
+ * 2005-08-05 Pablo Neira Ayuso <pablo@eurodev.net>
+ * - reimplemented to use new string matching iptables match
+ * - add functionality to match packets by using window offsets
+ * - add functionality to select the string matching algorithm
+ *
* ChangeLog
* 29.12.2003: Michael Rash <mbr@cipherdyne.org>
* Fixed iptables save/restore for ascii strings
@@ -21,36 +26,62 @@
#include <stdlib.h>
#include <getopt.h>
#include <ctype.h>
-
#include <iptables.h>
+#include <stddef.h>
#include <linux/netfilter_ipv4/ipt_string.h>
-
/* Function which prints out usage message. */
static void
help(void)
{
printf(
"STRING match v%s options:\n"
+"--from Offset to start searching from\n"
+"--to Offset to stop searching\n"
+"--algo Algorithm\n"
"--string [!] string Match a string in a packet\n"
"--hex-string [!] string Match a hex string in a packet\n",
IPTABLES_VERSION);
}
-
static struct option opts[] = {
- { .name = "string", .has_arg = 1, .flag = 0, .val = '1' },
- { .name = "hex-string", .has_arg = 1, .flag = 0, .val = '2' },
- { .name = 0 }
+ { "from", 1, 0, '1' },
+ { "to", 1, 0, '2' },
+ { "algo", 1, 0, '3' },
+ { "string", 1, 0, '4' },
+ { "hex-string", 1, 0, '5' },
+ {0}
};
static void
+init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+ struct ipt_string_info *i = (struct ipt_string_info *) m->data;
+
+ if (i->to_offset == 0)
+ i->to_offset = (u_int16_t) ~0UL;
+}
+
+static void
parse_string(const unsigned char *s, struct ipt_string_info *info)
{
- if (strlen(s) <= BM_MAX_NLEN) strcpy(info->string, s);
- else exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
+ if (strlen(s) <= IPT_STRING_MAX_PATTERN_SIZE) {
+ strncpy(info->pattern, s, IPT_STRING_MAX_PATTERN_SIZE);
+ info->patlen = strlen(s);
+ return;
+ }
+ exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
}
+static void
+parse_algo(const unsigned char *s, struct ipt_string_info *info)
+{
+ if (strlen(s) <= IPT_STRING_MAX_ALGO_NAME_SIZE) {
+ strncpy(info->algo, s, IPT_STRING_MAX_ALGO_NAME_SIZE);
+ return;
+ }
+ exit_error(PARAMETER_PROBLEM, "ALGO too long `%s'", s);
+}
static void
parse_hex_string(const unsigned char *s, struct ipt_string_info *info)
@@ -92,7 +123,7 @@
exit_error(PARAMETER_PROBLEM,
"Bad literal placement at end of string");
}
- info->string[sindex] = s[i+1];
+ info->pattern[sindex] = s[i+1];
i += 2; /* skip over literal char */
literal_f = 0;
} else if (hex_f) {
@@ -114,22 +145,26 @@
if (! sscanf(hextmp, "%x", &schar))
exit_error(PARAMETER_PROBLEM,
"Invalid hex char `%c'", s[i]);
- info->string[sindex] = (char) schar;
+ info->pattern[sindex] = (char) schar;
if (s[i+2] == ' ')
i += 3; /* spaces included in the hex block */
else
i += 2;
} else { /* the char is not part of hex data, so just copy */
- info->string[sindex] = s[i];
+ info->pattern[sindex] = s[i];
i++;
}
- if (sindex > BM_MAX_NLEN)
+ if (sindex > IPT_STRING_MAX_PATTERN_SIZE)
exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s);
sindex++;
}
- info->len = sindex;
+ info->patlen = sindex;
}
+#define STRING 0x1
+#define ALGO 0x2
+#define FROM 0x4
+#define TO 0x8
/* Function which parses command options; returns true if it
ate an option */
@@ -143,28 +178,48 @@
switch (c) {
case '1':
- if (*flags)
+ if (*flags & FROM)
exit_error(PARAMETER_PROBLEM,
- "Can't specify multiple strings");
-
+ "Can't specify multiple --from");
+ stringinfo->from_offset = atoi(optarg);
+ *flags |= FROM;
+ break;
+ case '2':
+ if (*flags & TO)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify multiple --to");
+ stringinfo->to_offset = atoi(optarg);
+ *flags |= TO;
+ break;
+ case '3':
+ if (*flags & ALGO)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify multiple --algo");
+ parse_algo(optarg, stringinfo);
+ *flags |= ALGO;
+ break;
+ case '4':
+ if (*flags & STRING)
+ exit_error(PARAMETER_PROBLEM,
+ "Can't specify multiple --string");
check_inverse(optarg, &invert, &optind, 0);
parse_string(argv[optind-1], stringinfo);
if (invert)
stringinfo->invert = 1;
- stringinfo->len=strlen((char *)&stringinfo->string);
- *flags = 1;
+ stringinfo->patlen=strlen((char *)&stringinfo->pattern);
+ *flags |= STRING;
break;
- case '2':
- if (*flags)
+ case '5':
+ if (*flags & STRING)
exit_error(PARAMETER_PROBLEM,
- "Can't specify multiple strings");
+ "Can't specify multiple --hex-string");
check_inverse(optarg, &invert, &optind, 0);
parse_hex_string(argv[optind-1], stringinfo); /* sets length */
if (invert)
stringinfo->invert = 1;
- *flags = 1;
+ *flags |= STRING;
break;
default:
@@ -178,9 +233,13 @@
static void
final_check(unsigned int flags)
{
- if (!flags)
+ if (!(flags & STRING))
exit_error(PARAMETER_PROBLEM,
- "STRING match: You must specify `--string' or `--hex-string'");
+ "STRING match: You must specify `--string' or "
+ "`--hex-string'");
+ if (!(flags & ALGO))
+ exit_error(PARAMETER_PROBLEM,
+ "STRING match: You must specify `--algo'");
}
/* Test to see if the string contains non-printable chars or quotes */
@@ -237,13 +296,18 @@
const struct ipt_string_info *info =
(const struct ipt_string_info*) match->data;
- if (is_hex_string(info->string, info->len)) {
+ if (is_hex_string(info->pattern, info->patlen)) {
printf("STRING match %s", (info->invert) ? "!" : "");
- print_hex_string(info->string, info->len);
+ print_hex_string(info->pattern, info->patlen);
} else {
printf("STRING match %s", (info->invert) ? "!" : "");
- print_string(info->string, info->len);
+ print_string(info->pattern, info->patlen);
}
+ printf("ALGO name %s ", info->algo);
+ if (info->from_offset != 0)
+ printf("FROM %u ", info->from_offset);
+ if (info->to_offset != 0)
+ printf("TO %u", info->to_offset);
}
@@ -254,27 +318,33 @@
const struct ipt_string_info *info =
(const struct ipt_string_info*) match->data;
- if (is_hex_string(info->string, info->len)) {
+ if (is_hex_string(info->pattern, info->patlen)) {
printf("--hex-string %s", (info->invert) ? "! ": "");
- print_hex_string(info->string, info->len);
+ print_hex_string(info->pattern, info->patlen);
} else {
printf("--string %s", (info->invert) ? "! ": "");
- print_string(info->string, info->len);
+ print_string(info->pattern, info->patlen);
}
+ printf("--algo %s ", info->algo);
+ if (info->from_offset != 0)
+ printf("--from-offset %u ", info->from_offset);
+ if (info->to_offset != 0)
+ printf("--to-offset %u ", info->to_offset);
}
static struct iptables_match string = {
- .name = "string",
- .version = IPTABLES_VERSION,
- .size = IPT_ALIGN(sizeof(struct ipt_string_info)),
- .userspacesize = IPT_ALIGN(sizeof(struct ipt_string_info)),
- .help = &help,
- .parse = &parse,
- .final_check = &final_check,
- .print = &print,
- .save = &save,
- .extra_opts = opts
+ .name = "string",
+ .version = IPTABLES_VERSION,
+ .size = IPT_ALIGN(sizeof(struct ipt_string_info)),
+ .userspacesize = offsetof(struct ipt_string_info, config),
+ .help = help,
+ .init = init,
+ .parse = parse,
+ .final_check = final_check,
+ .print = print,
+ .save = save,
+ .extra_opts = opts
};
next reply other threads:[~2005-08-20 16:08 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-08-20 16:08 Pablo Neira [this message]
2005-08-28 8:07 ` [PATCH 2/2] string match userspace part Harald Welte
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=43075592.2080704@eurodev.net \
--to=pablo@eurodev.net \
--cc=kaber@trash.net \
--cc=laforge@netfilter.org \
--cc=netfilter-devel@lists.netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.