aboutsummaryrefslogtreecommitdiffstats
path: root/epan/proto.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-02-01 15:19:10 -0800
committerGuy Harris <guy@alum.mit.edu>2016-02-01 23:20:12 +0000
commitb9fb2ceb88b0904e95b2931fbf2efd6222f56285 (patch)
treecc9ed34dea4bb981ce7c997c3e19cfc9de6c8d01 /epan/proto.c
parenta53ab9dfcc87ec817467a2a9c2259b0a70a1dd78 (diff)
Add heuristic dissectors for the variable part of COTP CR and CC PDUs.
Add tables for heuristic dissectors, and add dissectors for the stuff Microsoft puts there for RDP; they're violating the COTP spec, but I guess they're stuck because they're using TP0, which doesn't support user data. While we're at it, add variants of proto_tree_add_bitmask() and proto_tree_add_bitmask_flags() that return the bitmask, for use by callers. A side-effect of the change is that the proto_tree_add_bitmask routines no longer treat the encoding as a Boolean, so we have to pass ENC_LITTLE_ENDIAN or ENC_BIG_ENDIAN, not just some non-zero or zero value. Do so. Rename ositp_decode_CC() to ositp_decode_CR_CC(), to note that it decodes both CR and CC PDUs. Bug: 2626 Change-Id: If5fa2a6dfecd9eb99c1cb8104f2ebceccf1e57c2 Reviewed-on: https://code.wireshark.org/review/13648 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/proto.c')
-rw-r--r--epan/proto.c225
1 files changed, 112 insertions, 113 deletions
diff --git a/epan/proto.c b/epan/proto.c
index 0100c06cba..7c7c4b9891 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -1367,12 +1367,6 @@ get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const
return value;
}
-/*
- * NOTE: to support code written when proto_tree_add_item() took a
- * gboolean as its last argument, with FALSE meaning "big-endian"
- * and TRUE meaning "little-endian", we treat any non-zero value of
- * "encoding" as meaning "little-endian".
- */
static inline guint64
get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
{
@@ -1435,12 +1429,6 @@ get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, con
return value;
}
-/*
- * NOTE: to support code written when proto_tree_add_item() took a
- * gboolean as its last argument, with FALSE meaning "big-endian"
- * and TRUE meaning "little-endian", we treat any non-zero value of
- * "encoding" as meaning "little-endian".
- */
static gint32
get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
{
@@ -8716,71 +8704,25 @@ proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
return filter;
}
-/* This function is common code for both proto_tree_add_bitmask() and
- * proto_tree_add_bitmask_text() functions.
+/* This function is common code for all proto_tree_add_bitmask... functions.
*/
-/* NOTE: to support code written when proto_tree_add_bitmask() and
- * proto_tree_add_bitmask_text took a
- * gboolean as its last argument, with FALSE meaning "big-endian"
- * and TRUE meaning "little-endian", we treat any non-zero value of
- * "encoding" as meaning "little-endian".
- */
static gboolean
proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
const int len, const gint ett, const int **fields,
- const guint encoding, const int flags,
- gboolean first, gboolean use_parent_tree, gboolean use_value,
+ const int flags, gboolean first,
+ gboolean use_parent_tree,
proto_tree* tree, guint64 value)
{
+ guint bitshift;
guint64 available_bits = 0;
guint64 tmpval;
header_field_info *hf;
- switch (len) {
- case 1:
- if (use_value == FALSE)
- value = tvb_get_guint8(tvb, offset);
- available_bits = 0xFF;
- break;
- case 2:
- if (use_value == FALSE)
- value = encoding ? tvb_get_letohs(tvb, offset) : tvb_get_ntohs(tvb, offset);
- available_bits = 0xFFFF;
- break;
- case 3:
- if (use_value == FALSE)
- value = encoding ? tvb_get_letoh24(tvb, offset) : tvb_get_ntoh24(tvb, offset);
- available_bits = 0xFFFFFF;
- break;
- case 4:
- if (use_value == FALSE)
- value = encoding ? tvb_get_letohl(tvb, offset) : tvb_get_ntohl(tvb, offset);
- available_bits = 0xFFFFFFFF;
- break;
- case 5:
- if (use_value == FALSE)
- value = encoding ? tvb_get_letoh40(tvb, offset) : tvb_get_ntoh40(tvb, offset);
- available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFF);
- break;
- case 6:
- if (use_value == FALSE)
- value = encoding ? tvb_get_letoh48(tvb, offset) : tvb_get_ntoh48(tvb, offset);
- available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFF);
- break;
- case 7:
- if (use_value == FALSE)
- value = encoding ? tvb_get_letoh56(tvb, offset) : tvb_get_ntoh56(tvb, offset);
- available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFF);
- break;
- case 8:
- if (use_value == FALSE)
- value = encoding ? tvb_get_letoh64(tvb, offset) : tvb_get_ntoh64(tvb, offset);
- available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
- break;
- default:
- g_assert_not_reached();
- }
+ if (len <= 0 || len > 8)
+ g_assert_not_reached();
+ bitshift = (8 - (guint)len)*8;
+ available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
if (use_parent_tree == FALSE)
tree = proto_item_add_subtree(item, ett);
@@ -8797,43 +8739,36 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
continue;
}
- if (use_value)
- {
- switch (hf->type) {
- case FT_INT8:
- case FT_UINT8:
- case FT_INT16:
- case FT_UINT16:
- case FT_INT24:
- case FT_UINT24:
- case FT_INT32:
- case FT_UINT32:
- proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
- break;
+ switch (hf->type) {
+ case FT_INT8:
+ case FT_UINT8:
+ case FT_INT16:
+ case FT_UINT16:
+ case FT_INT24:
+ case FT_UINT24:
+ case FT_INT32:
+ case FT_UINT32:
+ proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
+ break;
- case FT_INT40:
- case FT_UINT40:
- case FT_INT48:
- case FT_UINT48:
- case FT_INT56:
- case FT_UINT56:
- case FT_INT64:
- case FT_UINT64:
- proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
- break;
+ case FT_INT40:
+ case FT_UINT40:
+ case FT_INT48:
+ case FT_UINT48:
+ case FT_INT56:
+ case FT_UINT56:
+ case FT_INT64:
+ case FT_UINT64:
+ proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
+ break;
- case FT_BOOLEAN:
- proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
- break;
+ case FT_BOOLEAN:
+ proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
+ break;
- default:
- DISSECTOR_ASSERT_NOT_REACHED();
- break;
- }
- }
- else
- {
- proto_tree_add_item(tree, **fields, tvb, offset, len, encoding);
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ break;
}
if (flags & BMT_NO_APPEND) {
fields++;
@@ -8921,11 +8856,38 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
}
/* This function will dissect a sequence of bytes that describe a
+ * bitmask and supply the value of that sequence through a pointer.
+ * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
+ * to be dissected.
+ * This field will form an expansion under which the individual fields of the
+ * bitmask is dissected and displayed.
+ * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
+ *
+ * fields is an array of pointers to int that lists all the fields of the
+ * bitmask. These fields can be either of the type FT_BOOLEAN for flags
+ * or another integer of the same type/size as hf_hdr with a mask specified.
+ * This array is terminated by a NULL entry.
+ *
+ * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
+ * FT_integer fields that have a value_string attached will have the
+ * matched string displayed on the expansion line.
+ */
+proto_item *
+proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
+ const guint offset, const int hf_hdr,
+ const gint ett, const int **fields,
+ const guint encoding, guint64 *retval)
+{
+ return proto_tree_add_bitmask_with_flags_ret_uint64(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, retval);
+}
+
+/* This function will dissect a sequence of bytes that describe a
* bitmask.
- * hf_hdr is a 8/16/24/32 bit integer that describes the bitmask to be dissected.
+ * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
+ * to be dissected.
* This field will form an expansion under which the individual fields of the
* bitmask is dissected and displayed.
- * This field must be of the type FT_[U]INT{8|16|24|32}.
+ * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
*
* fields is an array of pointers to int that lists all the fields of the
* bitmask. These fields can be either of the type FT_BOOLEAN for flags
@@ -8945,7 +8907,35 @@ proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
}
-/* The same as proto_tree_add_bitmask(), but uses user-supplied flags to determine
+/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
+ * what data is appended to the header.
+ */
+proto_item *
+proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
+ const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
+ guint64 *retval)
+{
+ proto_item *item = NULL;
+ header_field_info *hf;
+ int len;
+ guint64 value;
+
+ PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
+ DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
+ len = ftype_length(hf->type);
+ value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
+
+ if (parent_tree) {
+ item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
+ proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
+ flags, FALSE, FALSE, NULL, value);
+ }
+
+ *retval = value;
+ return item;
+}
+
+/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
* what data is appended to the header.
*/
proto_item *
@@ -8955,15 +8945,17 @@ proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const
proto_item *item = NULL;
header_field_info *hf;
int len;
+ guint64 value;
PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
- len = ftype_length(hf->type);
if (parent_tree) {
+ len = ftype_length(hf->type);
item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
- proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields, encoding,
- flags, FALSE, FALSE, FALSE, NULL, 0);
+ value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
+ proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
+ flags, FALSE, FALSE, NULL, value);
}
return item;
@@ -8999,8 +8991,7 @@ proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb,
item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
- 0, flags, FALSE, FALSE, TRUE, NULL, value);
-
+ flags, FALSE, FALSE, NULL, value);
}
return item;
@@ -9011,9 +9002,13 @@ void
proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
const int len, const int **fields, const guint encoding)
{
- if (tree)
+ guint64 value;
+
+ if (tree) {
+ value = get_uint64_value(tree, tvb, offset, len, encoding);
proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
- encoding, BMT_NO_APPEND, FALSE, TRUE, FALSE, tree, 0);
+ BMT_NO_APPEND, FALSE, TRUE, tree, value);
+ }
}
@@ -9039,6 +9034,7 @@ proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
guint decodable_len;
guint decodable_offset;
guint32 decodable_value;
+ guint64 value;
PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
@@ -9070,8 +9066,9 @@ proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
}
if (item) {
+ value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
- ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, FALSE, NULL, 0);
+ ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
}
return item;
@@ -9086,11 +9083,13 @@ proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
const guint encoding, const int flags)
{
proto_item *item = NULL;
+ guint64 value;
if (parent_tree) {
item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
- if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields, encoding,
- flags, TRUE, FALSE, FALSE, NULL, 0) && fallback) {
+ value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
+ if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
+ flags, TRUE, FALSE, NULL, value) && fallback) {
/* Still at first item - append 'fallback' text if any */
proto_item_append_text(item, "%s", fallback);
}