From f8ac329cc9a8822273aefc6686d58cae07e8a8f9 Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Wed, 26 Feb 2003 17:34:13 +0000 Subject: Add support for hex strings (Michael Rash) --- extensions/libipt_string.c | 67 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/extensions/libipt_string.c b/extensions/libipt_string.c index 20613fdc..dbed67db 100644 --- a/extensions/libipt_string.c +++ b/extensions/libipt_string.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -44,8 +45,70 @@ init(struct ipt_entry_match *m, unsigned int *nfcache) 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); + 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; + 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->string[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"); + } + 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->string[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]; + i++; + } + if (sindex > BM_MAX_NLEN) + exit_error(PARAMETER_PROBLEM, "STRING too long `%s'", s); + sindex++; + } } /* Function which parses command options; returns true if it -- cgit v1.2.3