diff options
author | Gilbert Ramirez <gram@alumni.rice.edu> | 2000-08-01 18:10:06 +0000 |
---|---|---|
committer | Gilbert Ramirez <gram@alumni.rice.edu> | 2000-08-01 18:10:06 +0000 |
commit | 5f3191082f81e0c596259143eeb805ab78086351 (patch) | |
tree | 2c043dd3320e0997cabbd9902b688a45ce1a8f06 | |
parent | 2bcc0d3c1366e47f1f26f0f65d862aa578281590 (diff) |
Allow filtering on strings.
svn path=/trunk/; revision=2193
-rw-r--r-- | dfilter-grammar.y | 76 | ||||
-rw-r--r-- | dfilter-int.h | 5 | ||||
-rw-r--r-- | dfilter-scanner.l | 16 | ||||
-rw-r--r-- | dfilter.c | 72 | ||||
-rw-r--r-- | dfilter.h | 6 |
5 files changed, 170 insertions, 5 deletions
diff --git a/dfilter-grammar.y b/dfilter-grammar.y index 9299d39e4a..6e4a1638eb 100644 --- a/dfilter-grammar.y +++ b/dfilter-grammar.y @@ -3,7 +3,7 @@ /* dfilter-grammar.y * Parser for display filters * - * $Id: dfilter-grammar.y,v 1.39 2000/07/22 15:58:52 gram Exp $ + * $Id: dfilter-grammar.y,v 1.40 2000/08/01 18:10:04 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -93,6 +93,8 @@ static GNode* dfilter_mknode_ipv6_variable(gint id); static GNode* dfilter_mknode_existence(gint id); static GNode* dfilter_mknode_bytes_value(GByteArray *barray); static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length); +static GNode* dfilter_mknode_string_value(char *s); +static GNode* dfilter_mknode_string_variable(gint id); static guint32 string_to_guint32(char *s, gboolean *success); static double string_to_double(char *s, gboolean *success); @@ -133,6 +135,7 @@ dfilter *global_df = NULL; %type <node> ipxnet_value ipxnet_variable %type <node> ipv4_value ipv4_variable %type <node> ipv6_value ipv6_variable +%type <node> string_value string_variable %type <node> variable_name %type <node> bytes_value bytes_variable @@ -161,6 +164,7 @@ dfilter *global_df = NULL; %token <variable> T_FT_DOUBLE %token <string> T_VAL_UNQUOTED_STRING +%token <string> T_VAL_QUOTED_STRING %token <string> T_VAL_BYTE_STRING %token <byte_range> T_VAL_BYTE_RANGE @@ -227,6 +231,15 @@ relation: numeric_variable numeric_relation numeric_value $$ = dfilter_mknode_join($1, relation, $2, $3); } + | string_variable equality_relation string_value + { + $$ = dfilter_mknode_join($1, relation, $2, $3); + } + | string_variable equality_relation string_variable + { + $$ = dfilter_mknode_join($1, relation, $2, $3); + } + | ipv4_variable numeric_relation ipv4_value { @@ -326,6 +339,24 @@ ether_value: T_VAL_BYTE_STRING } ; +string_value: T_VAL_UNQUOTED_STRING + { + $$ = dfilter_mknode_string_value($1); + g_free($1); + if ($$ == NULL) { + YYERROR; + } + } + | T_VAL_QUOTED_STRING + { + $$ = dfilter_mknode_string_value($1); + g_free($1); + if ($$ == NULL) { + YYERROR; + } + } + ; + ipxnet_value: T_VAL_UNQUOTED_STRING { gboolean success; @@ -515,6 +546,9 @@ ipv4_variable: T_FT_IPv4 { $$ = dfilter_mknode_ipv4_variable($1.id); } ipv6_variable: T_FT_IPv6 { $$ = dfilter_mknode_ipv6_variable($1.id); } ; +string_variable: T_FT_STRING { $$ = dfilter_mknode_string_variable($1.id); } + ; + variable_name: any_variable_type { GNode *variable; @@ -736,6 +770,24 @@ dfilter_mknode_ipv6_variable(gint id) } static GNode* +dfilter_mknode_string_variable(gint id) +{ + dfilter_node *node; + GNode *gnode; + + node = g_mem_chunk_alloc(global_df->node_memchunk); + node->ntype = variable; + node->elem_size = sizeof(char*); + node->fill_array_variable_func = fill_array_string_variable; + node->fill_array_value_func = NULL; + node->check_relation_func = check_relation_string; + node->value.variable = id; + gnode = g_node_new(node); + + return gnode; +} + +static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length) { dfilter_node *node; @@ -948,6 +1000,28 @@ dfilter_mknode_ipv6_value(char *host) return gnode; } + +static GNode* +dfilter_mknode_string_value(char *s) +{ + dfilter_node *node; + GNode *gnode; + + node = g_mem_chunk_alloc(global_df->node_memchunk); + node->ntype = string; + node->elem_size = sizeof(char*); + node->fill_array_variable_func = NULL; + node->fill_array_value_func = fill_array_string_value; + node->check_relation_func = check_relation_string; + node->value.string = g_strdup(s); + global_df->list_of_strings = g_slist_append(global_df->list_of_strings, + node->value.string); + gnode = g_node_new(node); + + return gnode; +} + + static GNode* dfilter_mknode_bytes_value(GByteArray *barray) { diff --git a/dfilter-int.h b/dfilter-int.h index a9ab39b2b2..cf7a1c71e8 100644 --- a/dfilter-int.h +++ b/dfilter-int.h @@ -2,7 +2,7 @@ * Definitions for routines common to multiple modules in the display * filter code, but not used outside that code. * - * $Id: dfilter-int.h,v 1.12 2000/07/22 15:58:53 gram Exp $ + * $Id: dfilter-int.h,v 1.13 2000/08/01 18:10:05 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -62,6 +62,7 @@ gboolean check_relation_ether(gint operand, GArray *a, GArray *b); gboolean check_relation_ipv4(gint operand, GArray *a, GArray *b); gboolean check_relation_ipv6(gint operand, GArray *a, GArray *b); gboolean check_relation_bytes(gint operand, GArray *a, GArray *b); +gboolean check_relation_string(gint operand, GArray *a, GArray *b); void fill_array_numeric_variable(field_info*, GArray*, const guint8*); void fill_array_floating_variable(field_info*, GArray*, const guint8*); @@ -69,6 +70,7 @@ void fill_array_ether_variable(field_info*, GArray*, const guint8*); void fill_array_ipv4_variable(field_info*, GArray*, const guint8*); void fill_array_ipv6_variable(field_info*, GArray*, const guint8*); void fill_array_bytes_variable(field_info*, GArray*, const guint8*); +void fill_array_string_variable(field_info*, GArray*, const guint8*); gboolean fill_array_numeric_value(GNode *gnode, gpointer data); gboolean fill_array_floating_value(GNode *gnode, gpointer data); @@ -76,6 +78,7 @@ gboolean fill_array_ether_value(GNode *gnode, gpointer data); gboolean fill_array_ipv4_value(GNode *gnode, gpointer data); gboolean fill_array_ipv6_value(GNode *gnode, gpointer data); gboolean fill_array_bytes_value(GNode *gnode, gpointer data); +gboolean fill_array_string_value(GNode *gnode, gpointer data); #ifdef WIN32 #define boolean truth_value diff --git a/dfilter-scanner.l b/dfilter-scanner.l index fceb0eae6a..0aa5a46d36 100644 --- a/dfilter-scanner.l +++ b/dfilter-scanner.l @@ -3,7 +3,7 @@ /* dfilter-scanner.l * Scanner for display filters * - * $Id: dfilter-scanner.l,v 1.30 2000/03/23 05:43:57 gram Exp $ + * $Id: dfilter-scanner.l,v 1.31 2000/08/01 18:10:05 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -276,6 +276,20 @@ le|\<\= { dfilter_lval.operand = TOK_LE; return TOK_LE; } return T_VAL_UNQUOTED_STRING; } +\"[^"]+\" { + int length; + + /* Don't copy the first quote. */ + dfilter_lval.string = g_strdup(&yytext[1]); + + /* Chop of the final quote mark. */ + length = strlen(dfilter_lval.string); + g_assert(length > 0); + dfilter_lval.string[length - 1] = 0; + + return T_VAL_QUOTED_STRING; +} + . return yytext[0]; %% @@ -1,7 +1,7 @@ /* dfilter.c * Routines for display filters * - * $Id: dfilter.c,v 1.35 2000/07/22 15:58:53 gram Exp $ + * $Id: dfilter.c,v 1.36 2000/08/01 18:10:05 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -225,10 +225,19 @@ dfilter_new(void) df->node_memchunk = g_mem_chunk_new("df->node_memchunk", sizeof(dfilter_node), 20 * sizeof(dfilter_node), G_ALLOC_ONLY); df->list_of_byte_arrays = NULL; + df->list_of_strings = NULL; return df; } +static void +free_string(gpointer data, gpointer user_data) +{ + char *string = data; + if (string) + g_free(string); +} + /* Frees all memory used by dfilter, and frees dfilter itself */ void dfilter_destroy(dfilter *df) @@ -249,8 +258,15 @@ dfilter_destroy(dfilter *df) g_slist_free(df->list_of_byte_arrays); } + /* clear the allocated strings */ + if (df->list_of_strings) { + g_slist_foreach(df->list_of_strings, free_string, NULL); + g_slist_free(df->list_of_strings); + } + df->dftree = NULL; df->list_of_byte_arrays = NULL; + df->list_of_strings = NULL; /* Git rid of memchunk */ if (df->node_memchunk) @@ -537,6 +553,12 @@ fill_array_ipv6_variable(field_info *finfo, GArray *array, const guint8 *pd) } void +fill_array_string_variable(field_info *finfo, GArray *array, const guint8 *pd) +{ + g_array_append_val(array, finfo->value.string); +} + +void fill_array_bytes_variable(field_info *finfo, GArray *array, const guint8 *pd) { GByteArray *barray; @@ -640,6 +662,16 @@ gboolean fill_array_bytes_value(GNode *gnode, gpointer data) return FALSE; /* FALSE = do not end traversal of GNode tree */ } +gboolean fill_array_string_value(GNode *gnode, gpointer data) +{ + GArray *array = (GArray*)data; + dfilter_node *dnode = (dfilter_node*) (gnode->data); + + g_array_append_val(array, dnode->value.string); + + return FALSE; /* FALSE = do not end traversal of GNode tree */ +} + gboolean check_relation_numeric(gint operand, GArray *a, GArray *b) { int i, j, len_a, len_b; @@ -1009,3 +1041,41 @@ gboolean check_relation_bytes(gint operand, GArray *a, GArray *b) g_assert_not_reached(); return FALSE; } + +gboolean check_relation_string(gint operand, GArray *a, GArray *b) +{ + int i, j, len_a, len_b; + char *ptr_a, *ptr_b; + + len_a = a->len; + len_b = b->len; + + + switch(operand) { + case TOK_EQ: + for(i = 0; i < len_a; i++) { + ptr_a = g_array_index(a, char*, i); + for (j = 0; j < len_b; j++) { + ptr_b = g_array_index(b, char*, j); + if (strcmp(ptr_a, ptr_b) == 0) + return TRUE; + } + } + return FALSE; + + case TOK_NE: + for(i = 0; i < len_a; i++) { + ptr_a = g_array_index(a, char*, i); + for (j = 0; j < len_b; j++) { + ptr_b = g_array_index(b, char*, j); + if (strcmp(ptr_a, ptr_b) != 0) + return TRUE; + } + } + return FALSE; + } + + g_assert_not_reached(); + return FALSE; +} + @@ -1,7 +1,7 @@ /* dfilter.h * Definitions for display filters * - * $Id: dfilter.h,v 1.16 2000/04/14 05:39:38 gram Exp $ + * $Id: dfilter.h,v 1.17 2000/08/01 18:10:06 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -45,6 +45,10 @@ typedef struct { /* list of byte arrays we allocate during parse. We can traverse this list * faster than the tree when we go back and free the byte arrays */ GSList *list_of_byte_arrays; + + /* List of strings allocated during parse. */ + GSList *list_of_strings; + } dfilter; /* Initialization of the symbol table. Called once during program startup */ |