forked from osmocom/wireshark
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:
parent
32d31e55ae
commit
337f49243f
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
277
epan/proto.c
277
epan/proto.c
|
@ -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* */
|
||||||
|
|
|
@ -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* */
|
||||||
|
|
Loading…
Reference in New Issue