From 086774b71f236b797a9e7a14e2bbb444b55e6d79 Mon Sep 17 00:00:00 2001 From: Gilbert Ramirez Date: Fri, 25 Jul 2003 03:44:05 +0000 Subject: Add to the fundamental types passed between the scanner and the parser. Besides "STRING", there is now "UNPARSED_STRING", where the distinction is that "STRING" was a double-quoted string and "UNPARSED_STRING" is just a sequence of characters that the scanner didn't know how to scan/parse, so it's up to the Ftype to parse it. This gives us more flexibility and prepares the dfilter parsing engine for the upcoming addition of the "contains" operator. In the process of doing this, I also re-did the double-quoted string support in the scanner, so that instead of the naively-simple support we used to have, double-quoted strings now can have embedded dobule-quotes, embedded octal sequences, and embedded hexadecimal sequences: "\"" embedded double-quote "\110" embedded octal "\x48" embedded hex Enhance the dfilter unit test script to be able to run a single collection of tests instead of having to run all of them all the time. svn path=/trunk/; revision=8083 --- doc/README.developer | 56 ++++++++++++++++-- doc/ethereal.pod.template | 17 ++++++ doc/tethereal.pod.template | 17 ++++++ epan/dfilter/grammar.lemon | 17 ++---- epan/dfilter/scanner.l | 77 ++++++++++++++++++++---- epan/dfilter/semcheck.c | 136 ++++++++++++++++++++++++++++++++++++------- epan/dfilter/sttype-string.c | 10 +++- epan/dfilter/syntax-tree.h | 3 +- epan/ftypes/ftype-bytes.c | 32 +++++----- epan/ftypes/ftype-double.c | 10 ++-- epan/ftypes/ftype-integer.c | 41 ++++++++----- epan/ftypes/ftype-ipv4.c | 10 ++-- epan/ftypes/ftype-none.c | 3 +- epan/ftypes/ftype-string.c | 9 ++- epan/ftypes/ftype-time.c | 10 ++-- epan/ftypes/ftype-tvbuff.c | 5 +- epan/ftypes/ftypes-int.h | 4 +- epan/ftypes/ftypes.c | 19 +++++- epan/ftypes/ftypes.h | 6 +- gtk/dfilter_expr_dlg.c | 4 +- tools/dfilter-test.py | 113 +++++++++++++++++++++++++++-------- 21 files changed, 476 insertions(+), 123 deletions(-) diff --git a/doc/README.developer b/doc/README.developer index 82f2151ac5..17395b40d7 100644 --- a/doc/README.developer +++ b/doc/README.developer @@ -1,4 +1,4 @@ -$Id: README.developer,v 1.76 2003/07/07 22:59:54 guy Exp $ +$Id: README.developer,v 1.77 2003/07/25 03:43:59 gram Exp $ This file is a HOWTO for Ethereal developers. It describes how to start coding a Ethereal protocol dissector and the use some of the important functions and @@ -208,7 +208,7 @@ code inside is needed only if you are using the "snprintf()" function. -The "$Id: README.developer,v 1.76 2003/07/07 22:59:54 guy Exp $" +The "$Id: README.developer,v 1.77 2003/07/25 03:43:59 gram Exp $" in the comment will be updated by CVS when the file is checked in; it will allow the RCS "ident" command to report which version of the file is currently checked out. @@ -218,7 +218,7 @@ version of the file is currently checked out. * Routines for PROTONAME dissection * Copyright 2000, YOUR_NAME * - * $Id: README.developer,v 1.76 2003/07/07 22:59:54 guy Exp $ + * $Id: README.developer,v 1.77 2003/07/25 03:43:59 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -2136,7 +2136,55 @@ a dissector. 4.0 Extending Wiretap. -5.0 Adding new capabilities. +5.0 How the Display Filter Engine works + +code: +epan/dfilter/* - the display filter engine, including + scanner, parser, syntax-tree semantics checker, DFVM bytecode + generator, and DFVM engine. +epan/ftypes/* - the definitions of the various FT_* field types. +epan/proto.c - proto_tree-related routines + +5.1 Parsing text + +The scanner/parser pair read the string representing the display filter and +convert it into a very simple syntax tree. The syntax tree is very simple in that +it is possible that many of the nodes contain unparsed chunks of text from the display +filter. + +5.1 Enhancing the syntax tree. + +The semantics of the simple syntax tree are checked to make sure that the fields +that are being compared are being compared to appropriate values. For example, +if a field is an integer, it can't be compared to a string, unless a value_string +has been defined for that field. + +During the process of checking the semantics, the simple syntax tree is fleshed out +and no longer contains nodes with unparsed information. The syntax tree is no +longer in its simple form, but in its complete form. + +5.2 Converting to DFVM bytecode + +The syntax tree is analyzed to create a sequence of bytecodes in the "DFVM" language. +"DFVM" stands for Display Filter Virtual Machine. The DFVM is similar in spirit, but +not in definition, to the BPF VM that libpcap uses to analyze packets. + +A virtual bytecode is created and used so that the actual process of filtering packets +will be fast. That is, it should be faster to process a list of VM bytecodes than +to attempt to filter packets directly from the syntax tree. (heh... no measurement +has been made to support this supposition) + +5.3 Filtering + +Once the DFVM bytecode has been produced, its a simple matter of running the +DFVM engine against the proto_tree from the packet dissection, using the DFVM bytecodes +as instructions. If the DFVM bytecode is known before packet dissection occurs, +the proto_tree-related code can be "primed" to store away pointers to field_info +structures that are interesting to the display filter. This makes lookup of those +field_info structures during the filtering process faster. + + +6.0 Adding new capabilities. diff --git a/doc/ethereal.pod.template b/doc/ethereal.pod.template index 509894090c..5826209eea 100644 --- a/doc/ethereal.pod.template +++ b/doc/ethereal.pod.template @@ -1332,6 +1332,23 @@ you will be using hexadecimal when testing for IPX network values: ipx.srcnet == 0xc0a82c00 +Strings are enclosed in double-quotes: + + http.request.method == "POST" + +Inside doulbe quotes, you may use the backslash to embed a double-quote, +or an arbitrary byte represented in either octal or hexadecimal. + + browser.comment = "An embedded \" double-quote" + +Use of hexadecimal to look for "HEAD": + + http.request.method == "\x48EAD" + +Use of octal to look for "HEAD": + + http.request.method == "\x110EAD" + A slice operator also exists. You can check the substring (byte-string) of any protocol or field. For example, you can filter on the vendor portion of an ethernet address (the first three bytes) like diff --git a/doc/tethereal.pod.template b/doc/tethereal.pod.template index 43a61436fd..5ed92b3091 100644 --- a/doc/tethereal.pod.template +++ b/doc/tethereal.pod.template @@ -672,6 +672,23 @@ you will be using hexadecimal when testing for IPX network values: ipx.srcnet == 0xc0a82c00 +Strings are enclosed in double-quotes: + + http.request.method == "POST" + +Inside doulbe quotes, you may use the backslash to embed a double-quote, +or an arbitrary byte represented in either octal or hexadecimal. + + browser.comment = "An embedded \" double-quote" + +Use of hexadecimal to look for "HEAD": + + http.request.method == "\x48EAD" + +Use of octal to look for "HEAD": + + http.request.method == "\x110EAD" + A slice operator also exists. You can check the substring (byte-string) of any protocol or field. For example, you can filter on the vendor portion of an ethernet address (the first three bytes) like diff --git a/epan/dfilter/grammar.lemon b/epan/dfilter/grammar.lemon index e252b496a8..35310adf7d 100644 --- a/epan/dfilter/grammar.lemon +++ b/epan/dfilter/grammar.lemon @@ -1,4 +1,4 @@ -/* $Id: grammar.lemon,v 1.4 2001/06/22 16:29:13 gram Exp $ */ +/* $Id: grammar.lemon,v 1.5 2003/07/25 03:44:01 gram Exp $ */ %include { #ifdef HAVE_CONFIG_H @@ -71,6 +71,10 @@ any "error" symbols are shifted, if possible. */ dfilter_fail("The string \"%s\" was unexpected in this context.", stnode_data(TOKEN)); break; + case STTYPE_UNPARSED: + dfilter_fail("\"%s\" was unexpected in this context.", + stnode_data(TOKEN)); + break; case STTYPE_INTEGER: dfilter_fail("The integer %u was unexpected in this context.", stnode_value(TOKEN)); @@ -150,18 +154,9 @@ logical_test(T) ::= FIELD(F). /* Entities, or things that can be compared/tested/checked */ entity(E) ::= FIELD(F). { E = F; } entity(E) ::= STRING(S). { E = S; } +entity(E) ::= UNPARSED(U). { E = U; } entity(E) ::= range(R). { E = R; } -/* CIDR: ADDRESS/NET */ -entity(E) ::= STRING(A) SLASH STRING(N). -{ - E = stnode_new(STTYPE_STRING, g_strjoin("/", stnode_data(A), - stnode_data(N), NULL)); - - stnode_free(A); - stnode_free(N); -} - /* Ranges */ range(R) ::= FIELD(F) LBRACKET drnode_list(L) RBRACKET. diff --git a/epan/dfilter/scanner.l b/epan/dfilter/scanner.l index c65c12dcc9..ca23626457 100644 --- a/epan/dfilter/scanner.l +++ b/epan/dfilter/scanner.l @@ -1,6 +1,6 @@ %{ /* - * $Id: scanner.l,v 1.7 2002/04/29 07:55:32 guy Exp $ + * $Id: scanner.l,v 1.8 2003/07/25 03:44:01 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -46,12 +46,15 @@ static int set_lval(int token, gpointer data); static int set_lval_int(int token, char *s); static int simple(int token); static gboolean str_to_guint32(char *s, guint32* pint); +GString* quoted_string = NULL; + +#define SCAN_FAILED 0 %} %x RANGE_INT %x RANGE_PUNCT - +%x DQUOTE %% @@ -61,7 +64,6 @@ static gboolean str_to_guint32(char *s, guint32* pint); "(" return simple(TOKEN_LPAREN); ")" return simple(TOKEN_RPAREN); -"/" return simple(TOKEN_SLASH); "==" return simple(TOKEN_TEST_EQ); "eq" return simple(TOKEN_TEST_EQ); @@ -94,6 +96,7 @@ static gboolean str_to_guint32(char *s, guint32* pint); BEGIN(RANGE_PUNCT); return set_lval_int(TOKEN_INTEGER, yytext); } + [+-]?0x[[:xdigit:]]+ { BEGIN(RANGE_PUNCT); return set_lval_int(TOKEN_INTEGER, yytext); @@ -119,13 +122,65 @@ static gboolean str_to_guint32(char *s, guint32* pint); return simple(TOKEN_RBRACKET); } +\" { + /* start quote */ + /* The example of how to scan for strings was taken from + the flex 2.5.4 manual, from the section "Start Conditions". + See: + http://www.gnu.org/manual/flex-2.5.4/html_node/flex_11.html */ + + BEGIN(DQUOTE); + g_assert(!quoted_string); + quoted_string = g_string_new(""); +} + +\" { + /* end quote */ + char *my_string = g_strdup(quoted_string->str); + BEGIN(INITIAL); + g_string_free(quoted_string, TRUE); + quoted_string = NULL; + return set_lval(TOKEN_STRING, my_string); +} -\"[^"]*\" { - return set_lval(TOKEN_STRING, g_substrdup(yytext, 1, -2)); +\\[0-7]{1,3} { + /* octal sequence */ + unsigned int result; + sscanf(yytext + 1, "%o", &result); + if (result > 0xff) { + g_string_free(quoted_string, TRUE); + quoted_string = NULL; + dfilter_fail("%s is larger than 255.", yytext); + return SCAN_FAILED; + } + g_string_append_c(quoted_string, result); } +\\x[[:xdigit:]]{1,2} { + /* hex sequence */ + unsigned int result; + sscanf(yytext + 2, "%x", &result); + g_string_append_c(quoted_string, result); +} +\\. { + /* escaped character */ + g_string_append_c(quoted_string, yytext[1]); +} + +[^\\\"]+ { + /* non-escaped string */ + g_string_append(quoted_string, yytext); +} + + + +[-[:alnum:]_\.]+\/[[:digit:]]+ { + /* CIDR */ + return set_lval(TOKEN_UNPARSED, g_strdup(yytext)); +} + [-[:alnum:]_.:]+ { /* Is it a field name? */ header_field_info *hfinfo; @@ -136,14 +191,14 @@ static gboolean str_to_guint32(char *s, guint32* pint); return set_lval(TOKEN_FIELD, hfinfo); } else { - /* No, so treat it as a string */ - return set_lval(TOKEN_STRING, g_strdup(yytext)); + /* No, so treat it as an unparsed string */ + return set_lval(TOKEN_UNPARSED, g_strdup(yytext)); } } . { /* Default */ - return set_lval(TOKEN_STRING, g_strdup(yytext)); + return set_lval(TOKEN_UNPARSED, g_strdup(yytext)); } @@ -160,7 +215,6 @@ simple(int token) case TOKEN_COLON: case TOKEN_COMMA: case TOKEN_HYPHEN: - case TOKEN_SLASH: case TOKEN_TEST_EQ: case TOKEN_TEST_NE: case TOKEN_TEST_GT: @@ -189,6 +243,9 @@ set_lval(int token, gpointer data) case TOKEN_FIELD: type_id = STTYPE_FIELD; break; + case TOKEN_UNPARSED: + type_id = STTYPE_UNPARSED; + break; default: g_assert_not_reached(); } @@ -204,7 +261,7 @@ set_lval_int(int token, char *s) guint32 val; if (!str_to_guint32(s, &val)) { - return 0; + return SCAN_FAILED; } switch (token) { diff --git a/epan/dfilter/semcheck.c b/epan/dfilter/semcheck.c index 123864b7ff..faba2942d4 100644 --- a/epan/dfilter/semcheck.c +++ b/epan/dfilter/semcheck.c @@ -1,5 +1,5 @@ /* - * $Id: semcheck.c,v 1.17 2003/06/13 07:39:26 guy Exp $ + * $Id: semcheck.c,v 1.18 2003/07/25 03:44:01 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -47,15 +47,15 @@ compatible_ftypes(ftenum_t a, ftenum_t b) switch (a) { case FT_NONE: case FT_PROTOCOL: - case FT_FLOAT: - case FT_DOUBLE: + case FT_FLOAT: /* XXX - should be able to compare with INT */ + case FT_DOUBLE: /* XXX - should be able to compare with INT */ case FT_ABSOLUTE_TIME: case FT_RELATIVE_TIME: case FT_IPv4: case FT_IPv6: case FT_IPXNET: - case FT_INT64: - case FT_UINT64: + case FT_INT64: /* XXX - should be able to compare with INT */ + case FT_UINT64: /* XXX - should be able to compare with INT */ return a == b; case FT_ETHER: @@ -187,7 +187,7 @@ mk_fvalue_from_val_string(header_field_info *hfinfo, char *s) return mk_uint32_fvalue(FALSE); } else { - dfilter_fail("\"%s\" cannot be found among the possible values for %s.", + dfilter_fail("\"%s\" cannot be found among the possible values for %s.", s, hfinfo->abbrev); return NULL; } @@ -256,9 +256,11 @@ is_bytes_type(enum ftenum type) return FALSE; } +/* If the LHS of a relation test is a FIELD, run some checks + * and possibly some modifications of syntax tree nodes. */ static void -check_relation_LHS_FIELD(FtypeCanFunc can_func, stnode_t *st_node, - stnode_t *st_arg1, stnode_t *st_arg2) +check_relation_LHS_FIELD(const char *relation_string, FtypeCanFunc can_func, + stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2) { stnode_t *new_st; sttype_id_t type1, type2; @@ -275,8 +277,9 @@ check_relation_LHS_FIELD(FtypeCanFunc can_func, stnode_t *st_node, ftype1 = hfinfo1->type; if (!can_func(ftype1)) { - dfilter_fail("%s (type=%s) cannot participate in specified comparison.", - hfinfo1->abbrev, ftype_pretty_name(ftype1)); + dfilter_fail("%s (type=%s) cannot participate in '%s' comparison.", + hfinfo1->abbrev, ftype_pretty_name(ftype1), + relation_string); THROW(TypeError); } @@ -313,6 +316,21 @@ check_relation_LHS_FIELD(FtypeCanFunc can_func, stnode_t *st_node, sttype_test_set2_args(st_node, st_arg1, new_st); stnode_free(st_arg2); } + else if (type2 == STTYPE_UNPARSED) { + s = stnode_data(st_arg2); + fvalue = fvalue_from_unparsed(ftype1, s, dfilter_fail); + if (!fvalue) { + /* check value_string */ + fvalue = mk_fvalue_from_val_string(hfinfo1, s); + if (!fvalue) { + THROW(TypeError); + } + } + + new_st = stnode_new(STTYPE_FVALUE, fvalue); + sttype_test_set2_args(st_node, st_arg1, new_st); + stnode_free(st_arg2); + } else if (type2 == STTYPE_RANGE) { if (!is_bytes_type(ftype1)) { if (!ftype_can_slice(ftype1)) { @@ -393,6 +411,60 @@ check_relation_LHS_STRING(FtypeCanFunc can_func _U_, stnode_t *st_node, } } +static void +check_relation_LHS_UNPARSED(FtypeCanFunc can_func _U_, stnode_t *st_node, + stnode_t *st_arg1, stnode_t *st_arg2) +{ + stnode_t *new_st; + sttype_id_t type1, type2; + header_field_info *hfinfo2; + ftenum_t ftype2; + fvalue_t *fvalue; + char *s; + + type1 = stnode_type_id(st_arg1); + type2 = stnode_type_id(st_arg2); + + if (type2 == STTYPE_FIELD) { + hfinfo2 = stnode_data(st_arg2); + ftype2 = hfinfo2->type; + + s = stnode_data(st_arg1); + fvalue = fvalue_from_unparsed(ftype2, s, dfilter_fail); + if (!fvalue) { + /* check value_string */ + fvalue = mk_fvalue_from_val_string(hfinfo2, s); + if (!fvalue) { + THROW(TypeError); + } + } + + new_st = stnode_new(STTYPE_FVALUE, fvalue); + sttype_test_set2_args(st_node, new_st, st_arg2); + stnode_free(st_arg1); + } + else if (type2 == STTYPE_STRING) { + /* Well now that's silly... */ + dfilter_fail("Neither \"%s\" nor \"%s\" are field or protocol names.", + stnode_data(st_arg1), + stnode_data(st_arg2)); + THROW(TypeError); + } + else if (type2 == STTYPE_RANGE) { + s = stnode_data(st_arg1); + fvalue = fvalue_from_unparsed(FT_BYTES, s, dfilter_fail); + if (!fvalue) { + THROW(TypeError); + } + new_st = stnode_new(STTYPE_FVALUE, fvalue); + sttype_test_set2_args(st_node, new_st, st_arg2); + stnode_free(st_arg1); + } + else { + g_assert_not_reached(); + } +} + struct check_drange_sanity_args { drange_node* err_node; }; @@ -515,6 +587,16 @@ check_relation_LHS_RANGE(FtypeCanFunc can_func _U_, stnode_t *st_node, sttype_test_set2_args(st_node, st_arg1, new_st); stnode_free(st_arg2); } + else if (type2 == STTYPE_UNPARSED) { + s = stnode_data(st_arg2); + fvalue = fvalue_from_unparsed(FT_BYTES, s, dfilter_fail); + if (!fvalue) { + THROW(TypeError); + } + new_st = stnode_new(STTYPE_FVALUE, fvalue); + sttype_test_set2_args(st_node, st_arg1, new_st); + stnode_free(st_arg2); + } else if (type2 == STTYPE_RANGE) { check_drange_sanity(st_arg2); /* XXX - check lengths of both ranges */ @@ -525,13 +607,14 @@ check_relation_LHS_RANGE(FtypeCanFunc can_func _U_, stnode_t *st_node, } +/* Check the semantics of any relational test. */ static void -check_relation(FtypeCanFunc can_func, stnode_t *st_node, +check_relation(const char *relation_string, FtypeCanFunc can_func, stnode_t *st_node, stnode_t *st_arg1, stnode_t *st_arg2) { switch (stnode_type_id(st_arg1)) { case STTYPE_FIELD: - check_relation_LHS_FIELD(can_func, st_node, st_arg1, st_arg2); + check_relation_LHS_FIELD(relation_string, can_func, st_node, st_arg1, st_arg2); break; case STTYPE_STRING: check_relation_LHS_STRING(can_func, st_node, st_arg1, st_arg2); @@ -539,6 +622,9 @@ check_relation(FtypeCanFunc can_func, stnode_t *st_node, case STTYPE_RANGE: check_relation_LHS_RANGE(can_func, st_node, st_arg1, st_arg2); break; + case STTYPE_UNPARSED: + check_relation_LHS_UNPARSED(can_func, st_node, st_arg1, st_arg2); + break; case STTYPE_UNINITIALIZED: case STTYPE_TEST: @@ -549,6 +635,7 @@ check_relation(FtypeCanFunc can_func, stnode_t *st_node, } } +/* Check the semantics of any type of TEST */ static void check_test(stnode_t *st_node) { @@ -577,34 +664,33 @@ check_test(stnode_t *st_node) break; case TEST_OP_EQ: - check_relation(ftype_can_eq, st_node, st_arg1, st_arg2); + check_relation("==", ftype_can_eq, st_node, st_arg1, st_arg2); break; case TEST_OP_NE: - check_relation(ftype_can_ne, st_node, st_arg1, st_arg2); + check_relation("!=", ftype_can_ne, st_node, st_arg1, st_arg2); break; case TEST_OP_GT: - check_relation(ftype_can_gt, st_node, st_arg1, st_arg2); + check_relation(">", ftype_can_gt, st_node, st_arg1, st_arg2); break; case TEST_OP_GE: - check_relation(ftype_can_ge, st_node, st_arg1, st_arg2); + check_relation(">=", ftype_can_ge, st_node, st_arg1, st_arg2); break; case TEST_OP_LT: - check_relation(ftype_can_lt, st_node, st_arg1, st_arg2); + check_relation("<", ftype_can_lt, st_node, st_arg1, st_arg2); break; case TEST_OP_LE: - check_relation(ftype_can_le, st_node, st_arg1, st_arg2); + check_relation("<=", ftype_can_le, st_node, st_arg1, st_arg2); break; } } +/* Check the entire syntax tree. */ static void semcheck(stnode_t *st_node) { - const char *name; - - name = stnode_type_name(st_node); - + /* The parser assures that the top-most syntax-tree + * node will be a TEST node, no matter what. So assert that. */ switch (stnode_type_id(st_node)) { case STTYPE_TEST: check_test(st_node); @@ -615,9 +701,15 @@ semcheck(stnode_t *st_node) } +/* Check the syntax tree for semantic errors, and convert + * some of the nodes into the form they need to be in order to + * later generate the DFVM bytecode. */ gboolean dfw_semcheck(dfwork_t *dfw) { + /* Instead of having to check for errors at every stage of + * the semantic-checking, the semantic-checking code will + * throw an exception if a problem is found. */ TRY { semcheck(dfw->st_root); } diff --git a/epan/dfilter/sttype-string.c b/epan/dfilter/sttype-string.c index 4bd8cbc0b1..160fce82d7 100644 --- a/epan/dfilter/sttype-string.c +++ b/epan/dfilter/sttype-string.c @@ -1,5 +1,5 @@ /* - * $Id: sttype-string.c,v 1.3 2002/08/28 20:40:56 jmayer Exp $ + * $Id: sttype-string.c,v 1.4 2003/07/25 03:44:01 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -46,5 +46,13 @@ sttype_register_string(void) string_free, }; + static sttype_t unparsed_type = { + STTYPE_UNPARSED, + "UNPARSED", + string_new, + string_free, + }; + sttype_register(&string_type); + sttype_register(&unparsed_type); } diff --git a/epan/dfilter/syntax-tree.h b/epan/dfilter/syntax-tree.h index 88c273b38d..f421609a60 100644 --- a/epan/dfilter/syntax-tree.h +++ b/epan/dfilter/syntax-tree.h @@ -1,5 +1,5 @@ /* - * $Id: syntax-tree.h,v 1.4 2002/08/28 20:40:56 jmayer Exp $ + * $Id: syntax-tree.h,v 1.5 2003/07/25 03:44:01 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -30,6 +30,7 @@ typedef enum { STTYPE_UNINITIALIZED, STTYPE_TEST, + STTYPE_UNPARSED, STTYPE_STRING, STTYPE_FIELD, STTYPE_FVALUE, diff --git a/epan/ftypes/ftype-bytes.c b/epan/ftypes/ftype-bytes.c index 28329f7295..25c2f445ec 100644 --- a/epan/ftypes/ftype-bytes.c +++ b/epan/ftypes/ftype-bytes.c @@ -1,5 +1,5 @@ /* - * $Id: ftype-bytes.c,v 1.15 2003/06/11 21:24:53 gram Exp $ + * $Id: ftype-bytes.c,v 1.16 2003/07/25 03:44:02 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -129,7 +129,7 @@ is_byte_sep(guint8 c) } static gboolean -val_from_string(fvalue_t *fv, char *s, LogFunc logfunc) +val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc) { GByteArray *bytes; guint8 val; @@ -226,7 +226,7 @@ val_from_string(fvalue_t *fv, char *s, LogFunc logfunc) } static gboolean -ether_from_string(fvalue_t *fv, char *s, LogFunc logfunc) +ether_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc) { guint8 *mac; @@ -235,7 +235,7 @@ ether_from_string(fvalue_t *fv, char *s, LogFunc logfunc) * up as an Ethernet host name if it does, and if that fails, * we'll log a message. */ - if (val_from_string(fv, s, NULL)) { + if (val_from_unparsed(fv, s, NULL)) { return TRUE; } @@ -251,7 +251,7 @@ ether_from_string(fvalue_t *fv, char *s, LogFunc logfunc) } static gboolean -ipv6_from_string(fvalue_t *fv, char *s, LogFunc logfunc) +ipv6_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc) { guint8 buffer[16]; @@ -265,7 +265,7 @@ ipv6_from_string(fvalue_t *fv, char *s, LogFunc logfunc) } static gboolean -u64_from_string(fvalue_t *fv, char *s, LogFunc logfunc) +u64_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc) { guint8 buffer[8]; @@ -279,7 +279,7 @@ u64_from_string(fvalue_t *fv, char *s, LogFunc logfunc) } static gboolean -i64_from_string(fvalue_t *fv, char *s, LogFunc logfunc) +i64_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc) { guint8 buffer[8]; @@ -587,7 +587,8 @@ ftype_register_bytes(void) 0, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_free, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ bytes_to_repr, /* val_to_string_repr */ bytes_repr_len, /* len_string_repr */ @@ -616,7 +617,8 @@ ftype_register_bytes(void) 0, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_free, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ bytes_to_repr, /* val_to_string_repr */ bytes_repr_len, /* len_string_repr */ @@ -645,7 +647,8 @@ ftype_register_bytes(void) ETHER_LEN, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_free, /* free_value */ - ether_from_string, /* val_from_string */ + ether_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ bytes_to_repr, /* val_to_string_repr */ bytes_repr_len, /* len_string_repr */ @@ -674,7 +677,8 @@ ftype_register_bytes(void) IPv6_LEN, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_free, /* free_value */ - ipv6_from_string, /* val_from_string */ + ipv6_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -703,7 +707,8 @@ ftype_register_bytes(void) U64_LEN, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_free, /* free_value */ - u64_from_string, /* val_from_string */ + u64_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -732,7 +737,8 @@ ftype_register_bytes(void) U64_LEN, /* wire_size */ bytes_fvalue_new, /* new_value */ bytes_fvalue_free, /* free_value */ - i64_from_string, /* val_from_string */ + i64_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ diff --git a/epan/ftypes/ftype-double.c b/epan/ftypes/ftype-double.c index 2091bda846..5ee3aee44d 100644 --- a/epan/ftypes/ftype-double.c +++ b/epan/ftypes/ftype-double.c @@ -1,5 +1,5 @@ /* - * $Id: ftype-double.c,v 1.8 2003/02/08 04:22:37 gram Exp $ + * $Id: ftype-double.c,v 1.9 2003/07/25 03:44:02 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -48,7 +48,7 @@ value_get_floating(fvalue_t *fv) } static gboolean -val_from_string(fvalue_t *fv, char *s, LogFunc logfunc) +val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc) { char *endptr = NULL; @@ -123,7 +123,8 @@ ftype_register_double(void) 0, double_fvalue_new, NULL, - val_from_string, + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -152,7 +153,8 @@ ftype_register_double(void) 0, double_fvalue_new, NULL, - val_from_string, + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ diff --git a/epan/ftypes/ftype-integer.c b/epan/ftypes/ftype-integer.c index d170dec129..818b6cce7a 100644 --- a/epan/ftypes/ftype-integer.c +++ b/epan/ftypes/ftype-integer.c @@ -1,5 +1,5 @@ /* - * $Id: ftype-integer.c,v 1.13 2003/06/11 21:24:53 gram Exp $ + * $Id: ftype-integer.c,v 1.14 2003/07/25 03:44:02 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -49,7 +49,7 @@ get_integer(fvalue_t *fv) } static gboolean -val_from_string(fvalue_t *fv, char *s, LogFunc logfunc) +val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc) { char *endptr; @@ -78,7 +78,7 @@ val_from_string(fvalue_t *fv, char *s, LogFunc logfunc) } static gboolean -ipxnet_from_string(fvalue_t *fv, char *s, LogFunc logfunc) +ipxnet_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc) { guint32 val; gboolean known; @@ -88,7 +88,7 @@ ipxnet_from_string(fvalue_t *fv, char *s, LogFunc logfunc) * up as an IPX network name if it does, and if that fails, * we'll log a message. */ - if (val_from_string(fv, s, NULL)) { + if (val_from_unparsed(fv, s, NULL)) { return TRUE; } @@ -223,7 +223,8 @@ ftype_register_integers(void) 1, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -251,7 +252,8 @@ ftype_register_integers(void) 2, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -279,7 +281,8 @@ ftype_register_integers(void) 3, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -307,7 +310,8 @@ ftype_register_integers(void) 4, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -335,7 +339,8 @@ ftype_register_integers(void) 1, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -363,7 +368,8 @@ ftype_register_integers(void) 2, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -391,7 +397,8 @@ ftype_register_integers(void) 3, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -419,7 +426,8 @@ ftype_register_integers(void) 4, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -447,7 +455,8 @@ ftype_register_integers(void) 0, /* wire_size */ boolean_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ boolean_to_repr, /* val_to_string_repr */ boolean_repr_len, /* len_string_repr */ @@ -476,7 +485,8 @@ ftype_register_integers(void) 4, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - ipxnet_from_string, /* val_from_string */ + ipxnet_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -505,7 +515,8 @@ ftype_register_integers(void) 4, /* wire_size */ int_fvalue_new, /* new_value */ NULL, /* free_value */ - val_from_string, /* val_from_string */ + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ diff --git a/epan/ftypes/ftype-ipv4.c b/epan/ftypes/ftype-ipv4.c index ad978a7915..e583f17aa0 100644 --- a/epan/ftypes/ftype-ipv4.c +++ b/epan/ftypes/ftype-ipv4.c @@ -1,5 +1,5 @@ /* - * $Id: ftype-ipv4.c,v 1.10 2003/02/08 04:22:37 gram Exp $ + * $Id: ftype-ipv4.c,v 1.11 2003/07/25 03:44:02 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -45,7 +45,7 @@ value_get(fvalue_t *fv) } static gboolean -val_from_string(fvalue_t *fv, char *s, LogFunc logfunc) +val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc) { guint32 addr; unsigned int nmask_bits; @@ -98,7 +98,8 @@ val_from_string(fvalue_t *fv, char *s, LogFunc logfunc) return FALSE; } - nmask_fvalue = fvalue_from_string(FT_UINT32, net_str, logfunc); + /* XXX - this is inefficient */ + nmask_fvalue = fvalue_from_unparsed(FT_UINT32, net_str, logfunc); g_free(s_copy); if (!nmask_fvalue) { return FALSE; @@ -167,7 +168,8 @@ ftype_register_ipv4(void) 4, NULL, NULL, - val_from_string, + val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ diff --git a/epan/ftypes/ftype-none.c b/epan/ftypes/ftype-none.c index 864c8a6b9a..bf6cd400eb 100644 --- a/epan/ftypes/ftype-none.c +++ b/epan/ftypes/ftype-none.c @@ -1,5 +1,5 @@ /* - * $Id: ftype-none.c,v 1.5 2003/02/08 04:22:37 gram Exp $ + * $Id: ftype-none.c,v 1.6 2003/07/25 03:44:03 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -39,6 +39,7 @@ ftype_register_none(void) NULL, NULL, NULL, + NULL, NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ diff --git a/epan/ftypes/ftype-string.c b/epan/ftypes/ftype-string.c index 312d1baa02..f1d529709a 100644 --- a/epan/ftypes/ftype-string.c +++ b/epan/ftypes/ftype-string.c @@ -1,5 +1,5 @@ /* - * $Id: ftype-string.c,v 1.9 2003/06/11 21:24:53 gram Exp $ + * $Id: ftype-string.c,v 1.10 2003/07/25 03:44:03 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -154,6 +154,7 @@ ftype_register_string(void) 0, /* wire_size */ string_fvalue_new, /* new_value */ string_fvalue_free, /* free_value */ + val_from_string, /* val_from_unparsed */ val_from_string, /* val_from_string */ string_to_repr, /* val_to_string_repr */ string_repr_len, /* len_string_repr */ @@ -182,7 +183,8 @@ ftype_register_string(void) 0, string_fvalue_new, string_fvalue_free, - val_from_string, + val_from_string, /* val_from_unparsed */ + val_from_string, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -210,7 +212,8 @@ ftype_register_string(void) 0, string_fvalue_new, string_fvalue_free, - val_from_string, + val_from_string, /* val_from_unparsed */ + val_from_string, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ diff --git a/epan/ftypes/ftype-time.c b/epan/ftypes/ftype-time.c index f35483da7b..818467a380 100644 --- a/epan/ftypes/ftype-time.c +++ b/epan/ftypes/ftype-time.c @@ -1,5 +1,5 @@ /* - * $Id: ftype-time.c,v 1.18 2003/02/08 04:22:37 gram Exp $ + * $Id: ftype-time.c,v 1.19 2003/07/25 03:44:03 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -167,7 +167,7 @@ get_nsecs(char *startp, int *nsecs) } static gboolean -relative_val_from_string(fvalue_t *fv, char *s, LogFunc logfunc) +relative_val_from_unparsed(fvalue_t *fv, char *s, LogFunc logfunc) { char *curptr, *endptr; @@ -307,7 +307,8 @@ ftype_register_time(void) 0, time_fvalue_new, NULL, - absolute_val_from_string, + absolute_val_from_string, /* val_from_unparsed */ + absolute_val_from_string, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ @@ -334,7 +335,8 @@ ftype_register_time(void) 0, time_fvalue_new, NULL, - relative_val_from_string, + relative_val_from_unparsed, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ diff --git a/epan/ftypes/ftype-tvbuff.c b/epan/ftypes/ftype-tvbuff.c index f051fd3094..43050f9f9f 100644 --- a/epan/ftypes/ftype-tvbuff.c +++ b/epan/ftypes/ftype-tvbuff.c @@ -1,5 +1,5 @@ /* - * $Id: ftype-tvbuff.c,v 1.8 2003/02/08 04:22:37 gram Exp $ + * $Id: ftype-tvbuff.c,v 1.9 2003/07/25 03:44:03 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -84,7 +84,8 @@ ftype_register_tvbuff(void) 0, value_new, NULL, - NULL, + NULL, /* val_from_unparsed */ + NULL, /* val_from_string */ NULL, /* val_to_string_repr */ NULL, /* len_string_repr */ diff --git a/epan/ftypes/ftypes-int.h b/epan/ftypes/ftypes-int.h index cda64a1862..d6922ef7c9 100644 --- a/epan/ftypes/ftypes-int.h +++ b/epan/ftypes/ftypes-int.h @@ -1,5 +1,5 @@ /* - * $Id: ftypes-int.h,v 1.8 2003/06/11 21:24:54 gram Exp $ + * $Id: ftypes-int.h,v 1.9 2003/07/25 03:44:03 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -29,6 +29,7 @@ typedef void (*FvalueNewFunc)(fvalue_t*); typedef void (*FvalueFreeFunc)(fvalue_t*); +typedef gboolean (*FvalueFromUnparsed)(fvalue_t*, char*, LogFunc); typedef gboolean (*FvalueFromString)(fvalue_t*, char*, LogFunc); typedef void (*FvalueToStringRepr)(fvalue_t*, ftrepr_t, char*); typedef int (*FvalueStringReprLen)(fvalue_t*, ftrepr_t); @@ -52,6 +53,7 @@ struct _ftype_t { int wire_size; FvalueNewFunc new_value; FvalueFreeFunc free_value; + FvalueFromUnparsed val_from_unparsed; FvalueFromString val_from_string; FvalueToStringRepr val_to_string_repr; FvalueStringReprLen len_string_repr; diff --git a/epan/ftypes/ftypes.c b/epan/ftypes/ftypes.c index fb07b1a738..aa2239397f 100644 --- a/epan/ftypes/ftypes.c +++ b/epan/ftypes/ftypes.c @@ -1,5 +1,5 @@ /* - * $Id: ftypes.c,v 1.9 2003/06/11 21:24:54 gram Exp $ + * $Id: ftypes.c,v 1.10 2003/07/25 03:44:03 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -235,7 +235,24 @@ fvalue_free(fvalue_t *fv) g_mem_chunk_free(gmc_fvalue, fv); } +fvalue_t* +fvalue_from_unparsed(ftenum_t ftype, char *s, LogFunc logfunc) +{ + fvalue_t *fv; + fv = fvalue_new(ftype); + if (fv->ftype->val_from_unparsed) { + if (fv->ftype->val_from_unparsed(fv, s, logfunc)) { + return fv; + } + } + else { + logfunc("\"%s\" cannot be converted to %s.", + s, ftype_pretty_name(ftype)); + } + fvalue_free(fv); + return NULL; +} fvalue_t* fvalue_from_string(ftenum_t ftype, char *s, LogFunc logfunc) diff --git a/epan/ftypes/ftypes.h b/epan/ftypes/ftypes.h index 9ddac05bb6..1e224cbf53 100644 --- a/epan/ftypes/ftypes.h +++ b/epan/ftypes/ftypes.h @@ -1,7 +1,7 @@ /* ftypes.h * Definitions for field types * - * $Id: ftypes.h,v 1.17 2003/06/11 21:24:54 gram Exp $ + * $Id: ftypes.h,v 1.18 2003/07/25 03:44:04 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -73,6 +73,7 @@ enum ftrepr { typedef enum ftrepr ftrepr_t; + /* Initialize the ftypes subsytem. Called once. */ void ftypes_initialize(void); @@ -150,6 +151,9 @@ fvalue_free(fvalue_t *fv); typedef void (*LogFunc)(char*,...); +fvalue_t* +fvalue_from_unparsed(ftenum_t ftype, char *s, LogFunc log); + fvalue_t* fvalue_from_string(ftenum_t ftype, char *s, LogFunc log); diff --git a/gtk/dfilter_expr_dlg.c b/gtk/dfilter_expr_dlg.c index 6b6a11ef82..0179c3e80e 100644 --- a/gtk/dfilter_expr_dlg.c +++ b/gtk/dfilter_expr_dlg.c @@ -7,7 +7,7 @@ * Copyright 2000, Jeffrey C. Foster and * Guy Harris * - * $Id: dfilter_expr_dlg.c,v 1.33 2003/03/10 02:06:33 jmayer Exp $ + * $Id: dfilter_expr_dlg.c,v 1.34 2003/07/25 03:44:04 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -928,7 +928,7 @@ dfilter_expr_dlg_accept_cb(GtkWidget *w, gpointer filter_te_arg) * for the type of the field; if a range string was * specified, must be valid for FT_BYTES. */ - fvalue = fvalue_from_string(ftype, stripped_value_str, + fvalue = fvalue_from_unparsed(ftype, stripped_value_str, dfilter_report_bad_value); if (fvalue == NULL) { /* diff --git a/tools/dfilter-test.py b/tools/dfilter-test.py index 1e837124d5..2e801a4e4d 100755 --- a/tools/dfilter-test.py +++ b/tools/dfilter-test.py @@ -4,7 +4,7 @@ Test-suite to test ethereal's dfilter mechanism. """ # -# $Id: dfilter-test.py,v 1.1 2003/07/09 03:57:34 gram Exp $ +# $Id: dfilter-test.py,v 1.2 2003/07/25 03:44:05 gram Exp $ # # Copyright (C) 2003 by Gilbert Ramirez # @@ -340,11 +340,11 @@ pkt_tftp.data = """ # Add tests here ################################################################################ -class Ftype_Bytes(Test): +class Bytes(Test): """Tests routines in ftype-bytes.c""" def __init__(self): - print "Note: Ftype_Bytes does not yet test FT_INT64." + print "Note: Bytes test does not yet test FT_INT64." def ck_eq_1(self): return self.DFilterCount(pkt_ipx_rip, @@ -485,7 +485,7 @@ class Ftype_Bytes(Test): ] -class Ftype_Double(Test): +class Double(Test): """Tests routines in ftype-double.c""" def ck_eq_1(self): @@ -564,7 +564,7 @@ class Ftype_Double(Test): ck_le_3, ] -class Ftype_Integer(Test): +class Integer(Test): """Tests routines in ftype-integer.c""" def ck_eq_1(self): @@ -741,7 +741,7 @@ class Ftype_Integer(Test): ck_ipx_2, ] -class Ftype_IPv4(Test): +class IPv4(Test): """Tests routines in ftype-ipv4.c""" def ck_eq_1(self): @@ -867,7 +867,7 @@ class Ftype_IPv4(Test): ck_cidr_ne_4, ] -class Ftype_String(Test): +class String(Test): """Tests routines in ftype-string.c""" def ck_eq_1(self): @@ -998,7 +998,7 @@ class Ftype_String(Test): ] -class Ftype_Time(Test): +class Time(Test): """Tests routines in ftype-time.c""" def ck_eq_1(self): @@ -1099,7 +1099,7 @@ class Ftype_Time(Test): ck_relative_time_3, ] -class Ftype_TVB(Test): +class TVB(Test): """Tests routines in ftype-tvb.c""" def ck_slice_1(self): @@ -1134,15 +1134,73 @@ class Ftype_TVB(Test): # ck_slice_5, ] + +class Scanner(Test): + """Tests routines in scanner.l""" + + def __init__(self): + print "Note: Scanner test does not yet test embedded double-quote." + + def ck_dquote_1(self): + return self.DFilterCount(pkt_http, + 'http.request.method == "HEAD"', 1) + + def ck_dquote_2(self): + return self.DFilterCount(pkt_http, + 'http.request.method == "\\x48EAD"', 1) + + def ck_dquote_3(self): + return self.DFilterCount(pkt_http, + 'http.request.method == "\\x58EAD"', 0) + + def ck_dquote_4(self): + return self.DFilterCount(pkt_http, + 'http.request.method == "\\110EAD"', 1) + + def ck_dquote_5(self): + return self.DFilterCount(pkt_http, + 'http.request.method == "\\111EAD"', 0) + + def ck_dquote_6(self): + return self.DFilterCount(pkt_http, + 'http.request.method == "\\HEAD"', 1) + + tests = [ + ck_dquote_1, + ck_dquote_2, + ck_dquote_3, + ck_dquote_4, + ck_dquote_5, + ] + ################################################################################ +# These are the test objects to run. +# Keep these in alphabetical order so the help message +# shows them in order. +all_tests = [ + Bytes(), + Double(), + Integer(), + IPv4(), + Scanner(), + String(), + Time(), + TVB(), + ] + def usage(): - print "usage: %s [OPTS]" % (sys.argv[0],) + print "usage: %s [OPTS] [TEST ...]" % (sys.argv[0],) print "\t-p PATH : path to find both tethereal and text2pcap (DEFAULT: . )" print "\t-t FILE : location of tethereal binary" print "\t-x FILE : location of text2pcap binary" print "\t-k : keep temporary files" print "\t-v : verbose" + print + print "By not mentioning a test name, all tests are run." + print "Available tests are:" + for test in all_tests: + print "\t", test.__class__.__name__ sys.exit(1) def main(): @@ -1157,7 +1215,7 @@ def main(): longopts = [] try: - opts, args = getopt.getopt(sys.argv[1:], optstring, longopts) + opts, specific_tests = getopt.getopt(sys.argv[1:], optstring, longopts) except getopt.GetoptError: usage() @@ -1185,22 +1243,31 @@ def main(): sys.exit("text2pcap program '%s' does not exist." % (TEXT2PCAP,)) - # These are the test objects to run. - tests = [ - Ftype_Bytes(), - Ftype_Double(), - Ftype_Integer(), - Ftype_IPv4(), - Ftype_String(), - Ftype_Time(), - Ftype_TVB(), - ] + # Determine which tests to run. + tests_to_run = [] + if specific_tests: + # Go through the tests looking for the ones whose names + # match the command-line arguments. + all_ok = 1 + for test_name in specific_tests: + for test in all_tests: + if test_name == test.__class__.__name__: + tests_to_run.append(test) + break + else: + print >> sys.stderr, "%s is unrecognized as a test." % \ + (test_name,) + all_ok = 0 + + if not all_ok: + sys.exit(1) + else: + tests_to_run = all_tests # Run the tests and keep score. tot_run = 0 tot_succeeded = 0 - - for test in tests: + for test in tests_to_run: print test.__class__.__name__ (run, succeeded) = test.Run() tot_run += run -- cgit v1.2.3