Add ptvcursor APIs that return the values it retrieves

ptvcursor_add_ret_uint
ptvcursor_add_ret_int
ptvcursor_add_ret_string
ptvcursor_add_ret_boolean

Change-Id: I41fa91b1ab805778d34a61215830b12a1331e864
Reviewed-on: https://code.wireshark.org/review/23895
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Michael Mann 2017-10-13 00:28:50 -04:00 committed by Anders Broman
parent 32d31e55ae
commit 337f49243f
4 changed files with 296 additions and 24 deletions

View File

@ -1223,6 +1223,10 @@ libwireshark.so.0 libwireshark0 #MINVER#
protocols_module@Base 1.9.1 protocols_module@Base 1.9.1
ptvcursor_add@Base 1.9.1 ptvcursor_add@Base 1.9.1
ptvcursor_add_no_advance@Base 1.9.1 ptvcursor_add_no_advance@Base 1.9.1
ptvcursor_add_ret_boolean@Base 2.5.0
ptvcursor_add_ret_int@Base 2.5.0
ptvcursor_add_ret_string@Base 2.5.0
ptvcursor_add_ret_uint@Base 2.5.0
ptvcursor_add_text_with_subtree@Base 1.9.1 ptvcursor_add_text_with_subtree@Base 1.9.1
ptvcursor_add_with_subtree@Base 1.9.1 ptvcursor_add_with_subtree@Base 1.9.1
ptvcursor_advance@Base 1.9.1 ptvcursor_advance@Base 1.9.1

View File

@ -3529,6 +3529,22 @@ the ptvcursor advances its cursor so the next call to ptvcursor_add
starts where this call finished. The 'encoding' parameter is relevant for starts where this call finished. The 'encoding' parameter is relevant for
certain type of fields (See above under proto_tree_add_item()). certain type of fields (See above under proto_tree_add_item()).
proto_item*
ptvcursor_add_ret_uint(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, guint32 *retval);
Like ptvcursor_add, but returns uint value retreived
proto_item*
ptvcursor_add_ret_int(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, gint32 *retval);
Like ptvcursor_add, but returns int value retreived
proto_item*
ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, wmem_allocator_t *scope, const guint8 **retval);
Like ptvcursor_add, but returns string retreived
proto_item*
ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, gboolean *retval);
Like ptvcursor_add, but returns boolean value retreived
proto_item* proto_item*
ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length, const guint encoding) ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length, const guint encoding)
Like ptvcursor_add, but does not advance the internal cursor. Like ptvcursor_add, but does not advance the internal cursor.

View File

@ -2086,6 +2086,32 @@ tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
} }
} }
/*
* Validates that field length bytes are available starting from
* start (pos/neg). Throws an exception if they aren't.
*/
static void
test_length(header_field_info *hfinfo, tvbuff_t *tvb,
gint start, gint length, const guint encoding)
{
gint size = length;
if (!tvb)
return;
if ((hfinfo->type == FT_STRINGZ) ||
((encoding & ENC_VARINT_PROTOBUF) && (IS_FT_UINT(hfinfo->type) || IS_FT_UINT(hfinfo->type)))) {
/* If we're fetching until the end of the TVB, only validate
* that the offset is within range.
*/
if (length == -1)
size = 0;
}
tvb_ensure_bytes_exist(tvb, start, size);
}
/* Add an item to a proto_tree, using the text label registered to that item; /* 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. */ the item is extracted from the tvbuff handed to it. */
static proto_item * static proto_item *
@ -2678,6 +2704,233 @@ proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
return proto_tree_add_node(tree, new_fi); return proto_tree_add_node(tree, new_fi);
} }
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
* and returns proto_item* and uint value retreived*/
proto_item *
ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, gint length,
const guint encoding, guint32 *retval)
{
field_info *new_fi;
header_field_info *hfinfo;
gint item_length;
int offset;
guint32 value;
offset = ptvc->offset;
PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
switch (hfinfo->type){
case FT_CHAR:
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
break;
default:
REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
"field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
hfinfo->abbrev));
}
get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
/* I believe it's ok if this is called with a NULL tree */
/* XXX - modify if we ever support EBCDIC FT_CHAR */
value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
if (retval) {
*retval = value;
if (hfinfo->bitmask) {
/* Mask out irrelevant portions */
*retval &= (guint32)(hfinfo->bitmask);
/* Shift bits */
*retval >>= hfinfo_bitshift(hfinfo);
}
}
ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
item_length, encoding);
CHECK_FOR_NULL_TREE(ptvc->tree);
/* Coast clear. Try and fake it */
TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
offset, length, encoding);
}
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
* and returns proto_item* and int value retreived*/
proto_item *
ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, gint length,
const guint encoding, gint32 *retval)
{
field_info *new_fi;
header_field_info *hfinfo;
gint item_length;
int offset;
guint32 value;
offset = ptvc->offset;
PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
switch (hfinfo->type){
case FT_INT8:
case FT_INT16:
case FT_INT24:
case FT_INT32:
break;
default:
REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
"field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
hfinfo->abbrev));
}
get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
/* I believe it's ok if this is called with a NULL tree */
/* XXX - modify if we ever support EBCDIC FT_CHAR */
value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
if (retval) {
gint no_of_bits;
*retval = value;
if (hfinfo->bitmask) {
/* Mask out irrelevant portions */
*retval &= (guint32)(hfinfo->bitmask);
/* Shift bits */
*retval >>= hfinfo_bitshift(hfinfo);
}
no_of_bits = ws_count_ones(hfinfo->bitmask);
*retval = ws_sign_ext32(*retval, no_of_bits);
}
ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
item_length, encoding);
CHECK_FOR_NULL_TREE(ptvc->tree);
/* Coast clear. Try and fake it */
TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
offset, length, encoding);
}
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
* and returns proto_item* and string value retreived */
proto_item*
ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, wmem_allocator_t *scope, const guint8 **retval)
{
header_field_info *hfinfo;
field_info *new_fi;
const guint8 *value;
gint item_length;
int offset;
offset = ptvc->offset;
PROTO_REGISTRAR_GET_NTH(hf, hfinfo);
switch (hfinfo->type){
case FT_STRING:
value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
break;
case FT_STRINGZ:
value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
break;
case FT_UINT_STRING:
value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
break;
case FT_STRINGZPAD:
value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
break;
default:
REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
"field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, or FT_STRINGZPAD",
hfinfo->abbrev));
}
if (retval)
*retval = value;
ptvc->offset += item_length;
CHECK_FOR_NULL_TREE(ptvc->tree);
TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
offset, length, encoding);
}
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
* and returns proto_item* and boolean value retreived */
proto_item*
ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, gint length, const guint encoding, gboolean *retval)
{
header_field_info *hfinfo;
field_info *new_fi;
gint item_length;
int offset;
guint64 value, bitval;
offset = ptvc->offset;
PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
if (hfinfo->type != FT_BOOLEAN) {
REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
"field %s is not of type FT_BOOLEAN", hfinfo->abbrev));
}
/* length validation for native number encoding caught by get_uint64_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_item_ret_uint",
length));
if (encoding & ENC_STRING) {
REPORT_DISSECTOR_BUG("wrong encoding");
}
get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
/* I believe it's ok if this is called with a NULL tree */
value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
if (retval) {
bitval = value;
if (hfinfo->bitmask) {
/* Mask out irrelevant portions */
bitval &= hfinfo->bitmask;
}
*retval = (bitval != 0);
}
ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
item_length, encoding);
CHECK_FOR_NULL_TREE(ptvc->tree);
TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
offset, length, encoding);
}
proto_item * proto_item *
proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
const gint start, gint length, const guint encoding, guint64 *retval) const gint start, gint length, const guint encoding, guint64 *retval)
@ -2906,30 +3159,6 @@ proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
tvb, start, length, encoding, scope, retval, &length); tvb, start, length, encoding, scope, retval, &length);
} }
/*
* Validates that field length bytes are available starting from
* start (pos/neg). Throws an exception if they aren't.
*/
static void
test_length(header_field_info *hfinfo, tvbuff_t *tvb,
gint start, gint length, const guint encoding)
{
gint size = length;
if (!tvb)
return;
if ((hfinfo->type == FT_STRINGZ) ||
((encoding & ENC_VARINT_PROTOBUF) && (IS_FT_UINT(hfinfo->type) || IS_FT_UINT(hfinfo->type)))) {
/* If we're fetching until the end of the TVB, only validate
* that the offset is within range.
*/
if (length == -1)
size = 0;
}
tvb_ensure_bytes_exist(tvb, start, size);
}
/* 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* */

View File

@ -45,6 +45,29 @@ WS_DLL_PUBLIC
proto_item* proto_item*
ptvcursor_add(ptvcursor_t* ptvc, int hf, gint length, const guint encoding); ptvcursor_add(ptvcursor_t* ptvc, int hf, gint length, const guint encoding);
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
* and returns proto_item* and uint value retreived*/
WS_DLL_PUBLIC
proto_item*
ptvcursor_add_ret_uint(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, guint32 *retval);
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
* and returns proto_item* and int value retreived */
WS_DLL_PUBLIC
proto_item*
ptvcursor_add_ret_int(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, gint32 *retval);
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
* and returns proto_item* and string value retreived */
WS_DLL_PUBLIC
proto_item*
ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, wmem_allocator_t *scope, const guint8 **retval);
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
* and returns proto_item* and boolean value retreived */
WS_DLL_PUBLIC
proto_item*
ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, gboolean *retval);
/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
* offset, and returns proto_item* */ * offset, and returns proto_item* */