Allow filtering on strings.
authorgram <gram@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 1 Aug 2000 18:10:06 +0000 (18:10 +0000)
committergram <gram@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 1 Aug 2000 18:10:06 +0000 (18:10 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@2193 f5534014-38df-0310-8fa8-9805f1628bb7

dfilter-grammar.y
dfilter-int.h
dfilter-scanner.l
dfilter.c
dfilter.h

index 9299d39e4a83148f97cdc222f4536d55ee7cdb02..6e4a1638eb55bc17698b9406ea8b409eab086f18 100644 (file)
@@ -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;
@@ -735,6 +769,24 @@ dfilter_mknode_ipv6_variable(gint id)
        return gnode;
 }
 
+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)
 {
@@ -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)
 {
index a9ab39b2b22827fe0a611f5595699185d796c71f..cf7a1c71e81d7a9ff4c91674e129459f23c04b77 100644 (file)
@@ -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
index fceb0eae6a682a6ebb83e70d423d95289b07a072..0aa5a46d36637c5e11bdf9a90b5f1c18b32fe657 100644 (file)
@@ -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];
 %%
 
index a61846891f11e3aa8388660aec044da8d531ccde..1fa0b3932bcad3ad8b8fa82429213b4d36239058 100644 (file)
--- a/dfilter.c
+++ b/dfilter.c
@@ -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)
@@ -536,6 +552,12 @@ fill_array_ipv6_variable(field_info *finfo, GArray *array, const guint8 *pd)
        g_array_append_val(array, finfo->value.ipv6);
 }
 
+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)
 {
@@ -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;
+}
+
index 6209453691b6e4e6648fd393eb295ec51337f1d1..54c11478ef8e2c547de7441fa6931fbefd78a7b2 100644 (file)
--- a/dfilter.h
+++ b/dfilter.h
@@ -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 */