summaryrefslogtreecommitdiff
path: root/epan
diff options
context:
space:
mode:
authorAndersBroman <anders.broman@ericsson.com>2015-02-13 09:34:16 +0100
committerAnders Broman <a.broman58@gmail.com>2015-03-19 16:06:18 +0000
commitb307ffe0f990860284f6e2be4f7a8f01fa822d36 (patch)
treeed93209968eefe4727e3318440702ae0b8884c9e /epan
parentef7e4c52f2daf5ce27b9d311900f7a34ea7c71a3 (diff)
downloadwireshark-b307ffe0f990860284f6e2be4f7a8f01fa822d36.tar.gz
Implement proto_tree_add_item_ret_int() and proto_tree_add_item_ret_uint() which
works as proto_tree_add_item(), but also returns the value of (u)ints of 8,16,24 and 32 bits length in a 32 bit variable. It's based on Hadriels previous work. Change-Id: If3b4b8588b63251f1ee9b954a202acde7c02ce86 Reviewed-on: https://code.wireshark.org/review/7230 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-tcp.c25
-rw-r--r--epan/proto.c79
-rw-r--r--epan/proto.h37
3 files changed, 127 insertions, 14 deletions
diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c
index a478010e83..c47c4ca05f 100644
--- a/epan/dissectors/packet-tcp.c
+++ b/epan/dissectors/packet-tcp.c
@@ -2622,7 +2622,8 @@ static void
dissect_tcpopt_wscale(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
int offset, guint optlen _U_, packet_info *pinfo, proto_tree *opt_tree, void *data _U_)
{
- guint8 val, shift;
+ guint8 val;
+ guint32 shift;
proto_item *wscale_pi, *shift_pi, *gen_pi;
proto_tree *wscale_tree;
struct tcp_analysis *tcpd=NULL;
@@ -2637,9 +2638,7 @@ dissect_tcpopt_wscale(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
proto_tree_add_item(wscale_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
- shift_pi = proto_tree_add_item(wscale_tree, hf_tcp_option_wscale_shift, tvb,
- offset, 1, ENC_BIG_ENDIAN);
- shift = tvb_get_guint8(tvb, offset);
+ shift_pi = proto_tree_add_item_ret_uint(wscale_tree, hf_tcp_option_wscale_shift, tvb, offset, 1, ENC_BIG_ENDIAN, &shift);
if (shift > 14) {
/* RFC 1323: "If a Window Scale option is received with a shift.cnt
* value exceeding 14, the TCP should log the error but use 14 instead
@@ -2785,14 +2784,12 @@ dissect_tcpopt_timestamp(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
proto_tree_add_item(ts_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
- proto_tree_add_item(ts_tree, hf_tcp_option_timestamp_tsval, tvb, offset,
- 4, ENC_BIG_ENDIAN);
- ts_val = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item_ret_uint(ts_tree, hf_tcp_option_timestamp_tsval, tvb, offset,
+ 4, ENC_BIG_ENDIAN, &ts_val);
offset += 4;
- proto_tree_add_item(ts_tree, hf_tcp_option_timestamp_tsecr, tvb, offset,
- 4, ENC_BIG_ENDIAN);
- ts_ecr = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_item_ret_uint(ts_tree, hf_tcp_option_timestamp_tsecr, tvb, offset,
+ 4, ENC_BIG_ENDIAN, &ts_ecr);
/* offset += 4; */
proto_item_append_text(ti, "TSval %u, TSecr %u", ts_val, ts_ecr);
@@ -4307,7 +4304,7 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint8 th_off_x2; /* combines th_off and th_x2 */
guint16 th_sum;
- guint16 th_urp;
+ guint32 th_urp;
proto_tree *tcp_tree = NULL, *field_tree = NULL;
proto_item *ti = NULL, *tf, *hidden_item;
proto_item *options_item;
@@ -4847,13 +4844,13 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
}
- th_urp = tvb_get_ntohs(tvb, offset + 18);
- item = proto_tree_add_item(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, ENC_BIG_ENDIAN);
+ item = proto_tree_add_item_ret_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, ENC_BIG_ENDIAN, &th_urp);
+
if (tcph->th_flags & TH_URG) {
/* Export the urgent pointer, for the benefit of protocols such as
rlogin. */
tcpinfo.urgent = TRUE;
- tcpinfo.urgent_pointer = th_urp;
+ tcpinfo.urgent_pointer = (guint16)th_urp;
tcp_info_append_uint(pinfo, "Urg", th_urp);
} else {
tcpinfo.urgent = FALSE;
diff --git a/epan/proto.c b/epan/proto.c
index cbc761c0e5..e48566363a 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -2071,6 +2071,85 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
return pi;
}
+
+/* ok, so this is going to be ugly, but repeating this code in multiple functions
+is also bad mojo, so I'm picking the lesser of two evils I think */
+#define PROTO_TREE_ADD_XXX_ITEM(ctype,gtype,hfinfo) \
+ \
+ DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!"); \
+ /* length validation for native number encoding caught by get_uint_value() */ \
+ /* length has to be -1 or > 0 regardless of encoding */ \
+ if (length < -1 || length == 0) \
+ REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(), \
+ "Invalid length %d passed to proto_tree_add_" #gtype "_item", \
+ length)); \
+ \
+ if (encoding & ENC_STRING) { \
+ REPORT_DISSECTOR_BUG("wrong encoding"); \
+ } \
+ /* I believe it's ok if this is called with a NULL tree */ \
+ value = get_ ## ctype ## _value(tree, tvb, start, length, encoding); \
+ \
+ if (retval) \
+ *retval = value; \
+ \
+ TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo); \
+ \
+ new_fi = new_field_info(tree, hfinfo, tvb, start, length); \
+ \
+ if (new_fi == NULL) \
+ return NULL; \
+ \
+ proto_tree_set_uint(new_fi, value); \
+ \
+ FI_SET_FLAG(new_fi, \
+ (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN); \
+ \
+ return proto_tree_add_node(tree, new_fi)
+
+
+proto_item *
+proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
+const gint start, gint length, const guint encoding,
+gint32 *retval)
+{
+ header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
+ field_info *new_fi;
+ guint32 value;
+
+ switch (hfinfo->type){
+ case FT_INT8:
+ case FT_INT16:
+ case FT_INT24:
+ case FT_INT32:
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ }
+ PROTO_TREE_ADD_XXX_ITEM(int, gint32, hfinfo);
+}
+
+proto_item *
+proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
+const gint start, gint length, const guint encoding,
+guint32 *retval)
+{
+ header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
+ field_info *new_fi;
+ guint32 value;
+
+ switch (hfinfo->type){
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ }
+ PROTO_TREE_ADD_XXX_ITEM(int, gint32, hfinfo);
+}
+
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
and returns proto_item* */
proto_item *
diff --git a/epan/proto.h b/epan/proto.h
index f0222e01f8..45fb0506ba 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -980,6 +980,43 @@ WS_DLL_PUBLIC proto_item *
proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
const gint start, gint length, const guint encoding);
+/** Add an item to a proto_tree, using the text label registered to that item.
+The item is extracted from the tvbuff handed to it, and the retrieved
+value is also set to *retval so the caller gets it back for other uses.
+
+This function retrieves the value even if the passed-in tree param is NULL,
+so that it can be used by dissectors at all times to both get the value
+and set the tree item to it.
+
+Like other proto_tree_add functions, if there is a tree and the value cannot
+be decoded from the tvbuff, then an expert info error is reported.
+
+This function accepts ENC_LITTLE_ENDIAN and ENC_BIG_ENDIAN for native number
+encoding in the tvbuff
+
+The length argument must
+be set to the appropriate size of the native type as in other proto_add routines.
+
+Integers of 8, 16, 24 and 32 bits can be retreived with these functions.
+
+@param tree the tree to append this item to
+@param hfindex field
+@param tvb the tv buffer of the current data
+@param start start of data in tvb (cannot be negative)
+@param length length of data in tvb (for strings can be -1 for remaining)
+@param encoding data encoding (e.g, ENC_LITTLE_ENDIAN, ENC_BIG_ENDIAN, ENC_ASCII|ENC_STRING, etc.)
+@param[out] retval points to a gint/guint 8/16/32/64 or gfloat/gdouble which will be set
+@param[out] err gets set to 0 if no failure, else the errno code (EDOM or ERANGE)
+@return the newly created item, and value is set to the decoded value
+*/
+WS_DLL_PUBLIC proto_item *
+proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
+const gint start, gint length, const guint encoding, gint32 *retval);
+
+WS_DLL_PUBLIC proto_item *
+proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
+const gint start, gint length, const guint encoding, guint32 *retval);
+
/** (DEPRECATED) Add a text-only node to a proto_tree.
@param tree the tree to append this item to
@param tvb the tv buffer of the current data