aboutsummaryrefslogtreecommitdiffstats
path: root/epan/proto.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-05-03 00:48:37 +0000
committerGuy Harris <guy@alum.mit.edu>2003-05-03 00:48:37 +0000
commitca318813a4d4c28af90b14abdb60f7ecbcb46ea9 (patch)
treee9aa16cb6d0df21a992929c5fc2cb8f53a13bd04 /epan/proto.c
parenta8f171f2ffb7ebba2f270a7baa2df94d35b0fed8 (diff)
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
Diffstat (limited to 'epan/proto.c')
-rw-r--r--epan/proto.c127
1 files changed, 104 insertions, 23 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 <gerald@ethereal.com>
@@ -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;i<finfo->length; i++) {
+ for (i=0;i<length; i++) {
+ c = tvb_get_guint8(finfo->ds_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);
}