aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2000-07-27 06:41:59 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2000-07-27 06:41:59 +0000
commit9e4260ae467002f135c8d8dcb1252417d0fc4f83 (patch)
tree5a37b3935dbc315f6df1720180e4ea4d0ca34031
parent1cbca8fb96894db59a49ea786d4320e339e0b997 (diff)
Add initial attempt at FT_NSTRING_UINT8, a string with a single byte prefix
indicating the string length. It's available only with proto_tree_add_item(). Add proto_item_get_len(), so that dissectors can find out how long the FT_NSTRING_UINT8 turned out to be. In proto_tree_add_item(), don't add a proto_item to the proto_tree until *after* the attempt to pull data from the tvbuff. That way, if the tvbuff raises an exception, an item with garbage data won't be left in the proto_tree. svn path=/trunk/; revision=2167
-rw-r--r--proto.c67
-rw-r--r--proto.h7
2 files changed, 59 insertions, 15 deletions
diff --git a/proto.c b/proto.c
index f8262fcc7d..fac918c80c 100644
--- a/proto.c
+++ b/proto.c
@@ -1,7 +1,7 @@
/* proto.c
* Routines for protocol tree
*
- * $Id: proto.c,v 1.70 2000/07/22 15:58:53 gram Exp $
+ * $Id: proto.c,v 1.71 2000/07/27 06:41:58 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -91,6 +91,9 @@ static gboolean check_for_protocol_or_field_id(GNode *node, gpointer data);
static proto_item*
proto_tree_add_node(proto_tree *tree, field_info *fi);
+static field_info *
+alloc_field_info(int hfindex, tvbuff_t *tvb, gint start, gint length);
+
static proto_item *
proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
field_info **pfi);
@@ -251,6 +254,8 @@ proto_tree_free_node(GNode *node, gpointer data)
g_mem_chunk_free(gmc_item_labels, fi->representation);
if (fi->hfinfo->type == FT_STRING)
g_free(fi->value.string);
+ else if (fi->hfinfo->type == FT_NSTRING_UINT8)
+ g_free(fi->value.string);
else if (fi->hfinfo->type == FT_BYTES)
g_free(fi->value.bytes);
g_mem_chunk_free(gmc_field_info, fi);
@@ -400,12 +405,13 @@ proto_item *
proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
gint start, gint length, gboolean little_endian)
{
- proto_item *pi;
field_info *new_fi;
- guint32 value;
+ proto_item *pi;
+ guint32 value, n;
- pi = proto_tree_add_pi(tree, hfindex, tvb, start, length, &new_fi);
- if (pi == NULL)
+ new_fi = alloc_field_info(hfindex, tvb, start, length);
+
+ if (new_fi == NULL)
return(NULL);
switch(new_fi->hfinfo->type) {
@@ -467,12 +473,25 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
proto_tree_set_string_tvb(new_fi, tvb, start, length);
break;
+ case FT_NSTRING_UINT8:
+ n = tvb_get_guint8(tvb, start);
+ /* This g_strdup'ed memory is freed in proto_tree_free_node() */
+ proto_tree_set_string_tvb(new_fi, tvb, start + 1, n);
+ /* Instead of calling proto_item_set_len(), since we don't yet
+ * have a proto_item, we set the field_info's length ourselves. */
+ new_fi->length = n + 1;
+ break;
+
default:
g_error("new_fi->hfinfo->type %d not handled\n", new_fi->hfinfo->type);
g_assert_not_reached();
break;
}
+ /* Don't add to proto_item to proto_tree until now so that any exceptions
+ * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
+ pi = proto_tree_add_node(tree, new_fi);
+
return pi;
}
@@ -933,8 +952,10 @@ proto_tree_set_string(field_info *fi, const char* value)
static void
proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
{
- /* This g_strdup'ed memory is freed in proto_tree_free_node() */
- fi->value.string = tvb_memdup(tvb, start, length);
+ /* This memory is freed in proto_tree_free_node() */
+ fi->value.string = g_malloc(length + 1);
+ tvb_memcpy(tvb, fi->value.string, start, length);
+ fi->value.string[length] = '\0';
}
/* Add a FT_ETHER to a proto_tree */
@@ -1326,6 +1347,21 @@ proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint
if (!tree)
return(NULL);
+ fi = alloc_field_info(hfindex, tvb, start, length);
+ pi = proto_tree_add_node(tree, fi);
+
+ if (pfi) {
+ *pfi = fi;
+ }
+
+ return pi;
+}
+
+static field_info *
+alloc_field_info(int hfindex, tvbuff_t *tvb, gint start, gint length)
+{
+ field_info *fi;
+
fi = g_mem_chunk_alloc(gmc_field_info);
g_assert(hfindex >= 0 && hfindex < gpa_hfinfo->len);
@@ -1340,13 +1376,7 @@ proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint
fi->visible = proto_tree_is_visible;
fi->representation = NULL;
- pi = proto_tree_add_node(tree, fi);
-
- if (pfi) {
- *pfi = fi;
- }
-
- return pi;
+ return fi;
}
/* Set representation of a proto_tree entry, if the protocol tree is to
@@ -1383,6 +1413,13 @@ proto_item_set_len(proto_item *pi, gint length)
fi->length = length;
}
+int
+proto_item_get_len(proto_item *pi)
+{
+ field_info *fi = (field_info*) (((GNode*)pi)->data);
+ return fi->length;
+}
+
proto_tree*
proto_tree_create_root(void)
{
@@ -1601,6 +1638,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str)
break;
case FT_STRING:
+ case FT_NSTRING_UINT8:
snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s", fi->hfinfo->name, fi->value.string);
break;
@@ -2049,6 +2087,7 @@ proto_registrar_get_length(int n)
case FT_BYTES:
case FT_BOOLEAN:
case FT_STRING:
+ case FT_NSTRING_UINT8:
case FT_DOUBLE:
case FT_ABSOLUTE_TIME:
case FT_RELATIVE_TIME:
diff --git a/proto.h b/proto.h
index 2597c7e7af..7ad266f9e6 100644
--- a/proto.h
+++ b/proto.h
@@ -1,7 +1,7 @@
/* proto.h
* Definitions for protocol display
*
- * $Id: proto.h,v 1.36 2000/07/22 15:58:54 gram Exp $
+ * $Id: proto.h,v 1.37 2000/07/27 06:41:59 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -75,6 +75,7 @@ enum ftenum {
FT_ABSOLUTE_TIME,
FT_RELATIVE_TIME,
FT_STRING,
+ FT_NSTRING_UINT8, /* String prefixed by 1 byte indicating length */
FT_ETHER,
FT_BYTES,
FT_IPv4,
@@ -159,6 +160,10 @@ void proto_item_set_text(proto_item *ti, const char *format, ...);
/* Set length of proto_item after having already been created. */
void proto_item_set_len(proto_item *ti, gint length);
+/* Get length of proto_item. Useful after using proto_tree_add_item()
+ * to add a variable-length field (e.g., FT_NSTRING_UINT8) */
+int proto_item_get_len(proto_item *ti);
+
/* Creates new proto_tree root */
proto_tree* proto_tree_create_root(void);