When printing the code for a display filter:

print register numbers as unsigned (they're guint32);

	when printing a PUT_FVALUE instruction, show the value as well
	as the type of the value.

That requires that a bunch of types get to_repr methods; add them for
PCRE (FTREPR_DFILTER-only - show the regular expression as text),
tvbuffs (FTREPR_DFILTER_only - show the data as a hex string), integral
types, string types other than FT_STRING, and FT_IPv6.

That means we can use fvalue_to_string_repr() for FT_IPXNET and FT_IPv6
in proto_construct_dfilter_string(), and that we don't need to handle
integer and floating types specially in MATE.

Fix some problems with the PCRE execution code for tvbuff types.

svn path=/trunk/; revision=16369
This commit is contained in:
Guy Harris 2005-10-31 02:42:22 +00:00
parent 552ee02a93
commit cbce856e9e
8 changed files with 195 additions and 116 deletions

View File

@ -2,10 +2,9 @@
* $Id$
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* By Gerald Combs <gerald@ethereal.com>
* Copyright 2001 Gerald Combs
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -93,6 +92,7 @@ dfvm_dump(FILE *f, GPtrArray *insns)
dfvm_value_t *arg2;
dfvm_value_t *arg3;
dfvm_value_t *arg4;
char *value_str;
length = insns->len;
@ -111,66 +111,70 @@ dfvm_dump(FILE *f, GPtrArray *insns)
break;
case READ_TREE:
fprintf(f, "%05d READ_TREE\t\t%s -> reg#%d\n",
fprintf(f, "%05d READ_TREE\t\t%s -> reg#%u\n",
id, arg1->value.hfinfo->abbrev,
arg2->value.numeric);
break;
case PUT_FVALUE:
fprintf(f, "%05d PUT_FVALUE\t<%s> -> reg#%d\n",
id, fvalue_type_name(arg1->value.fvalue),
value_str = fvalue_to_string_repr(arg1->value.fvalue,
FTREPR_DFILTER, NULL);
fprintf(f, "%05d PUT_FVALUE\t%s <%s> -> reg#%u\n",
id, value_str,
fvalue_type_name(arg1->value.fvalue),
arg2->value.numeric);
g_free(value_str);
break;
case MK_RANGE:
fprintf(f, "%05d MK_RANGE\t\treg#%d[?] -> reg#%d\n",
fprintf(f, "%05d MK_RANGE\t\treg#%u[?] -> reg#%u\n",
id,
arg1->value.numeric,
arg2->value.numeric);
break;
case ANY_EQ:
fprintf(f, "%05d ANY_EQ\t\treg#%d == reg#%d\n",
fprintf(f, "%05d ANY_EQ\t\treg#%u == reg#%u\n",
id, arg1->value.numeric, arg2->value.numeric);
break;
case ANY_NE:
fprintf(f, "%05d ANY_NE\t\treg#%d == reg#%d\n",
fprintf(f, "%05d ANY_NE\t\treg#%u == reg#%u\n",
id, arg1->value.numeric, arg2->value.numeric);
break;
case ANY_GT:
fprintf(f, "%05d ANY_GT\t\treg#%d == reg#%d\n",
fprintf(f, "%05d ANY_GT\t\treg#%u == reg#%u\n",
id, arg1->value.numeric, arg2->value.numeric);
break;
case ANY_GE:
fprintf(f, "%05d ANY_GE\t\treg#%d == reg#%d\n",
fprintf(f, "%05d ANY_GE\t\treg#%u == reg#%u\n",
id, arg1->value.numeric, arg2->value.numeric);
break;
case ANY_LT:
fprintf(f, "%05d ANY_LT\t\treg#%d == reg#%d\n",
fprintf(f, "%05d ANY_LT\t\treg#%u == reg#%u\n",
id, arg1->value.numeric, arg2->value.numeric);
break;
case ANY_LE:
fprintf(f, "%05d ANY_LE\t\treg#%d == reg#%d\n",
fprintf(f, "%05d ANY_LE\t\treg#%u == reg#%u\n",
id, arg1->value.numeric, arg2->value.numeric);
break;
case ANY_BITWISE_AND:
fprintf(f, "%05d ANY_BITWISE_AND\t\treg#%d == reg#%d\n",
fprintf(f, "%05d ANY_BITWISE_AND\t\treg#%u == reg#%u\n",
id, arg1->value.numeric, arg2->value.numeric);
break;
case ANY_CONTAINS:
fprintf(f, "%05d ANY_CONTAINS\treg#%d contains reg#%d\n",
fprintf(f, "%05d ANY_CONTAINS\treg#%u contains reg#%u\n",
id, arg1->value.numeric, arg2->value.numeric);
break;
case ANY_MATCHES:
fprintf(f, "%05d ANY_MATCHES\treg#%d matches reg#%d\n",
fprintf(f, "%05d ANY_MATCHES\treg#%u matches reg#%u\n",
id, arg1->value.numeric, arg2->value.numeric);
break;

View File

@ -238,6 +238,21 @@ ipv6_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogF
return TRUE;
}
static int
ipv6_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
{
/*
* 39 characters for "XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX".
*/
return 39;
}
static void
ipv6_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
{
ip6_to_str_buf((struct e_in6_addr *)fv->value.bytes->data, buf);
}
static gboolean
get_guid(char *s, guint8 *buf)
{
@ -603,8 +618,8 @@ ftype_register_bytes(void)
bytes_fvalue_free, /* free_value */
ipv6_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
ipv6_to_repr, /* val_to_string_repr */
ipv6_repr_len, /* len_string_repr */
ipv6_fvalue_set, /* set_value */
NULL, /* set_value_integer */
@ -638,8 +653,8 @@ ftype_register_bytes(void)
bytes_fvalue_free, /* free_value */
guid_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
guid_to_repr, /* val_to_string_repr */
guid_repr_len, /* len_string_repr */
guid_to_repr, /* val_to_string_repr */
guid_repr_len, /* len_string_repr */
guid_fvalue_set, /* set_value */
NULL, /* set_value_integer */

View File

@ -108,6 +108,30 @@ val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFu
return TRUE;
}
static int
integer_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
{
return 11; /* enough for 12^31-1, in decimal */
}
static void
integer_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
{
sprintf(buf, "%d", fv->value.integer);
}
static int
uinteger_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
{
return 10; /* enough for 2^32-1, in decimal */
}
static void
uinteger_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
{
sprintf(buf, "%u", fv->value.integer);
}
static gboolean
ipxnet_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
{
@ -133,6 +157,18 @@ ipxnet_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, Lo
return FALSE;
}
static int
ipxnet_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
{
return 2+8; /* 0xXXXXXXXX */
}
static void
ipxnet_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
{
sprintf(buf, "0x%08x", fv->value.integer);
}
static gboolean
cmp_eq(fvalue_t *a, fvalue_t *b)
{
@ -262,6 +298,30 @@ val64_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, Log
return TRUE;
}
static int
integer64_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
{
return 20; /* enough for -2^63-1, in decimal */
}
static void
integer64_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
{
sprintf(buf, PRId64, fv->value.integer64);
}
static int
uinteger64_repr_len(fvalue_t *fv _U_, ftrepr_t rtype _U_)
{
return 20; /* enough for 2^64-1, in decimal */
}
static void
uinteger64_to_repr(fvalue_t *fv, ftrepr_t rtype _U_, char *buf)
{
sprintf(buf, PRIu64, fv->value.integer64);
}
static gboolean
cmp_eq64(fvalue_t *a, fvalue_t *b)
{
@ -391,8 +451,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
uinteger_to_repr, /* val_to_string_repr */
uinteger_repr_len, /* len_string_repr */
NULL, /* set_value */
set_integer, /* set_value_integer */
@ -425,8 +485,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
uinteger_to_repr, /* val_to_string_repr */
uinteger_repr_len, /* len_string_repr */
NULL, /* set_value */
set_integer, /* set_value_integer */
@ -459,8 +519,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
uinteger_to_repr, /* val_to_string_repr */
uinteger_repr_len, /* len_string_repr */
NULL, /* set_value */
set_integer, /* set_value_integer */
@ -493,8 +553,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
uinteger_to_repr, /* val_to_string_repr */
uinteger_repr_len, /* len_string_repr */
NULL, /* set_value */
set_integer, /* set_value_integer */
@ -527,8 +587,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val64_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
uinteger64_to_repr, /* val_to_string_repr */
uinteger64_repr_len, /* len_string_repr */
NULL, /* set_value */
NULL, /* set_value_integer */
@ -561,8 +621,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
integer_to_repr, /* val_to_string_repr */
integer_repr_len, /* len_string_repr */
NULL, /* set_value */
set_integer, /* set_value_integer */
@ -595,8 +655,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
integer_to_repr, /* val_to_string_repr */
integer_repr_len, /* len_string_repr */
NULL, /* set_value */
set_integer, /* set_value_integer */
@ -629,8 +689,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
integer_to_repr, /* val_to_string_repr */
integer_repr_len, /* len_string_repr */
NULL, /* set_value */
set_integer, /* set_value_integer */
@ -663,8 +723,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
integer_to_repr, /* val_to_string_repr */
integer_repr_len, /* len_string_repr */
NULL, /* set_value */
set_integer, /* set_value_integer */
@ -697,8 +757,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val64_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
integer64_to_repr, /* val_to_string_repr */
integer64_repr_len, /* len_string_repr */
NULL, /* set_value */
NULL, /* set_value_integer */
@ -766,8 +826,8 @@ ftype_register_integers(void)
NULL, /* free_value */
ipxnet_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
ipxnet_to_repr, /* val_to_string_repr */
ipxnet_repr_len, /* len_string_repr */
NULL, /* set_value */
set_integer, /* set_value_integer */
@ -801,8 +861,8 @@ ftype_register_integers(void)
NULL, /* free_value */
val_from_unparsed, /* val_from_unparsed */
NULL, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
uinteger_to_repr, /* val_to_string_repr */
uinteger_repr_len, /* len_string_repr */
NULL, /* set_value */
set_integer, /* set_value_integer */

View File

@ -5,7 +5,6 @@
* By Gerald Combs <gerald@ethereal.com>
* Copyright 2001 Gerald Combs
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -35,6 +34,9 @@
#include <ftypes-int.h>
#ifdef HAVE_LIBPCRE
#include <string.h>
#include <pcre.h>
/* Create a pcre_tuple_t object based on the given string pattern */
@ -138,6 +140,20 @@ val_from_unparsed(fvalue_t *fv, char *pattern, gboolean allow_partial_value _U_,
return TRUE;
}
static int
pcre_repr_len(fvalue_t *fv, ftrepr_t rtype)
{
g_assert(rtype == FTREPR_DFILTER);
return strlen(fv->value.re->string);
}
static void
pcre_to_repr(fvalue_t *fv, ftrepr_t rtype, char *buf)
{
g_assert(rtype == FTREPR_DFILTER);
strcpy(buf, fv->value.re->string);
}
/* BEHOLD - value contains the string representation of the regular expression,
* and we want to store the compiled PCRE RE object into the value. */
static void
@ -167,8 +183,8 @@ ftype_register_pcre(void)
pcre_fvalue_free, /* free_value */
val_from_unparsed, /* val_from_unparsed */
val_from_string, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
pcre_to_repr, /* val_to_string_repr */
pcre_repr_len, /* len_string_repr */
pcre_fvalue_set, /* set_value */
NULL, /* set_value_integer */

View File

@ -342,8 +342,8 @@ ftype_register_string(void)
string_fvalue_free, /* free_value */
val_from_unparsed, /* val_from_unparsed */
val_from_string, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
string_to_repr, /* val_to_string_repr */
string_repr_len, /* len_string_repr */
string_fvalue_set, /* set_value */
NULL, /* set_value_integer */
@ -376,8 +376,8 @@ ftype_register_string(void)
string_fvalue_free, /* free_value */
val_from_unparsed, /* val_from_unparsed */
val_from_string, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
string_to_repr, /* val_to_string_repr */
string_repr_len, /* len_string_repr */
string_fvalue_set, /* set_value */
NULL, /* set_value_integer */

View File

@ -127,6 +127,43 @@ val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFu
g_assert_not_reached();
}
static int
val_repr_len(fvalue_t *fv, ftrepr_t rtype)
{
guint length;
g_assert(rtype == FTREPR_DFILTER);
length = tvb_length(fv->value.tvb);
/* 3 bytes for each byte of the byte "NN:" minus 1 byte
* as there's no trailing ":". */
return length * 3 - 1;
}
static void
val_to_repr(fvalue_t *fv, ftrepr_t rtype, char *buf)
{
guint length;
const guint8 *c;
char *write_cursor;
unsigned int i;
g_assert(rtype == FTREPR_DFILTER);
length = tvb_length(fv->value.tvb);
c = tvb_get_ptr(fv->value.tvb, 0, length);
write_cursor = buf;
for (i = 0; i < length; i++) {
if (i == 0) {
sprintf(write_cursor, "%02x", *c++);
write_cursor += 2;
}
else {
sprintf(write_cursor, ":%02x", *c++);
write_cursor += 3;
}
}
}
static gpointer
value_get(fvalue_t *fv)
{
@ -178,7 +215,7 @@ cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b)
tvbuff_t *tvb = fv_a->value.tvb;
pcre_tuple_t *pcre = fv_b->value.re;
int options = 0;
int rc;
volatile int rc = 1;
const char *data = NULL; /* tvb data */
guint32 tvb_len; /* tvb length */
@ -200,10 +237,10 @@ cmp_matches(fvalue_t *fv_a, fvalue_t *fv_b)
pcre->ex, /* PCRE extra from pcre_study() */
data, /* The data to check for the pattern... */
tvb_len, /* ... and its length */
0, /* Start offset within data */
0, /* Start offset within data */
options, /* PCRE options */
NULL, /* We are not interested in the matched string */
0 /* of the pattern; only in success or failure. */
0 /* of the pattern; only in success or failure. */
);
/* NOTE - DO NOT g_free(data) */
}
@ -230,8 +267,8 @@ ftype_register_tvbuff(void)
value_free, /* free_value */
val_from_unparsed, /* val_from_unparsed */
val_from_string, /* val_from_string */
NULL, /* val_to_string_repr */
NULL, /* len_string_repr */
val_to_repr, /* val_to_string_repr */
val_repr_len, /* len_string_repr */
value_set, /* set_value */
NULL, /* set_value_integer */

View File

@ -4683,7 +4683,7 @@ proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
}
/* This function returns a string allocated with packet lifetime scope.
* You do not need to [g_]free() this string since it willb e automatically
* You do not need to [g_]free() this string since it will be automatically
* freed once the next packet is dissected.
*/
char*
@ -4703,17 +4703,14 @@ proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
abbrev_len = strlen(hfinfo->abbrev);
/*
* XXX - we should add "val_to_string_repr" and "string_repr_len"
* functions for more types, and use them whenever possible.
*
* The FT_UINT and FT_INT types are the only tricky ones, as
* we choose the base in the string expression based on the
* display base of the field.
* XXX - we can't use the "val_to_string_repr" and "string_repr_len"
* functions for FT_UINT and FT_INT types, as we choose the base in
* the string expression based on the display base of the field.
*
* Note that the base does matter, as this is also used for
* the protocolinfo tap.
*
* It might be nice to use that in "proto_item_fill_label()"
* It might be nice to use them in "proto_item_fill_label()"
* as well, although, there, you'd have to deal with the base
* *and* with resolved values for addresses.
*
@ -4782,33 +4779,8 @@ proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
g_snprintf(buf, dfilter_len, format, hfinfo->abbrev, fvalue_get_integer64(&finfo->value));
break;
case FT_IPXNET:
/*
* 4 bytes for " == ".
* 2 bytes for "0x".
* 8 bytes for 8 digits of 32-bit hex number.
* 1 byte for the trailing '\0'.
*/
dfilter_len = abbrev_len + 4 + 2 + 8 + 1;
buf = ep_alloc0(dfilter_len);
g_snprintf(buf, dfilter_len, "%s == 0x%08x", hfinfo->abbrev,
fvalue_get_integer(&finfo->value));
break;
case FT_IPv6:
/*
* 4 bytes for " == ".
* N bytes for the string for the address.
* 1 byte for the trailing '\0'.
*/
stringified = ip6_to_str((struct e_in6_addr*) fvalue_get(&finfo->value));
dfilter_len = abbrev_len + 4 + strlen(stringified) + 1;
buf = ep_alloc0(dfilter_len);
g_snprintf(buf, dfilter_len, "%s == %s", hfinfo->abbrev,
stringified);
break;
/* These use the fvalue's "to_string_repr" method. */
case FT_IPXNET:
case FT_BOOLEAN:
case FT_STRING:
case FT_ETHER:
@ -4819,6 +4791,7 @@ proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
case FT_ABSOLUTE_TIME:
case FT_RELATIVE_TIME:
case FT_IPv4:
case FT_IPv6:
case FT_GUID:
/* Figure out the string length needed.
* The ft_repr length.

View File

@ -237,22 +237,6 @@ gchar* scs_subscribe_printf(SCS_collection* c, gchar* fmt, ...) {
return scs_subscribe(c,buf);
}
static gchar* scs_subscribe_int(SCS_collection* c, int i) {
static gchar buf[SCS_SMALL_SIZE];
g_snprintf(buf, SCS_SMALL_SIZE-1 ,"%i", i);
return scs_subscribe(c,buf);
}
static gchar* scs_subscribe_float(SCS_collection* c, float f) {
static gchar buf[SCS_SMALL_SIZE];
g_snprintf(buf, SCS_SMALL_SIZE-1 ,"%f", f);
return scs_subscribe(c,buf);
}
/***************************************************************************
* AVPs & Co.
***************************************************************************
@ -353,20 +337,10 @@ extern AVP* new_avp_from_finfo(const gchar* name, field_info* finfo) {
new->n = scs_subscribe(avp_strings, name);
if (finfo->value.ftype->get_value_integer) {
value = scs_subscribe_int(avp_strings, fvalue_get_integer(&finfo->value));
#ifdef _AVP_DEBUGGING
dbg_print (dbg_avp,2,dbg_fp,"new_avp_from_finfo: from integer: %s",value);
#endif
} else if (finfo->value.ftype->val_to_string_repr) {
if (finfo->value.ftype->val_to_string_repr) {
value = scs_subscribe(avp_strings, fvalue_to_string_repr(&finfo->value,FTREPR_DISPLAY,NULL));
#ifdef _AVP_DEBUGGING
dbg_print (dbg_avp,2,dbg_fp,"new_avp_from_finfo: from string: %s",value);
#endif
} else if (finfo->value.ftype->get_value_floating) {
value = scs_subscribe_float(avp_strings, (float) fvalue_get_floating(&finfo->value));
#ifdef _AVP_DEBUGGING
dbg_print (dbg_avp,2,dbg_fp,"new_avp_from_finfo: from float: %s",value);
#endif
} else {
#ifdef _AVP_DEBUGGING