forked from osmocom/wireshark
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>
This commit is contained in:
parent
ef7e4c52f2
commit
b307ffe0f9
|
@ -979,6 +979,8 @@ libwireshark.so.0 libwireshark0 #MINVER#
|
||||||
proto_tree_add_ipxnet_format_value@Base 1.9.1
|
proto_tree_add_ipxnet_format_value@Base 1.9.1
|
||||||
proto_tree_add_item@Base 1.9.1
|
proto_tree_add_item@Base 1.9.1
|
||||||
proto_tree_add_item_new@Base 1.12.0~rc1
|
proto_tree_add_item_new@Base 1.12.0~rc1
|
||||||
|
proto_tree_add_item_ret_int@Base 1.9.4
|
||||||
|
proto_tree_add_item_ret_uint@Base 1.9.4
|
||||||
proto_tree_add_none_format@Base 1.9.1
|
proto_tree_add_none_format@Base 1.9.1
|
||||||
proto_tree_add_protocol_format@Base 1.9.1
|
proto_tree_add_protocol_format@Base 1.9.1
|
||||||
proto_tree_add_string@Base 1.9.1
|
proto_tree_add_string@Base 1.9.1
|
||||||
|
|
|
@ -1125,6 +1125,14 @@ protocol or field labels to the proto_tree:
|
||||||
proto_item*
|
proto_item*
|
||||||
proto_tree_add_item(tree, id, tvb, start, length, encoding);
|
proto_tree_add_item(tree, id, tvb, start, length, encoding);
|
||||||
|
|
||||||
|
proto_item*
|
||||||
|
proto_tree_add_item_ret_int(tree, id, tvb, start, length, encoding,
|
||||||
|
*retval);
|
||||||
|
|
||||||
|
proto_item*
|
||||||
|
proto_tree_add_item_ret_uint(tree, id, tvb, start, length, encoding,
|
||||||
|
*retval);
|
||||||
|
|
||||||
proto_item*
|
proto_item*
|
||||||
proto_tree_add_subtree(tree, tvb, start, length, idx, tree_item,
|
proto_tree_add_subtree(tree, tvb, start, length, idx, tree_item,
|
||||||
text);
|
text);
|
||||||
|
@ -1532,6 +1540,12 @@ Subarea Nodes. The user does not have to shift the value of the FID to
|
||||||
the high nibble of the byte ("sna.th.fid == 0xf0") as was necessary
|
the high nibble of the byte ("sna.th.fid == 0xf0") as was necessary
|
||||||
in the past.
|
in the past.
|
||||||
|
|
||||||
|
proto_tree_add_item_ret_XXX()
|
||||||
|
------------------------------
|
||||||
|
proto_tree_add_item_ret_XXX is used when you want the displayed value returned
|
||||||
|
for futher processing only integer and unsigned integer types up to 32 bits are
|
||||||
|
supported usage of proper FT_ is checked.
|
||||||
|
|
||||||
proto_tree_add_XXX_item()
|
proto_tree_add_XXX_item()
|
||||||
---------------------
|
---------------------
|
||||||
proto_tree_add_XXX_item is used when you wish to do no special formatting,
|
proto_tree_add_XXX_item is used when you wish to do no special formatting,
|
||||||
|
|
|
@ -2622,7 +2622,8 @@ static void
|
||||||
dissect_tcpopt_wscale(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
|
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_)
|
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_item *wscale_pi, *shift_pi, *gen_pi;
|
||||||
proto_tree *wscale_tree;
|
proto_tree *wscale_tree;
|
||||||
struct tcp_analysis *tcpd=NULL;
|
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);
|
proto_tree_add_item(wscale_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|
||||||
shift_pi = proto_tree_add_item(wscale_tree, hf_tcp_option_wscale_shift, tvb,
|
shift_pi = proto_tree_add_item_ret_uint(wscale_tree, hf_tcp_option_wscale_shift, tvb, offset, 1, ENC_BIG_ENDIAN, &shift);
|
||||||
offset, 1, ENC_BIG_ENDIAN);
|
|
||||||
shift = tvb_get_guint8(tvb, offset);
|
|
||||||
if (shift > 14) {
|
if (shift > 14) {
|
||||||
/* RFC 1323: "If a Window Scale option is received with a shift.cnt
|
/* 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
|
* 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);
|
proto_tree_add_item(ts_tree, hf_tcp_option_len, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|
||||||
proto_tree_add_item(ts_tree, hf_tcp_option_timestamp_tsval, tvb, offset,
|
proto_tree_add_item_ret_uint(ts_tree, hf_tcp_option_timestamp_tsval, tvb, offset,
|
||||||
4, ENC_BIG_ENDIAN);
|
4, ENC_BIG_ENDIAN, &ts_val);
|
||||||
ts_val = tvb_get_ntohl(tvb, offset);
|
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
proto_tree_add_item(ts_tree, hf_tcp_option_timestamp_tsecr, tvb, offset,
|
proto_tree_add_item_ret_uint(ts_tree, hf_tcp_option_timestamp_tsecr, tvb, offset,
|
||||||
4, ENC_BIG_ENDIAN);
|
4, ENC_BIG_ENDIAN, &ts_ecr);
|
||||||
ts_ecr = tvb_get_ntohl(tvb, offset);
|
|
||||||
/* offset += 4; */
|
/* offset += 4; */
|
||||||
|
|
||||||
proto_item_append_text(ti, "TSval %u, TSecr %u", ts_val, ts_ecr);
|
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 */
|
guint8 th_off_x2; /* combines th_off and th_x2 */
|
||||||
guint16 th_sum;
|
guint16 th_sum;
|
||||||
guint16 th_urp;
|
guint32 th_urp;
|
||||||
proto_tree *tcp_tree = NULL, *field_tree = NULL;
|
proto_tree *tcp_tree = NULL, *field_tree = NULL;
|
||||||
proto_item *ti = NULL, *tf, *hidden_item;
|
proto_item *ti = NULL, *tf, *hidden_item;
|
||||||
proto_item *options_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_ret_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, ENC_BIG_ENDIAN, &th_urp);
|
||||||
item = proto_tree_add_item(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, ENC_BIG_ENDIAN);
|
|
||||||
if (tcph->th_flags & TH_URG) {
|
if (tcph->th_flags & TH_URG) {
|
||||||
/* Export the urgent pointer, for the benefit of protocols such as
|
/* Export the urgent pointer, for the benefit of protocols such as
|
||||||
rlogin. */
|
rlogin. */
|
||||||
tcpinfo.urgent = TRUE;
|
tcpinfo.urgent = TRUE;
|
||||||
tcpinfo.urgent_pointer = th_urp;
|
tcpinfo.urgent_pointer = (guint16)th_urp;
|
||||||
tcp_info_append_uint(pinfo, "Urg", th_urp);
|
tcp_info_append_uint(pinfo, "Urg", th_urp);
|
||||||
} else {
|
} else {
|
||||||
tcpinfo.urgent = FALSE;
|
tcpinfo.urgent = FALSE;
|
||||||
|
|
79
epan/proto.c
79
epan/proto.c
|
@ -2071,6 +2071,85 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree,
|
||||||
return pi;
|
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,
|
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
|
||||||
and returns proto_item* */
|
and returns proto_item* */
|
||||||
proto_item *
|
proto_item *
|
||||||
|
|
37
epan/proto.h
37
epan/proto.h
|
@ -980,6 +980,43 @@ WS_DLL_PUBLIC proto_item *
|
||||||
proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
|
proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
|
||||||
const gint start, gint length, const guint encoding);
|
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.
|
/** (DEPRECATED) Add a text-only node to a proto_tree.
|
||||||
@param tree the tree to append this item to
|
@param tree the tree to append this item to
|
||||||
@param tvb the tv buffer of the current data
|
@param tvb the tv buffer of the current data
|
||||||
|
|
|
@ -1587,7 +1587,7 @@ sub check_proto_tree_add_XXX_encoding($$)
|
||||||
$args =~ s/\(.*\)//sg;
|
$args =~ s/\(.*\)//sg;
|
||||||
|
|
||||||
if ($args =~ /,\s*ENC_/xos) {
|
if ($args =~ /,\s*ENC_/xos) {
|
||||||
if (!($func =~ /proto_tree_add_(time|item|bitmask|bits_item|bits_ret_val)/xos)
|
if (!($func =~ /proto_tree_add_(time|item|bitmask|bits_item|bits_ret_val|item_ret_int|item_ret_uint)/xos)
|
||||||
) {
|
) {
|
||||||
print STDERR "Error: ".$filename." uses $func with ENC_*.\n";
|
print STDERR "Error: ".$filename." uses $func with ENC_*.\n";
|
||||||
$errorCount++;
|
$errorCount++;
|
||||||
|
|
Loading…
Reference in New Issue