aboutsummaryrefslogtreecommitdiffstats
path: root/epan/proto.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2019-06-08 01:08:11 -0700
committerGuy Harris <guy@alum.mit.edu>2019-06-08 09:11:22 +0000
commit1c601c204a26a3d4b49225bfa198eaee379e564e (patch)
tree4730332817d9816689e2066def26dcbb5a545ec3 /epan/proto.c
parentcf9f46c5f59dce4c528f6608a7dfffb7c1fbfb5a (diff)
Have routines to add a protocol tree item and return a display string.
That way, even if we're not building a protocol tree, so that you don't get protocol tree items, you can get the display string, e.g. to use in a column. Replace the use of the "get display string" routines with calls to those routines. Change-Id: I23e3e88838bdf837d8660c271f78c79b7d1c5620 Reviewed-on: https://code.wireshark.org/review/33519 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/proto.c')
-rw-r--r--epan/proto.c319
1 files changed, 203 insertions, 116 deletions
diff --git a/epan/proto.c b/epan/proto.c
index 1522b275fa..d22959611a 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -1004,6 +1004,96 @@ proto_registrar_get_id_byname(const char *field_name)
}
+static char *
+hfinfo_format_text(wmem_allocator_t *scope, const header_field_info *hfinfo,
+ const guchar *string)
+{
+ switch (hfinfo->display) {
+ case STR_ASCII:
+ return format_text(scope, string, strlen(string));
+/*
+ case STR_ASCII_WSP
+ return format_text_wsp(string, strlen(string));
+ */
+ case STR_UNICODE:
+ /* XXX, format_unicode_text() */
+ return wmem_strdup(scope, string);
+ }
+
+ return format_text(scope, string, strlen(string));
+}
+
+static char *
+hfinfo_format_bytes(wmem_allocator_t *scope, const header_field_info *hfinfo,
+ const guint8 *bytes, guint length)
+{
+ char *str = NULL;
+ const guint8 *p;
+ gboolean is_printable;
+
+ if (bytes) {
+ if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE) {
+ /*
+ * Check whether all bytes are printable.
+ */
+ is_printable = TRUE;
+ for (p = bytes; p < bytes+length; p++) {
+ if (!g_ascii_isprint(*p)) {
+ /* Not printable. */
+ is_printable = FALSE;
+ break;
+ }
+ }
+
+ /*
+ * If all bytes are printable ASCII, show the bytes
+ * as a string - in quotes to indicate that it's
+ * a string.
+ */
+ if (is_printable) {
+ str = wmem_strdup_printf(scope, "\"%.*s\"",
+ (int)length, bytes);
+ return str;
+ }
+ }
+
+ /*
+ * Either it's not printable ASCII, or we don't care whether
+ * it's printable ASCII; show it as hex bytes.
+ */
+ switch (FIELD_DISPLAY(hfinfo->display)) {
+ case SEP_DOT:
+ str = bytestring_to_str(scope, bytes, length, '.');
+ break;
+ case SEP_DASH:
+ str = bytestring_to_str(scope, bytes, length, '-');
+ break;
+ case SEP_COLON:
+ str = bytestring_to_str(scope, bytes, length, ':');
+ break;
+ case SEP_SPACE:
+ str = bytestring_to_str(scope, bytes, length, ' ');
+ break;
+ case BASE_NONE:
+ default:
+ if (prefs.display_byte_fields_with_spaces) {
+ str = bytestring_to_str(scope, bytes, length, ' ');
+ } else {
+ str = bytes_to_str(scope, bytes, length);
+ }
+ break;
+ }
+ }
+ else {
+ if (hfinfo->display & BASE_ALLOW_ZERO) {
+ str = wmem_strdup(scope, "<none>");
+ } else {
+ str = wmem_strdup(scope, "<MISSING>");
+ }
+ }
+ return str;
+}
+
static void
ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
{
@@ -3321,6 +3411,119 @@ proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
tvb, start, length, encoding, scope, retval, &length);
}
+proto_item *
+proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
+ tvbuff_t *tvb,
+ const gint start, gint length,
+ const guint encoding,
+ wmem_allocator_t *scope,
+ char **retval,
+ gint *lenretval)
+{
+ proto_item *pi;
+ header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
+ field_info *new_fi;
+ const guint8 *value;
+ guint32 n = 0;
+
+ DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
+
+ switch (hfinfo->type) {
+ case FT_STRING:
+ value = get_string_value(scope, tvb, start, length, lenretval, encoding);
+ *retval = hfinfo_format_text(scope, hfinfo, value);;
+ break;
+ case FT_STRINGZ:
+ value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
+ *retval = hfinfo_format_text(scope, hfinfo, value);;
+ break;
+ case FT_UINT_STRING:
+ value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
+ *retval = hfinfo_format_text(scope, hfinfo, value);;
+ break;
+ case FT_STRINGZPAD:
+ value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
+ *retval = hfinfo_format_text(scope, hfinfo, value);;
+ break;
+ case FT_BYTES:
+ value = tvb_get_ptr(tvb, start, length);
+ *retval = hfinfo_format_bytes(scope, hfinfo, value, length);
+ if (lenretval)
+ *lenretval = length;
+ break;
+ case FT_UINT_BYTES:
+ n = get_uint_value(tree, tvb, start, length, encoding);
+ value = tvb_get_ptr(tvb, start + length, n);
+ *retval = hfinfo_format_bytes(scope, hfinfo, value, n);
+ if (lenretval)
+ *lenretval = length + n;
+ break;
+ default:
+ REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_BYTES, or FT_UINT_BYTES",
+ hfinfo->abbrev);
+ }
+
+ CHECK_FOR_NULL_TREE(tree);
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
+
+ new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
+
+ switch (hfinfo->type) {
+
+ case FT_STRING:
+ case FT_STRINGZ:
+ case FT_UINT_STRING:
+ case FT_STRINGZPAD:
+ proto_tree_set_string(new_fi, value);
+ break;
+
+ case FT_BYTES:
+ proto_tree_set_bytes(new_fi, value, length);
+ break;
+
+ case FT_UINT_BYTES:
+ proto_tree_set_bytes(new_fi, value, n);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
+
+ pi = proto_tree_add_node(tree, new_fi);
+
+ switch (hfinfo->type) {
+
+ case FT_STRING:
+ case FT_STRINGZ:
+ case FT_UINT_STRING:
+ case FT_STRINGZPAD:
+ detect_trailing_stray_characters(hfinfo->type, encoding, value, length, pi);
+ break;
+
+ case FT_BYTES:
+ case FT_UINT_BYTES:
+ break;
+
+ default:
+ g_assert_not_reached();
+ }
+
+ return pi;
+}
+
+proto_item *
+proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
+ tvbuff_t *tvb,
+ const gint start, gint length,
+ const guint encoding,
+ wmem_allocator_t *scope,
+ char **retval)
+{
+ return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
+ tvb, start, length, encoding, scope, retval, &length);
+}
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
and returns proto_item* */
@@ -5733,96 +5936,6 @@ proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
}
}
-static char *
-hfinfo_format_text(wmem_allocator_t *scope, const header_field_info *hfinfo,
- const guchar *string)
-{
- switch (hfinfo->display) {
- case STR_ASCII:
- return format_text(scope, string, strlen(string));
-/*
- case STR_ASCII_WSP
- return format_text_wsp(string, strlen(string));
- */
- case STR_UNICODE:
- /* XXX, format_unicode_text() */
- return wmem_strdup(scope, string);
- }
-
- return format_text(scope, string, strlen(string));
-}
-
-static char *
-hfinfo_format_bytes(wmem_allocator_t *scope, const header_field_info *hfinfo,
- guint8 *bytes, guint length)
-{
- char *str = NULL;
- guint8 *p;
- gboolean is_printable;
-
- if (bytes) {
- if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE) {
- /*
- * Check whether all bytes are printable.
- */
- is_printable = TRUE;
- for (p = bytes; p < bytes+length; p++) {
- if (!g_ascii_isprint(*p)) {
- /* Not printable. */
- is_printable = FALSE;
- break;
- }
- }
-
- /*
- * If all bytes are printable ASCII, show the bytes
- * as a string - in quotes to indicate that it's
- * a string.
- */
- if (is_printable) {
- str = wmem_strdup_printf(scope, "\"%.*s\"",
- (int)length, bytes);
- return str;
- }
- }
-
- /*
- * Either it's not printable ASCII, or we don't care whether
- * it's printable ASCII; show it as hex bytes.
- */
- switch (FIELD_DISPLAY(hfinfo->display)) {
- case SEP_DOT:
- str = bytestring_to_str(scope, bytes, length, '.');
- break;
- case SEP_DASH:
- str = bytestring_to_str(scope, bytes, length, '-');
- break;
- case SEP_COLON:
- str = bytestring_to_str(scope, bytes, length, ':');
- break;
- case SEP_SPACE:
- str = bytestring_to_str(scope, bytes, length, ' ');
- break;
- case BASE_NONE:
- default:
- if (prefs.display_byte_fields_with_spaces) {
- str = bytestring_to_str(scope, bytes, length, ' ');
- } else {
- str = bytes_to_str(scope, bytes, length);
- }
- break;
- }
- }
- else {
- if (hfinfo->display & BASE_ALLOW_ZERO) {
- str = wmem_strdup(scope, "<none>");
- } else {
- str = wmem_strdup(scope, "<MISSING>");
- }
- }
- return str;
-}
-
static int
protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
{
@@ -12339,32 +12452,6 @@ proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
return ti;
}
-char *
-proto_string_item_get_display_string(wmem_allocator_t *scope, proto_item *pi)
-{
- field_info *fi = pi->finfo;
- header_field_info *hfinfo = fi->hfinfo;
-
- DISSECTOR_ASSERT(hfinfo->type == FT_STRING ||
- hfinfo->type == FT_STRINGZ ||
- hfinfo->type == FT_UINT_STRING ||
- hfinfo->type == FT_STRINGZPAD);
- return hfinfo_format_text(scope, hfinfo,
- (guint8 *)fvalue_get(&fi->value));
-}
-
-char *
-proto_bytes_item_get_display_string(wmem_allocator_t *scope, proto_item *pi)
-{
- field_info *fi = pi->finfo;
- header_field_info *hfinfo = fi->hfinfo;
-
- DISSECTOR_ASSERT(hfinfo->type == FT_BYTES ||
- hfinfo->type == FT_UINT_BYTES);
- return hfinfo_format_bytes(scope, hfinfo,
- (guint8 *)fvalue_get(&fi->value), fvalue_length(&fi->value));
-}
-
guchar
proto_check_field_name(const gchar *field_name)
{