aboutsummaryrefslogtreecommitdiffstats
path: root/epan/proto.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-02-01 20:56:56 -0800
committerGuy Harris <guy@alum.mit.edu>2016-02-02 04:57:28 +0000
commitc599cd7b0b7bb8e5b5998633d4989a75b41a51a6 (patch)
tree792c271cc0d3c8d6149c99f0422295c802820545 /epan/proto.c
parentcd7daa77d9ef833de0be145baaa225a297b75654 (diff)
Add proto_tree_add_item_ret_string() routine.
It adds string-type fields to the protocol tree and returns the value of the string. Add the new bitmask-adding routines to the Debian symbol list while we're at it. Change-Id: Idaeec44c9cd373588cadce85010f3eaf1f3febb5 Reviewed-on: https://code.wireshark.org/review/13657 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/proto.c')
-rw-r--r--epan/proto.c247
1 files changed, 173 insertions, 74 deletions
diff --git a/epan/proto.c b/epan/proto.c
index 7c7c4b9891..d68e480c7f 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -225,8 +225,6 @@ proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
static void
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, gint encoding);
-static void
proto_tree_set_ax25(field_info *fi, const guint8* value);
static void
proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
@@ -1511,6 +1509,98 @@ get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const
return value;
}
+/* For FT_STRING */
+static inline const guint8 *
+get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
+ gint length, gint *ret_length, const guint encoding)
+{
+ if (length == -1) {
+ length = tvb_ensure_captured_length_remaining(tvb, start);
+ }
+ *ret_length = length;
+ return tvb_get_string_enc(scope, tvb, start, length, encoding);
+}
+
+/* For FT_STRINGZ */
+static inline const guint8 *
+get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
+ gint start, gint length, gint *ret_length, const guint encoding)
+{
+ const guint8 *value;
+
+ if (length < -1) {
+ report_type_length_mismatch(tree, "a string", length, TRUE);
+ }
+ if (length == -1) {
+ /* This can throw an exception */
+ value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
+ } else if (length == 0) {
+ value = "[Empty]";
+ } else {
+ /* In this case, length signifies the length of the string.
+ *
+ * This could either be a null-padded string, which doesn't
+ * necessarily have a '\0' at the end, or a null-terminated
+ * string, with a trailing '\0'. (Yes, there are cases
+ * where you have a string that's both counted and null-
+ * terminated.)
+ *
+ * In the first case, we must allocate a buffer of length
+ * "length+1", to make room for a trailing '\0'.
+ *
+ * In the second case, we don't assume that there is a
+ * trailing '\0' there, as the packet might be malformed.
+ * (XXX - should we throw an exception if there's no
+ * trailing '\0'?) Therefore, we allocate a buffer of
+ * length "length+1", and put in a trailing '\0', just to
+ * be safe.
+ *
+ * (XXX - this would change if we made string values counted
+ * rather than null-terminated.)
+ */
+ value = tvb_get_string_enc(scope, tvb, start, length, encoding);
+ }
+ *ret_length = length;
+ return value;
+}
+
+/* For FT_UINT_STRING */
+static inline const guint8 *
+get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
+ tvbuff_t *tvb, gint start, gint length, gint *ret_length,
+ const guint encoding)
+{
+ guint32 n;
+ const guint8 *value;
+
+ /* I believe it's ok if this is called with a NULL tree */
+ n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
+ value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
+ length += n;
+ *ret_length = length;
+ return value;
+}
+
+/* For FT_STRINGZPAD */
+static inline const guint8 *
+get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
+ gint length, gint *ret_length, const guint encoding)
+{
+ /*
+ * XXX - currently, string values are null-
+ * terminated, so a "zero-padded" string
+ * isn't special. If we represent string
+ * values as something that includes a counted
+ * array of bytes, we'll need to strip
+ * trailing NULs.
+ */
+ if (length == -1) {
+ length = tvb_ensure_captured_length_remaining(tvb, start);
+ }
+ *ret_length = length;
+ return tvb_get_string_enc(scope, tvb, start, length, encoding);
+}
+
/* this can be called when there is no tree, so don't add that as a param */
static void
get_time_value(tvbuff_t *tvb, const gint start, const gint length, const guint encoding,
@@ -1729,7 +1819,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
guint32 value, n;
float floatval;
double doubleval;
- const char *string;
+ const char *stringval;
nstime_t time_stamp;
gboolean length_error;
@@ -1993,14 +2083,27 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
break;
case FT_STRING:
- proto_tree_set_string_tvb(new_fi, tvb, start, length,
- encoding);
+ stringval = get_string_value(wmem_packet_scope(),
+ tvb, start, length, &length, encoding);
+ proto_tree_set_string(new_fi, stringval);
+
+ /* Instead of calling proto_item_set_len(), since we
+ * don't yet have a proto_item, we set the
+ * field_info's length ourselves.
+ *
+ * XXX - our caller can't use that length to
+ * advance an offset unless they arrange that
+ * there always be a protocol tree into which
+ * we're putting this item.
+ */
+ new_fi->length = length;
break;
case FT_STRINGZ:
- if (length < -1) {
- report_type_length_mismatch(tree, "a string", length, TRUE);
- }
+ stringval = get_stringz_value(wmem_packet_scope(),
+ tree, tvb, start, length, &length, encoding);
+ proto_tree_set_string(new_fi, stringval);
+
/* Instead of calling proto_item_set_len(),
* since we don't yet have a proto_item, we
* set the field_info's length ourselves.
@@ -2010,47 +2113,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
* there always be a protocol tree into which
* we're putting this item.
*/
- if (length == -1) {
- /* This can throw an exception */
- string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
- } else if (length == 0) {
- string = "[Empty]";
- } else {
- /* In this case, length signifies
- * the length of the string.
- *
- * This could either be a null-padded
- * string, which doesn't necessarily
- * have a '\0' at the end, or a
- * null-terminated string, with a
- * trailing '\0'. (Yes, there are
- * cases where you have a string
- * that's both counted and null-
- * terminated.)
- *
- * In the first case, we must
- * allocate a buffer of length
- * "length+1", to make room for
- * a trailing '\0'.
- *
- * In the second case, we don't
- * assume that there is a trailing
- * '\0' there, as the packet might
- * be malformed. (XXX - should we
- * throw an exception if there's no
- * trailing '\0'?) Therefore, we
- * allocate a buffer of length
- * "length+1", and put in a trailing
- * '\0', just to be safe.
- *
- * (XXX - this would change if
- * we made string values counted
- * rather than null-terminated.)
- */
- string = tvb_get_string_enc(wmem_packet_scope(), tvb, start, length, encoding);
- }
new_fi->length = length;
- proto_tree_set_string(new_fi, string);
break;
case FT_UINT_STRING:
@@ -2068,9 +2131,9 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
*/
if (encoding == TRUE)
encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
- n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
- proto_tree_set_string_tvb(new_fi, tvb, start + length, n,
- encoding);
+ stringval = get_uint_string_value(wmem_packet_scope(),
+ tree, tvb, start, length, &length, encoding);
+ proto_tree_set_string(new_fi, stringval);
/* Instead of calling proto_item_set_len(), since we
* don't yet have a proto_item, we set the
@@ -2081,20 +2144,24 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
* there always be a protocol tree into which
* we're putting this item.
*/
- new_fi->length = n + length;
+ new_fi->length = length;
break;
case FT_STRINGZPAD:
- /*
- * XXX - currently, string values are null-
- * terminated, so a "zero-padded" string
- * isn't special. If we represent string
- * values as something that includes a counted
- * array of bytes, we'll need to strip
- * trailing NULs.
+ stringval = get_stringzpad_value(wmem_packet_scope(),
+ tvb, start, length, &length, encoding);
+ proto_tree_set_string(new_fi, stringval);
+
+ /* Instead of calling proto_item_set_len(), since we
+ * don't yet have a proto_item, we set the
+ * field_info's length ourselves.
+ *
+ * XXX - our caller can't use that length to
+ * advance an offset unless they arrange that
+ * there always be a protocol tree into which
+ * we're putting this item.
*/
- proto_tree_set_string_tvb(new_fi, tvb, start, length,
- encoding);
+ new_fi->length = length;
break;
case FT_ABSOLUTE_TIME:
@@ -2288,6 +2355,51 @@ proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
return proto_tree_add_node(tree, new_fi);
}
+proto_item *
+proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
+ const gint start, gint length,
+ const guint encoding, wmem_allocator_t *scope,
+ const guint8 **retval)
+{
+ header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
+ field_info *new_fi;
+ const guint8 *value;
+
+ DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
+
+ switch (hfinfo->type){
+ case FT_STRING:
+ value = get_string_value(scope, tvb, start, length, &length, encoding);
+ break;
+ case FT_STRINGZ:
+ value = get_stringz_value(scope, tree, tvb, start, length, &length, encoding);
+ break;
+ case FT_UINT_STRING:
+ value = get_uint_string_value(scope, tree, tvb, start, length, &length, encoding);
+ break;
+ case FT_STRINGZPAD:
+ value = get_stringzpad_value(scope, tvb, start, length, &length, encoding);
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ }
+
+ if (retval)
+ *retval = value;
+
+ CHECK_FOR_NULL_TREE(tree);
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
+
+ new_fi = new_field_info(tree, hfinfo, tvb, start, length);
+
+ proto_tree_set_string(new_fi, value);
+
+ new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
+
+ return proto_tree_add_node(tree, new_fi);
+}
+
/*
* Validates that field length bytes are available starting from
@@ -3464,19 +3576,6 @@ 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, gint encoding)
-{
- gchar *string;
-
- if (length == -1) {
- length = tvb_ensure_captured_length_remaining(tvb, start);
- }
-
- string = tvb_get_string_enc(wmem_packet_scope(), tvb, start, length, encoding);
- proto_tree_set_string(fi, string);
-}
-
/* Set the FT_AX25 value */
static void
proto_tree_set_ax25(field_info *fi, const guint8* value)