From 6636db005a5599096f0830564017a007f886d19e Mon Sep 17 00:00:00 2001 From: Gilbert Ramirez Date: Sat, 22 Jul 2000 15:58:54 +0000 Subject: Simplify the way the display filter routines get field values from the proto tree. Now, proto_get_finfo_ptr_array() can easily be used by any routine, not just display filter code, to get values from the proto tree. This might be useful if one were to allow columns in the packet list to show the value of an arbitrary field. Fixed a memleak when filtering on a byte arrays. Fixed erroneous asserts in dfilter-grammar.y, where I used '=' instead of '=='. They had to do with byte-arrays, too. svn path=/trunk/; revision=2152 --- dfilter.c | 196 ++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 95 insertions(+), 101 deletions(-) (limited to 'dfilter.c') diff --git a/dfilter.c b/dfilter.c index c07827cc86..a61846891f 100644 --- a/dfilter.c +++ b/dfilter.c @@ -1,7 +1,7 @@ /* dfilter.c * Routines for display filters * - * $Id: dfilter.c,v 1.34 2000/04/14 05:39:36 gram Exp $ + * $Id: dfilter.c,v 1.35 2000/07/22 15:58:53 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -403,6 +403,21 @@ check_logical(gint operand, GNode *a, GNode *b, proto_tree *ptree, const guint8 return FALSE; } + +static void +free_array_of_byte_arrays(GArray *array) +{ + int i, len; + GByteArray *ba_ptr; + + len = array->len; + + for (i = 0; i < len ; i++) { + ba_ptr = g_array_index(array, GByteArray*, i); + g_byte_array_free(ba_ptr, TRUE); + } +} + /* this is inefficient. I get arrays for both a and b that represent all the values present. That is, * if a is bootp.option, e.g., i'll get an array showing all the bootp.option values in the protocol * tree. Then I'll get an array for b, which more than likely is a single int, and then I'll compare @@ -432,12 +447,22 @@ check_relation(gint operand, GNode *a, GNode *b, proto_tree *ptree, const guint8 retval = node_a->check_relation_func(operand, vals_a, vals_b); + /* Free GByteArrays alloated by fill_array_bytes_variable() */ + if (node_a->fill_array_variable_func == fill_array_bytes_variable) { + free_array_of_byte_arrays(vals_a); + } + + if (node_b->fill_array_variable_func == fill_array_bytes_variable) { + free_array_of_byte_arrays(vals_b); + } + g_array_free(vals_a, FALSE); g_array_free(vals_b, FALSE); return retval; } + static gboolean check_existence_in_ptree(dfilter_node *dnode, proto_tree *ptree) { @@ -450,141 +475,110 @@ check_existence_in_ptree(dfilter_node *dnode, proto_tree *ptree) static GArray* get_values_from_ptree(dfilter_node *dnode, proto_tree *ptree, const guint8 *pd) { - GArray *array; - int parent_protocol; - proto_tree_search_info sinfo; + GArray *result_array; + GPtrArray *finfo_array; + int i, len; + field_info *finfo; + /* Prepare the array for results */ g_assert(dnode->elem_size > 0); - array = g_array_new(FALSE, FALSE, dnode->elem_size); + result_array = g_array_new(FALSE, FALSE, dnode->elem_size); - sinfo.target = dnode->value.variable; - sinfo.result.array = array; - sinfo.packet_data = pd; - sinfo.traverse_func = dnode->fill_array_func; - - /* Find the proto_tree subtree where we should start searching.*/ - if (proto_registrar_is_protocol(sinfo.target)) { - proto_find_protocol_multi(ptree, sinfo.target, - (GNodeTraverseFunc)proto_get_field_values, &sinfo); - } - else { - parent_protocol = proto_registrar_get_parent(sinfo.target); - if (parent_protocol >= 0) { - proto_find_protocol_multi(ptree, parent_protocol, - (GNodeTraverseFunc)proto_get_field_values, &sinfo); - } + /* Cull the finfos from the proto_tree */ + finfo_array = proto_get_finfo_ptr_array(ptree, dnode->value.variable); + if (!finfo_array) { + return result_array; } - return array; -} + len = g_ptr_array_len(finfo_array); -static GArray* -get_values_from_dfilter(dfilter_node *dnode, GNode *gnode) -{ - GArray *array; + for (i = 0; i < len; i++) { + finfo = g_ptr_array_index(finfo_array, i); + dnode->fill_array_variable_func(finfo, result_array, pd); + } - g_assert(dnode->elem_size > 0); - array = g_array_new(FALSE, FALSE, dnode->elem_size); + g_ptr_array_free(finfo_array, FALSE); - g_node_traverse(gnode, G_IN_ORDER, G_TRAVERSE_ALL, -1, dnode->fill_array_func, array); - return array; + return result_array; } -gboolean fill_array_numeric_variable(GNode *gnode, gpointer data) -{ - proto_tree_search_info *sinfo = (proto_tree_search_info*)data; - field_info *fi = (field_info*) (gnode->data); - if (fi->hfinfo->id == sinfo->target) { - g_array_append_val(sinfo->result.array, fi->value.numeric); - } - - return FALSE; /* FALSE = do not end traversal of GNode tree */ +void +fill_array_numeric_variable(field_info *finfo, GArray *array, const guint8 *pd) +{ + g_array_append_val(array, finfo->value.numeric); } -gboolean fill_array_floating_variable(GNode *gnode, gpointer data) +void +fill_array_floating_variable(field_info *finfo, GArray *array, const guint8 *pd) { - proto_tree_search_info *sinfo = (proto_tree_search_info*)data; - field_info *fi = (field_info*) (gnode->data); - - if (fi->hfinfo->id == sinfo->target) { - g_array_append_val(sinfo->result.array, fi->value.floating); - } - - return FALSE; /* FALSE = do not end traversal of GNode tree */ + g_array_append_val(array, finfo->value.floating); } -gboolean fill_array_ether_variable(GNode *gnode, gpointer data) +void +fill_array_ether_variable(field_info *finfo, GArray *array, const guint8 *pd) { - proto_tree_search_info *sinfo = (proto_tree_search_info*)data; - field_info *fi = (field_info*) (gnode->data); - - if (fi->hfinfo->id == sinfo->target) { - g_array_append_val(sinfo->result.array, fi->value.ether); - } - - return FALSE; /* FALSE = do not end traversal of GNode tree */ + /* hmmm, yes, I *can* copy a pointer instead of memcpy() */ + g_array_append_val(array, finfo->value.ether); } -gboolean fill_array_ipv4_variable(GNode *gnode, gpointer data) +void +fill_array_ipv4_variable(field_info *finfo, GArray *array, const guint8 *pd) { - proto_tree_search_info *sinfo = (proto_tree_search_info*)data; - field_info *fi = (field_info*) (gnode->data); - - if (fi->hfinfo->id == sinfo->target) { - g_array_append_val(sinfo->result.array, fi->value.ipv4); - } - - return FALSE; /* FALSE = do not end traversal of GNode tree */ + /* hmmm, yes, I *can* copy a pointer instead of memcpy() */ + g_array_append_val(array, finfo->value.ipv4); } -gboolean fill_array_ipv6_variable(GNode *gnode, gpointer data) -{ - proto_tree_search_info *sinfo = (proto_tree_search_info*)data; - field_info *fi = (field_info*) (gnode->data); - - if (fi->hfinfo->id == sinfo->target) { - g_array_append_val(sinfo->result.array, fi->value.ipv6); - } - return FALSE; /* FALSE = do not end traversal of GNode tree */ +void +fill_array_ipv6_variable(field_info *finfo, GArray *array, const guint8 *pd) +{ + /* hmmm, yes, I *can* copy a pointer instead of memcpy() */ + g_array_append_val(array, finfo->value.ipv6); } -gboolean fill_array_bytes_variable(GNode *gnode, gpointer data) +void +fill_array_bytes_variable(field_info *finfo, GArray *array, const guint8 *pd) { - proto_tree_search_info *sinfo = (proto_tree_search_info*)data; - field_info *fi = (field_info*) (gnode->data); GByteArray *barray; guint read_start, pkt_end; - if (fi->hfinfo->id == sinfo->target) { + if (bytes_offset < 0) { + /* Handle negative byte offsets */ + bytes_offset = finfo->length + bytes_offset; if (bytes_offset < 0) { - /* Handle negative byte offsets */ - bytes_offset = fi->length + bytes_offset; - if (bytes_offset < 0) { - goto FAIL; - } - } - - /* Check to make sure offset exists for this field */ - if (bytes_offset >= fi->length) { - goto FAIL; + return; } + } - pkt_end = fi->start + fi->length; - read_start = fi->start + bytes_offset; + /* Check to make sure offset exists for this field */ + if (bytes_offset >= finfo->length) { + return; + } - /* Check to make sure entire length requested is inside field */ - if (pkt_end < read_start + bytes_length) { - goto FAIL; - } + pkt_end = finfo->start + finfo->length; + read_start = finfo->start + bytes_offset; - barray = g_byte_array_new(); - g_byte_array_append(barray, sinfo->packet_data + read_start, bytes_length); - g_array_append_val(sinfo->result.array, barray); + /* Check to make sure entire length requested is inside field */ + if (pkt_end < read_start + bytes_length) { + return; } - FAIL: - return FALSE; /* FALSE = do not end traversal of GNode tree */ + barray = g_byte_array_new(); + g_byte_array_append(barray, pd + read_start, bytes_length); + g_array_append_val(array, barray); +} + +static GArray* +get_values_from_dfilter(dfilter_node *dnode, GNode *gnode) +{ + GArray *array; + + g_assert(dnode->elem_size > 0); + array = g_array_new(FALSE, FALSE, dnode->elem_size); + + g_node_traverse(gnode, G_IN_ORDER, G_TRAVERSE_ALL, -1, + dnode->fill_array_value_func, array); + return array; } gboolean fill_array_numeric_value(GNode *gnode, gpointer data) -- cgit v1.2.3