From ca318813a4d4c28af90b14abdb60f7ecbcb46ea9 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Sat, 3 May 2003 00:48:37 +0000 Subject: [PATCH] Rename "proto_alloc_dfilter_string()" to "proto_construct_dfilter_string()", to more accurately reflect what it does. Give it, and "proto_can_match_selected()", an "epan_dissect_t *" argument, which replaces the raw data pointer argument to "proto_construct_dfilter_string()". For fields that don't have a type we can directly filter on, we don't support filtering on the field as raw data if: the "epan_dissect_t *" argument is null; the data source tvbuff for the field isn't the tvbuff for the "epan_dissect_t" in question (i.e., it's in the result of a reassembly, and "frame[N:M]" can't get at it). Trim the length the raw data in the case of such a field to the length of the tvbuff for the "epan_dissect_t" in question, so we don't go past it. Fetch the raw data bytes to match from that tvbuff. Have "proto_construct_dfilter_string()" return a null pointer if it can't construct the filter string, and have "protocolinfo_packet()" in the tap-protocolinfo tap ignore a field if "proto_construct_dfilter_string()" can't construct a filter string for it - and have it pass NULL as the "epan_dissect_t *", for now. If somebody decides it makes sense to dump out a "frame[N:M] =" value for non-registered fields, it can be changed to pass "edt". svn path=/trunk/; revision=7635 --- epan/proto.c | 127 +++++++++++++++++++++++++++++++++++++-------- epan/proto.h | 8 +-- gtk/main.c | 26 +++++----- gtk/menu.c | 10 ++-- tap-protocolinfo.c | 10 ++-- 5 files changed, 133 insertions(+), 48 deletions(-) diff --git a/epan/proto.c b/epan/proto.c index 5a455ef889..31f90dbe54 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -1,7 +1,7 @@ /* proto.c * Routines for protocol tree * - * $Id: proto.c,v 1.83 2003/04/29 21:27:14 guy Exp $ + * $Id: proto.c,v 1.84 2003/05/03 00:48:35 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -41,6 +41,7 @@ #include "ipv6-utils.h" #include "proto.h" #include "int-64bit.h" +#include "epan_dissect.h" #define cVALS(x) (const value_string*)(x) @@ -3319,9 +3320,10 @@ hfinfo_numeric_format(header_field_info *hfinfo) * otherwise. */ gboolean -proto_can_match_selected(field_info *finfo) +proto_can_match_selected(field_info *finfo, epan_dissect_t *edt) { header_field_info *hfinfo; + gint length; hfinfo = finfo->hfinfo; g_assert(hfinfo); @@ -3329,28 +3331,28 @@ proto_can_match_selected(field_info *finfo) switch(hfinfo->type) { case FT_BOOLEAN: - case FT_FRAMENUM: case FT_UINT8: case FT_UINT16: case FT_UINT24: case FT_UINT32: - case FT_UINT64: case FT_INT8: case FT_INT16: case FT_INT24: case FT_INT32: + case FT_FRAMENUM: + case FT_UINT64: case FT_INT64: case FT_IPv4: case FT_IPXNET: case FT_IPv6: case FT_FLOAT: case FT_DOUBLE: - case FT_ETHER: case FT_ABSOLUTE_TIME: case FT_RELATIVE_TIME: case FT_STRING: case FT_STRINGZ: case FT_UINT_STRING: + case FT_ETHER: case FT_BYTES: case FT_UINT_BYTES: /* @@ -3361,22 +3363,58 @@ proto_can_match_selected(field_info *finfo) default: /* * This doesn't have a value, so we'd match - * on the raw bytes at this address; - * however, if the length is 0, there's nothing - * to match, so we can't match. + * on the raw bytes at this address. + * + * Should we be allowed to access to the raw bytes? + * If "edt" is NULL, the answer is "no". */ - return (finfo->length != 0); + if (edt == NULL) + return FALSE; + + /* + * Is this field part of the raw frame tvbuff? + * If not, we can't use "frame[N:M]" to match + * it. + * + * XXX - should this be frame-relative, or + * protocol-relative? + * + * XXX - does this fallback for non-registered + * fields even make sense? + */ + if (finfo->ds_tvb != edt->tvb) + return FALSE; + + /* + * If the length is 0, there's nothing to match, so + * we can't match. (Also check for negative values, + * just in case, as we'll cast it to an unsigned + * value later.) + */ + length = finfo->length; + if (length <= 0) + return FALSE; + + /* + * Don't go past the end of that tvbuff. + */ + if ((guint)length > tvb_length(finfo->ds_tvb)) + length = tvb_length(finfo->ds_tvb); + if (length <= 0) + return FALSE; + return TRUE; } } char* -proto_alloc_dfilter_string(field_info *finfo, guint8 *pd) +proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt) { header_field_info *hfinfo; int abbrev_len; char *buf, *stringified, *format, *ptr, *value_str; int dfilter_len, i; - guint8 *c; + gint start, length; + guint8 c; hfinfo = finfo->hfinfo; g_assert(hfinfo); @@ -3524,7 +3562,6 @@ proto_alloc_dfilter_string(field_info *finfo, guint8 *pd) fvalue_get_floating(finfo->value)); break; - case FT_ABSOLUTE_TIME: /* * 4 bytes for " == ". @@ -3555,6 +3592,8 @@ proto_alloc_dfilter_string(field_info *finfo, guint8 *pd) break; case FT_STRING: + case FT_STRINGZ: + case FT_UINT_STRING: /* * 4 bytes for " == ". * N bytes for the string. @@ -3574,32 +3613,74 @@ proto_alloc_dfilter_string(field_info *finfo, guint8 *pd) /* * 4 bytes for " == ". * 1 byte for the trailing '\0'. - * */ dfilter_len = fvalue_string_repr_len(finfo->value); dfilter_len += abbrev_len + 4 + 1; buf = g_malloc0(dfilter_len); snprintf(buf, dfilter_len, "%s == ", hfinfo->abbrev); - stringified = fvalue_to_string_repr(finfo->value); - strcat(buf, stringified); - g_free(stringified); + stringified = fvalue_to_string_repr(finfo->value); + strcat(buf, stringified); + g_free(stringified); break; default: - c = pd + finfo->start; - buf = g_malloc0(32 + finfo->length * 3); + /* + * This doesn't have a value, so we'd match + * on the raw bytes at this address. + * + * Should we be allowed to access to the raw bytes? + * If "edt" is NULL, the answer is "no". + */ + if (edt == NULL) + return FALSE; + + /* + * Is this field part of the raw frame tvbuff? + * If not, we can't use "frame[N:M]" to match + * it. + * + * XXX - should this be frame-relative, or + * protocol-relative? + * + * XXX - does this fallback for non-registered + * fields even make sense? + */ + if (finfo->ds_tvb != edt->tvb) + return NULL; /* you lose */ + + /* + * If the length is 0, there's nothing to match, so + * we can't match. (Also check for negative values, + * just in case, as we'll cast it to an unsigned + * value later.) + */ + length = finfo->length; + if (length <= 0) + return NULL; + + /* + * Don't go past the end of that tvbuff. + */ + if ((guint)length > tvb_length(finfo->ds_tvb)) + length = tvb_length(finfo->ds_tvb); + if (length <= 0) + return NULL; + + start = finfo->start; + buf = g_malloc0(32 + length * 3); ptr = buf; - sprintf(ptr, "frame[%d:%d] == ", finfo->start, - finfo->length); + sprintf(ptr, "frame[%d:%d] == ", finfo->start, length); ptr = buf+strlen(buf); - for (i=0;ilength; i++) { + for (i=0;ids_tvb, start); + start++; if (i == 0 ) { - sprintf(ptr, "%02x", *c++); + sprintf(ptr, "%02x", c); } else { - sprintf(ptr, ":%02x", *c++); + sprintf(ptr, ":%02x", c); } ptr = buf+strlen(buf); } diff --git a/epan/proto.h b/epan/proto.h index 0749cee13a..24d5b3aa35 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -1,7 +1,7 @@ /* proto.h * Definitions for protocol display * - * $Id: proto.h,v 1.39 2003/04/29 21:27:14 guy Exp $ + * $Id: proto.h,v 1.40 2003/05/03 00:48:35 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -600,15 +600,17 @@ extern int num_tree_types; extern int hfinfo_bitwidth(header_field_info *hfinfo); +#include "epan.h" + /* * Returns TRUE if we can do a "match selected" on the field, FALSE * otherwise. */ extern gboolean -proto_can_match_selected(field_info *finfo); +proto_can_match_selected(field_info *finfo, epan_dissect_t *edt); extern char* -proto_alloc_dfilter_string(field_info *finfo, guint8 *pd); +proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt); extern field_info* proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb); diff --git a/gtk/main.c b/gtk/main.c index b879f6f89f..9d49a2b26d 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1,6 +1,6 @@ /* main.c * - * $Id: main.c,v 1.291 2003/04/23 20:51:57 deniel Exp $ + * $Id: main.c,v 1.292 2003/05/03 00:48:37 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -303,7 +303,7 @@ match_selected_cb_replace_ptree(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -312,7 +312,7 @@ match_selected_cb_and_ptree(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -321,7 +321,7 @@ match_selected_cb_or_ptree(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -330,7 +330,7 @@ match_selected_cb_not_ptree(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -339,7 +339,7 @@ match_selected_cb_and_ptree_not(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -348,7 +348,7 @@ match_selected_cb_or_ptree_not(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_OR_NOT, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -357,7 +357,7 @@ prepare_selected_cb_replace_ptree(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_REPLACE, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -366,7 +366,7 @@ prepare_selected_cb_and_ptree(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_AND, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -375,7 +375,7 @@ prepare_selected_cb_or_ptree(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_OR, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -384,7 +384,7 @@ prepare_selected_cb_not_ptree(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_NOT, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -393,7 +393,7 @@ prepare_selected_cb_and_ptree_not(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_AND_NOT, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } void @@ -402,7 +402,7 @@ prepare_selected_cb_or_ptree_not(GtkWidget *w, gpointer data) if (finfo_selected) match_selected_cb_do((data ? data : w), MATCH_SELECTED_OR_NOT, - proto_alloc_dfilter_string(finfo_selected, cfile.pd)); + proto_construct_dfilter_string(finfo_selected, cfile.edt)); } static gchar * diff --git a/gtk/menu.c b/gtk/menu.c index 3655b9d377..3c613e8c68 100644 --- a/gtk/menu.c +++ b/gtk/menu.c @@ -1,7 +1,7 @@ /* menu.c * Menu routines * - * $Id: menu.c,v 1.92 2003/04/23 05:37:22 guy Exp $ + * $Id: menu.c,v 1.93 2003/05/03 00:48:37 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -757,13 +757,13 @@ set_menus_for_selected_tree_row(gboolean have_selected_tree) "/Go To Corresponding Frame", FALSE); } set_menu_sensitivity(main_menu_factory, "/Display/Match", - proto_can_match_selected(finfo_selected)); + proto_can_match_selected(finfo_selected, cfile.edt)); set_menu_sensitivity(tree_view_menu_factory, "/Match", - proto_can_match_selected(finfo_selected)); + proto_can_match_selected(finfo_selected, cfile.edt)); set_menu_sensitivity(main_menu_factory, "/Display/Prepare", - proto_can_match_selected(finfo_selected)); + proto_can_match_selected(finfo_selected, cfile.edt)); set_menu_sensitivity(tree_view_menu_factory, "/Prepare", - proto_can_match_selected(finfo_selected)); + proto_can_match_selected(finfo_selected, cfile.edt)); } else { set_menu_sensitivity(main_menu_factory, "/Display/Match", FALSE); set_menu_sensitivity(tree_view_menu_factory, "/Match", FALSE); diff --git a/tap-protocolinfo.c b/tap-protocolinfo.c index c2025a3ae8..eade2065be 100644 --- a/tap-protocolinfo.c +++ b/tap-protocolinfo.c @@ -1,7 +1,7 @@ /* tap-protocolinfo.c * protohierstat 2002 Ronnie Sahlberg * - * $Id: tap-protocolinfo.c,v 1.3 2003/04/23 08:20:01 guy Exp $ + * $Id: tap-protocolinfo.c,v 1.4 2003/05/03 00:48:33 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -61,9 +61,11 @@ protocolinfo_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt, void *du } for(i=0;ilen;i++){ - str=proto_alloc_dfilter_string(gp->pdata[i], NULL); - col_append_fstr(pinfo->cinfo, COL_INFO, " %s",str); - g_free(str); + str=proto_construct_dfilter_string(gp->pdata[i], NULL); + if(str){ + col_append_fstr(pinfo->cinfo, COL_INFO, " %s",str); + g_free(str); + } } return 0; }