From ede46d6949cf1442196b70e3a9954ecec0e8ad27 Mon Sep 17 00:00:00 2001 From: Yasuyuki KOZAKAI Date: Tue, 24 Jul 2007 06:51:30 +0000 Subject: Moves libipt_string.c to libxt_string.c --- extensions/.string-test | 2 - extensions/.string-testx | 3 + extensions/libipt_string.c | 355 --------------------------------------------- extensions/libxt_string.c | 355 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 358 insertions(+), 357 deletions(-) delete mode 100755 extensions/.string-test create mode 100644 extensions/.string-testx delete mode 100644 extensions/libipt_string.c create mode 100644 extensions/libxt_string.c diff --git a/extensions/.string-test b/extensions/.string-test deleted file mode 100755 index 609f1c2b..00000000 --- a/extensions/.string-test +++ /dev/null @@ -1,2 +0,0 @@ -#! /bin/sh -[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_string.h ] && echo string diff --git a/extensions/.string-testx b/extensions/.string-testx new file mode 100644 index 00000000..b8de540f --- /dev/null +++ b/extensions/.string-testx @@ -0,0 +1,3 @@ +#! /bin/sh +[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_string.h ] || \ +[ -f $KERNEL_DIR/include/linux/netfilter/xt_string.h ] && echo string diff --git a/extensions/libipt_string.c b/extensions/libipt_string.c deleted file mode 100644 index e879dca1..00000000 --- a/extensions/libipt_string.c +++ /dev/null @@ -1,355 +0,0 @@ -/* Shared library add-on to iptables to add string matching support. - * - * Copyright (C) 2000 Emmanuel Roger - * - * 2005-08-05 Pablo Neira Ayuso - * - 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 - * Fixed iptables save/restore for ascii strings - * that contain space chars, and hex strings that - * contain embedded NULL chars. Updated to print - * strings in hex mode if any non-printable char - * is contained within the string. - * - * 27.01.2001: Gianni Tedesco - * Changed --tos to --string in save(). Also - * updated to work with slightly modified - * ipt_string_info. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* 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[] = { - { "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 xt_entry_match *m, unsigned int *nfcache) -{ - struct xt_string_info *i = (struct xt_string_info *) m->data; - - if (i->to_offset == 0) - i->to_offset = (u_int16_t) ~0UL; -} - -static void -parse_string(const char *s, struct xt_string_info *info) -{ - if (strlen(s) <= XT_STRING_MAX_PATTERN_SIZE) { - strncpy(info->pattern, s, XT_STRING_MAX_PATTERN_SIZE); - info->patlen = strlen(s); - return; - } - exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s); -} - -static void -parse_algo(const char *s, struct xt_string_info *info) -{ - if (strlen(s) <= XT_STRING_MAX_ALGO_NAME_SIZE) { - strncpy(info->algo, s, XT_STRING_MAX_ALGO_NAME_SIZE); - return; - } - exit_error(PARAMETER_PROBLEM, "ALGO too long `%s'", s); -} - -static void -parse_hex_string(const char *s, struct xt_string_info *info) -{ - int i=0, slen, sindex=0, schar; - short hex_f = 0, literal_f = 0; - char hextmp[3]; - - slen = strlen(s); - - if (slen == 0) { - exit_error(PARAMETER_PROBLEM, - "STRING must contain at least one char"); - } - - while (i < slen) { - if (s[i] == '\\' && !hex_f) { - literal_f = 1; - } else if (s[i] == '\\') { - exit_error(PARAMETER_PROBLEM, - "Cannot include literals in hex data"); - } else if (s[i] == '|') { - if (hex_f) - hex_f = 0; - else { - hex_f = 1; - /* get past any initial whitespace just after the '|' */ - while (s[i+1] == ' ') - i++; - } - if (i+1 >= slen) - break; - else - i++; /* advance to the next character */ - } - - if (literal_f) { - if (i+1 >= slen) { - exit_error(PARAMETER_PROBLEM, - "Bad literal placement at end of string"); - } - info->pattern[sindex] = s[i+1]; - i += 2; /* skip over literal char */ - literal_f = 0; - } else if (hex_f) { - if (i+1 >= slen) { - exit_error(PARAMETER_PROBLEM, - "Odd number of hex digits"); - } - if (i+2 >= slen) { - /* must end with a "|" */ - exit_error(PARAMETER_PROBLEM, "Invalid hex block"); - } - if (! isxdigit(s[i])) /* check for valid hex char */ - exit_error(PARAMETER_PROBLEM, "Invalid hex char `%c'", s[i]); - if (! isxdigit(s[i+1])) /* check for valid hex char */ - exit_error(PARAMETER_PROBLEM, "Invalid hex char `%c'", s[i+1]); - hextmp[0] = s[i]; - hextmp[1] = s[i+1]; - hextmp[2] = '\0'; - if (! sscanf(hextmp, "%x", &schar)) - exit_error(PARAMETER_PROBLEM, - "Invalid hex char `%c'", s[i]); - 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->pattern[sindex] = s[i]; - i++; - } - if (sindex > XT_STRING_MAX_PATTERN_SIZE) - exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s); - 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 */ -static int -parse(int c, char **argv, int invert, unsigned int *flags, - const void *entry, - unsigned int *nfcache, - struct xt_entry_match **match) -{ - struct xt_string_info *stringinfo = (struct xt_string_info *)(*match)->data; - - switch (c) { - case '1': - if (*flags & FROM) - exit_error(PARAMETER_PROBLEM, - "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->patlen=strlen((char *)&stringinfo->pattern); - *flags |= STRING; - break; - - case '5': - if (*flags & STRING) - exit_error(PARAMETER_PROBLEM, - "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 |= STRING; - break; - - default: - return 0; - } - return 1; -} - - -/* Final check; must have specified --string. */ -static void -final_check(unsigned int flags) -{ - if (!(flags & STRING)) - exit_error(PARAMETER_PROBLEM, - "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 */ -static unsigned short int -is_hex_string(const char *str, const unsigned short int len) -{ - unsigned int i; - for (i=0; i < len; i++) - if (! isprint(str[i])) - return 1; /* string contains at least one non-printable char */ - /* use hex output if the last char is a "\" */ - if ((unsigned char) str[len-1] == 0x5c) - return 1; - return 0; -} - -/* Print string with "|" chars included as one would pass to --hex-string */ -static void -print_hex_string(const char *str, const unsigned short int len) -{ - unsigned int i; - /* start hex block */ - printf("\"|"); - for (i=0; i < len; i++) { - /* see if we need to prepend a zero */ - if ((unsigned char) str[i] <= 0x0F) - printf("0%x", (unsigned char) str[i]); - else - printf("%x", (unsigned char) str[i]); - } - /* close hex block */ - printf("|\" "); -} - -static void -print_string(const char *str, const unsigned short int len) -{ - unsigned int i; - printf("\""); - for (i=0; i < len; i++) { - if ((unsigned char) str[i] == 0x22) /* escape any embedded quotes */ - printf("%c", 0x5c); - printf("%c", (unsigned char) str[i]); - } - printf("\" "); /* closing space and quote */ -} - -/* Prints out the matchinfo. */ -static void -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; - - if (is_hex_string(info->pattern, info->patlen)) { - printf("STRING match %s", (info->invert) ? "!" : ""); - print_hex_string(info->pattern, info->patlen); - } else { - printf("STRING match %s", (info->invert) ? "!" : ""); - 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); -} - - -/* Saves the union ipt_matchinfo in parseable form to stdout. */ -static void -save(const void *ip, const struct xt_entry_match *match) -{ - const struct xt_string_info *info = - (const struct xt_string_info*) match->data; - - if (is_hex_string(info->pattern, info->patlen)) { - printf("--hex-string %s", (info->invert) ? "! ": ""); - print_hex_string(info->pattern, info->patlen); - } else { - printf("--string %s", (info->invert) ? "! ": ""); - print_string(info->pattern, info->patlen); - } - printf("--algo %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); -} - - -static struct xtables_match string = { - .name = "string", - .family = AF_INET, - .version = IPTABLES_VERSION, - .size = XT_ALIGN(sizeof(struct xt_string_info)), - .userspacesize = offsetof(struct xt_string_info, config), - .help = help, - .init = init, - .parse = parse, - .final_check = final_check, - .print = print, - .save = save, - .extra_opts = opts -}; - - -void _init(void) -{ - xtables_register_match(&string); -} diff --git a/extensions/libxt_string.c b/extensions/libxt_string.c new file mode 100644 index 00000000..e879dca1 --- /dev/null +++ b/extensions/libxt_string.c @@ -0,0 +1,355 @@ +/* Shared library add-on to iptables to add string matching support. + * + * Copyright (C) 2000 Emmanuel Roger + * + * 2005-08-05 Pablo Neira Ayuso + * - 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 + * Fixed iptables save/restore for ascii strings + * that contain space chars, and hex strings that + * contain embedded NULL chars. Updated to print + * strings in hex mode if any non-printable char + * is contained within the string. + * + * 27.01.2001: Gianni Tedesco + * Changed --tos to --string in save(). Also + * updated to work with slightly modified + * ipt_string_info. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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[] = { + { "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 xt_entry_match *m, unsigned int *nfcache) +{ + struct xt_string_info *i = (struct xt_string_info *) m->data; + + if (i->to_offset == 0) + i->to_offset = (u_int16_t) ~0UL; +} + +static void +parse_string(const char *s, struct xt_string_info *info) +{ + if (strlen(s) <= XT_STRING_MAX_PATTERN_SIZE) { + strncpy(info->pattern, s, XT_STRING_MAX_PATTERN_SIZE); + info->patlen = strlen(s); + return; + } + exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s); +} + +static void +parse_algo(const char *s, struct xt_string_info *info) +{ + if (strlen(s) <= XT_STRING_MAX_ALGO_NAME_SIZE) { + strncpy(info->algo, s, XT_STRING_MAX_ALGO_NAME_SIZE); + return; + } + exit_error(PARAMETER_PROBLEM, "ALGO too long `%s'", s); +} + +static void +parse_hex_string(const char *s, struct xt_string_info *info) +{ + int i=0, slen, sindex=0, schar; + short hex_f = 0, literal_f = 0; + char hextmp[3]; + + slen = strlen(s); + + if (slen == 0) { + exit_error(PARAMETER_PROBLEM, + "STRING must contain at least one char"); + } + + while (i < slen) { + if (s[i] == '\\' && !hex_f) { + literal_f = 1; + } else if (s[i] == '\\') { + exit_error(PARAMETER_PROBLEM, + "Cannot include literals in hex data"); + } else if (s[i] == '|') { + if (hex_f) + hex_f = 0; + else { + hex_f = 1; + /* get past any initial whitespace just after the '|' */ + while (s[i+1] == ' ') + i++; + } + if (i+1 >= slen) + break; + else + i++; /* advance to the next character */ + } + + if (literal_f) { + if (i+1 >= slen) { + exit_error(PARAMETER_PROBLEM, + "Bad literal placement at end of string"); + } + info->pattern[sindex] = s[i+1]; + i += 2; /* skip over literal char */ + literal_f = 0; + } else if (hex_f) { + if (i+1 >= slen) { + exit_error(PARAMETER_PROBLEM, + "Odd number of hex digits"); + } + if (i+2 >= slen) { + /* must end with a "|" */ + exit_error(PARAMETER_PROBLEM, "Invalid hex block"); + } + if (! isxdigit(s[i])) /* check for valid hex char */ + exit_error(PARAMETER_PROBLEM, "Invalid hex char `%c'", s[i]); + if (! isxdigit(s[i+1])) /* check for valid hex char */ + exit_error(PARAMETER_PROBLEM, "Invalid hex char `%c'", s[i+1]); + hextmp[0] = s[i]; + hextmp[1] = s[i+1]; + hextmp[2] = '\0'; + if (! sscanf(hextmp, "%x", &schar)) + exit_error(PARAMETER_PROBLEM, + "Invalid hex char `%c'", s[i]); + 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->pattern[sindex] = s[i]; + i++; + } + if (sindex > XT_STRING_MAX_PATTERN_SIZE) + exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s); + 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 */ +static int +parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, + unsigned int *nfcache, + struct xt_entry_match **match) +{ + struct xt_string_info *stringinfo = (struct xt_string_info *)(*match)->data; + + switch (c) { + case '1': + if (*flags & FROM) + exit_error(PARAMETER_PROBLEM, + "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->patlen=strlen((char *)&stringinfo->pattern); + *flags |= STRING; + break; + + case '5': + if (*flags & STRING) + exit_error(PARAMETER_PROBLEM, + "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 |= STRING; + break; + + default: + return 0; + } + return 1; +} + + +/* Final check; must have specified --string. */ +static void +final_check(unsigned int flags) +{ + if (!(flags & STRING)) + exit_error(PARAMETER_PROBLEM, + "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 */ +static unsigned short int +is_hex_string(const char *str, const unsigned short int len) +{ + unsigned int i; + for (i=0; i < len; i++) + if (! isprint(str[i])) + return 1; /* string contains at least one non-printable char */ + /* use hex output if the last char is a "\" */ + if ((unsigned char) str[len-1] == 0x5c) + return 1; + return 0; +} + +/* Print string with "|" chars included as one would pass to --hex-string */ +static void +print_hex_string(const char *str, const unsigned short int len) +{ + unsigned int i; + /* start hex block */ + printf("\"|"); + for (i=0; i < len; i++) { + /* see if we need to prepend a zero */ + if ((unsigned char) str[i] <= 0x0F) + printf("0%x", (unsigned char) str[i]); + else + printf("%x", (unsigned char) str[i]); + } + /* close hex block */ + printf("|\" "); +} + +static void +print_string(const char *str, const unsigned short int len) +{ + unsigned int i; + printf("\""); + for (i=0; i < len; i++) { + if ((unsigned char) str[i] == 0x22) /* escape any embedded quotes */ + printf("%c", 0x5c); + printf("%c", (unsigned char) str[i]); + } + printf("\" "); /* closing space and quote */ +} + +/* Prints out the matchinfo. */ +static void +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; + + if (is_hex_string(info->pattern, info->patlen)) { + printf("STRING match %s", (info->invert) ? "!" : ""); + print_hex_string(info->pattern, info->patlen); + } else { + printf("STRING match %s", (info->invert) ? "!" : ""); + 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); +} + + +/* Saves the union ipt_matchinfo in parseable form to stdout. */ +static void +save(const void *ip, const struct xt_entry_match *match) +{ + const struct xt_string_info *info = + (const struct xt_string_info*) match->data; + + if (is_hex_string(info->pattern, info->patlen)) { + printf("--hex-string %s", (info->invert) ? "! ": ""); + print_hex_string(info->pattern, info->patlen); + } else { + printf("--string %s", (info->invert) ? "! ": ""); + print_string(info->pattern, info->patlen); + } + printf("--algo %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); +} + + +static struct xtables_match string = { + .name = "string", + .family = AF_INET, + .version = IPTABLES_VERSION, + .size = XT_ALIGN(sizeof(struct xt_string_info)), + .userspacesize = offsetof(struct xt_string_info, config), + .help = help, + .init = init, + .parse = parse, + .final_check = final_check, + .print = print, + .save = save, + .extra_opts = opts +}; + + +void _init(void) +{ + xtables_register_match(&string); +} -- cgit v1.2.3