#include <ctype.h>
#include <glib.h>
#include <float.h>
+#include <wsutil/swar.h>
#include "packet.h"
#include "ptvcursor.h"
gint offset;
};
-/* Candidates for assembler */
-static int
-wrs_count_bitshift(const guint32 bitmask)
-{
- int bitshift = 0;
-
- while ((bitmask & (1 << bitshift)) == 0)
- bitshift++;
- return bitshift;
-}
-
#define cVALS(x) (const value_string*)(x)
/** See inlined comments.
static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
static void fill_label_boolean(field_info *fi, gchar *label_str);
-static void fill_label_bitfield(field_info *fi, gchar *label_str);
+static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
+static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
proto_tree_add_node(proto_tree *tree, field_info *fi);
static void
-get_hfi_and_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
- gint *item_length);
+get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
+ gint *item_length);
static field_info *
new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
static proto_item *
proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
- gint start, gint *length, field_info **pfi);
+ gint start, gint *length);
static void
proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
static void
proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
static void
+proto_tree_set_vines(field_info *fi, const guint8* value);
+static void
+proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
+static void
proto_tree_set_ether(field_info *fi, const guint8* value);
static void
proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
const char *short_name; /* short description */
const char *filter_name; /* name of this protocol in filters */
int proto_id; /* field ID for this protocol */
- GList *fields; /* fields for this protocol */
- GList *last_field; /* pointer to end of list of fields */
+ GSList *fields; /* fields for this protocol */
+ GSList *last_field; /* pointer to end of list of fields */
gboolean is_enabled; /* TRUE if protocol is enabled */
gboolean can_toggle; /* TRUE if is_enabled can be changed */
gboolean is_private; /* TRUE is protocol is private */
guint32 allocated_len;
header_field_info **hfi;
} gpa_hfinfo_t;
-gpa_hfinfo_t gpa_hfinfo;
+
+static gpa_hfinfo_t gpa_hfinfo;
/* Balanced tree of abbreviations and IDs */
static GTree *gpa_name_tree = NULL;
same_name_hfinfo = (header_field_info*)data;
}
-/* Points to the first element of an array of Booleans, indexed by
+/* Points to the first element of an array of bits, indexed by
a subtree item type; that array element is TRUE if subtrees of
an item of that type are to be expanded. */
-gboolean *tree_is_expanded;
+static guint32 *tree_is_expanded;
/* Number of elements in that array. */
int num_tree_types;
/* We've assigned all the subtree type values; allocate the array
for them, and zero it out. */
- tree_is_expanded = g_new0(gboolean, num_tree_types);
+ tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
}
void
DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
g_slice_free(header_field_info, hfinfo);
- g_list_free(protocol->fields);
+ g_slist_free(protocol->fields);
protocols = g_list_remove(protocols, protocol);
g_free(protocol);
}
}
-/* Finds a record in the hf_info_records array by id. */
+/* Finds a record in the hfinfo array by id. */
header_field_info *
proto_registrar_get_nth(guint hfindex)
{
g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
}
-/* Finds a record in the hf_info_records array by name.
+/* Finds a record in the hfinfo array by name.
* If it fails to find it in the already registered fields,
* it tries to find and call an initializer in the prefixes
* table and if so it looks again.
proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
{
proto_item *pi;
- field_info *new_fi;
if (tree == NULL)
return NULL;
- pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length, &new_fi);
+ pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
return pi;
}
/* We could probably get away with changing is_error to a minimum length value. */
static void
report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
- tree_data_t *tree_data = PTREE_DATA(tree);
- field_info *fi_save = tree_data->fi_tmp;
+ if (tree) {
+ tree_data_t *tree_data = PTREE_DATA(tree);
+ field_info *fi_save = tree_data->fi_tmp;
- /* Keep the current item from getting freed by proto_tree_new_item. */
- tree_data->fi_tmp = NULL;
+ /* Keep the current item from getting freed by proto_tree_new_item. */
+ tree_data->fi_tmp = NULL;
- expert_add_info_format(NULL, tree, PI_MALFORMED, is_error ? PI_ERROR : PI_WARN, "Trying to fetch %s with length %d", descr, length);
+ expert_add_info_format(NULL, tree, PI_MALFORMED, is_error ? PI_ERROR : PI_WARN, "Trying to fetch %s with length %d", descr, length);
- tree_data->fi_tmp = fi_save;
+ tree_data->fi_tmp = fi_save;
+ }
if (is_error) {
THROW(ReportedBoundsError);
}
}
-/*
- * 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 guint32
get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
{
break;
case 2:
- value = encoding ? tvb_get_letohs(tvb, offset)
- : tvb_get_ntohs(tvb, offset);
+ value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
+ : tvb_get_ntohs(tvb, offset);
break;
case 3:
- value = encoding ? tvb_get_letoh24(tvb, offset)
- : tvb_get_ntoh24(tvb, offset);
+ value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
+ : tvb_get_ntoh24(tvb, offset);
break;
case 4:
- value = encoding ? tvb_get_letohl(tvb, offset)
- : tvb_get_ntohl(tvb, offset);
+ value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
+ : tvb_get_ntohl(tvb, offset);
break;
default:
value = 0;
} else {
length_error = FALSE;
- value = encoding ? tvb_get_letohl(tvb, offset)
- : tvb_get_ntohl(tvb, offset);
+ value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
+ : tvb_get_ntohl(tvb, offset);
}
report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
break;
report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
}
proto_tree_set_ipxnet(new_fi,
- get_uint_value(tree, tvb, start, FT_IPXNET_LEN, FALSE));
+ get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
break;
case FT_IPv6:
case FT_AX25:
if (length != 7) {
length_error = length < 7 ? TRUE : FALSE;
- expert_add_info_format(NULL, tree, PI_MALFORMED, PI_ERROR, "Trying to fetch an AX.25 address with length %d", length);
- THROW(ReportedBoundsError);
+ report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
}
proto_tree_set_ax25_tvb(new_fi, tvb, start);
break;
+ case FT_VINES:
+ if (length != VINES_ADDR_LEN) {
+ length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
+ report_type_length_mismatch(tree, "a Vines address", length, length_error);
+ }
+ proto_tree_set_vines_tvb(new_fi, tvb, start);
+ break;
+
case FT_ETHER:
if (length != FT_ETHER_LEN) {
length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
offset = ptvc->offset;
PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
- get_hfi_and_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
+ get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
ptvc->offset += length;
if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
/*
*/
static void
test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb,
- gint start, gint length, gboolean little_endian)
+ gint start, gint length, const guint encoding)
{
gint size = length;
if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
guint32 n;
- n = get_uint_value(tree, tvb, start, length, little_endian);
+ n = get_uint_value(tree, tvb, start, length, encoding);
if (n > size + n) {
/* If n > size + n then we have an integer overflow, so
* set size to -1, which will force the
else {
size += n;
}
+ } else if (hfinfo->type == FT_STRINGZ) {
+ /* 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;
the item is extracted from the tvbuff handed to it. */
proto_item *
-proto_tree_add_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
+proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
const gint start, gint length, const guint encoding)
{
field_info *new_fi;
- header_field_info *hfinfo;
gint item_length;
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
- get_hfi_and_length(hfinfo, tvb, start, &length, &item_length);
+ DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
+
+ get_hfi_length(hfinfo, tvb, start, &length, &item_length);
test_length(hfinfo, tree, tvb, start, item_length, encoding);
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
}
+proto_item *
+proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
+ const gint start, gint length, const guint encoding)
+{
+ return proto_tree_add_item_new(tree, proto_registrar_get_nth(hfindex), tvb, start, length, encoding);
+}
+
/* Add a FT_NONE to a proto_tree */
proto_item *
proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
proto_item *pi;
va_list ap;
header_field_info *hfinfo;
- field_info *new_fi;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_NONE);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
TRY_TO_FAKE_THIS_REPR(pi);
{
proto_item *pi;
va_list ap;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
- proto_tree_set_protocol_tvb(new_fi, (start == 0 ? tvb : tvb_new_subset(tvb, start, length, length)));
+ proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset(tvb, start, length, length)));
TRY_TO_FAKE_THIS_REPR(pi);
gint length, const guint8 *start_ptr)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_BYTES);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_bytes(new_fi, start_ptr, length);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
return pi;
}
gint length, nstime_t *value_ptr)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_ABSOLUTE_TIME ||
hfinfo->type == FT_RELATIVE_TIME);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_time(new_fi, value_ptr);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
return pi;
}
gint length, guint32 value)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_IPXNET);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_ipxnet(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
return pi;
}
gint length, guint32 value)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_IPv4);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_ipv4(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_ipv4(PNODE_FINFO(pi), value);
return pi;
}
gint length, const guint8* value_ptr)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_IPv6);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_ipv6(new_fi, value_ptr);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr);
return pi;
}
gint length, const e_guid_t *value_ptr)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_GUID);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_guid(new_fi, value_ptr);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
return pi;
}
gint length, const guint8* value_ptr)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_OID);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_oid(new_fi, value_ptr, length);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
return pi;
}
gint length, const char* value)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
DISSECTOR_ASSERT(length >= 0);
- proto_tree_set_string(new_fi, value);
+ proto_tree_set_string(PNODE_FINFO(pi), value);
return pi;
}
{
field_info *fi;
header_field_info *hfinfo;
- gchar *old_str, *new_str;
+ const gchar *old_str, *new_str;
if (!pi)
return;
}
DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
old_str = (guint8 *)fvalue_get(&fi->value);
- new_str = ep_strdup_printf("%s%s", old_str, str);
- fvalue_set(&fi->value, new_str, FALSE);
+ if (old_str && old_str[0])
+ new_str = ep_strconcat(old_str, str, NULL);
+ else
+ new_str = str;
+ fvalue_set(&fi->value, (gpointer) new_str, FALSE);
}
/* Set the FT_STRING value */
const guint8* value)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_AX25);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_ax25(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_ax25(PNODE_FINFO(pi), value);
return pi;
}
proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
}
+/* Set the FT_VINES value */
+static void
+proto_tree_set_vines(field_info *fi, const guint8* value)
+{
+ fvalue_set(&fi->value, (gpointer) value, FALSE);
+}
+
+static void
+proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
+{
+ proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
+}
/* Add a FT_ETHER to a proto_tree */
proto_item *
gint length, const guint8* value)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_ETHER);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_ether(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_ether(PNODE_FINFO(pi), value);
return pi;
}
gint length, guint32 value)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_BOOLEAN);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_boolean(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_boolean(PNODE_FINFO(pi), value);
return pi;
}
gint length, float value)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_FLOAT);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_float(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_float(PNODE_FINFO(pi), value);
return pi;
}
gint length, double value)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_DOUBLE);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_double(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_double(PNODE_FINFO(pi), value);
return pi;
}
gint length, guint32 value)
{
proto_item *pi = NULL;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
case FT_UINT24:
case FT_UINT32:
case FT_FRAMENUM:
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length,
- &new_fi);
- proto_tree_set_uint(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_uint(PNODE_FINFO(pi), value);
break;
default:
integer &= hfinfo->bitmask;
/* Shift bits */
- if (hfinfo->bitshift > 0) {
- integer >>= hfinfo->bitshift;
- }
+ integer >>= hfinfo_bitshift(hfinfo);
}
fvalue_set_uinteger(&fi->value, integer);
proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, guint64 value)
{
- proto_item *pi = NULL;
- field_info *new_fi;
+ proto_item *pi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_uint64(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_uint64(PNODE_FINFO(pi), value);
return pi;
}
gint length, gint32 value)
{
proto_item *pi = NULL;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
case FT_INT16:
case FT_INT24:
case FT_INT32:
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length,
- &new_fi);
- proto_tree_set_int(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_int(PNODE_FINFO(pi), value);
break;
default:
{
header_field_info *hfinfo;
guint32 integer;
+ gint no_of_bits;
hfinfo = fi->hfinfo;
integer = (guint32) value;
integer &= hfinfo->bitmask;
/* Shift bits */
- if (hfinfo->bitshift > 0) {
- integer >>= hfinfo->bitshift;
- }
+ integer >>= hfinfo_bitshift(hfinfo);
+
+ no_of_bits = swar_count_bits(hfinfo->bitmask);
+ if (integer & (1 << (no_of_bits-1)))
+ integer |= (-1 << no_of_bits);
}
fvalue_set_sinteger(&fi->value, integer);
proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
gint length, gint64 value)
{
- proto_item *pi = NULL;
- field_info *new_fi;
+ proto_item *pi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_INT64);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_uint64(new_fi, (guint64)value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_uint64(PNODE_FINFO(pi), (guint64)value);
return pi;
}
gint length, const guint64 value)
{
proto_item *pi;
- field_info *new_fi;
header_field_info *hfinfo;
TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_EUI64);
- pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length, &new_fi);
- proto_tree_set_eui64(new_fi, value);
+ pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
+ proto_tree_set_eui64(PNODE_FINFO(pi), value);
return pi;
}
* Sets *pfi to address of newly-allocated field_info struct */
static proto_item *
proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
- gint *length, field_info **pfi)
+ gint *length)
{
proto_item *pi;
field_info *fi;
fi = alloc_field_info(tree, hfinfo, tvb, start, length);
pi = proto_tree_add_node(tree, fi);
- *pfi = fi;
-
return pi;
}
static void
-get_hfi_and_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
+get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
gint *item_length)
{
- gint length_remaining;
+ gint length_remaining;
/*
* We only allow a null tvbuff if the item has a zero length,
{
gint item_length;
- get_hfi_and_length(hfinfo, tvb, start, length, &item_length);
+ get_hfi_length(hfinfo, tvb, start, length, &item_length);
return new_field_info(tree, hfinfo, tvb, start, item_length);
}
+static void
+label_mark_truncated_start(char *label_str)
+{
+ static const char trunc_str[] = "[truncated] ";
+ const size_t trunc_len = sizeof(trunc_str)-1;
+
+ memmove(label_str + trunc_len, label_str, ITEM_LABEL_LENGTH - trunc_len);
+ memcpy(label_str, trunc_str, trunc_len);
+ label_str[ITEM_LABEL_LENGTH-1] = '\0';
+}
+
/* If the protocol tree is to be visible, set the representation of a
proto_tree entry with the name of the field for the item and with
the value formatted with the supplied printf-style format and
char *p;
val = fvalue_get_uinteger(&fi->value);
- if (hf->bitshift > 0)
- val <<= hf->bitshift;
+ val <<= hfinfo_bitshift(hf);
p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_bitwidth(hf));
ret = (int) (p - fi->rep->representation);
/* Uh oh, we don't have enough room. Tell the user
* that the field is truncated.
*/
- char *oldrep;
-
- /* Argh, we cannot reuse 'ap' here. So make a copy
- * of what we formatted for (re)use below.
- */
- oldrep = g_strdup(fi->rep->representation);
-
- g_snprintf(fi->rep->representation,
- ITEM_LABEL_LENGTH,
- "[truncated] %s",
- oldrep);
- g_free(oldrep);
+ /* XXX, label_mark_truncated() ? */
+ label_mark_truncated_start(fi->rep->representation);
}
}
}
/* Uh oh, we don't have enough room. Tell the user
* that the field is truncated.
*/
- char *oldrep;
-
- /* Argh, we cannot reuse 'ap' here. So make a copy
- * of what we formatted for (re)use below.
- */
- oldrep = g_strdup(fi->rep->representation);
-
- g_snprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
- "[truncated] %s", oldrep);
- g_free(oldrep);
+ label_mark_truncated_start(fi->rep->representation);
}
}
}
return (int) res;
}
+static header_field_info *
+hfinfo_same_name_get_prev(const header_field_info *hfinfo)
+{
+ if (hfinfo->same_name_prev_id == -1)
+ return NULL;
+ return proto_registrar_get_nth(hfinfo->same_name_prev_id);
+}
+
/* -------------------------- */
const gchar *
proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
gchar *result, gchar *expr, const int size)
{
- guint32 u_integer;
- gint32 integer;
+ guint32 number;
guint8 *bytes;
ipv4_addr *ipv4;
struct e_in6_addr *ipv6;
header_field_info* hfinfo;
const gchar *abbrev = NULL;
+ const char *hf_str_val;
char number_buf[32];
const char *number_out;
if (occurrence < 0) {
/* Search other direction */
- while (hfinfo->same_name_prev) {
- hfinfo = hfinfo->same_name_prev;
+ while (hfinfo->same_name_prev_id != -1) {
+ hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id);
}
}
if (occurrence < 0) {
hfinfo = hfinfo->same_name_next;
} else {
- hfinfo = hfinfo->same_name_prev;
+ hfinfo = hfinfo_same_name_get_prev(hfinfo);
}
continue;
}
if (occurrence < 0) {
hfinfo = hfinfo->same_name_next;
} else {
- hfinfo = hfinfo->same_name_prev;
+ hfinfo = hfinfo_same_name_get_prev(hfinfo);
}
prev_len += len;
continue;
break;
case FT_BOOLEAN:
- u_integer = fvalue_get_uinteger(&finfo->value);
+ number = fvalue_get_uinteger(&finfo->value);
tfstring = (const true_false_string *)&tfs_true_false;
if (hfinfo->strings) {
tfstring = (const struct true_false_string*) hfinfo->strings;
}
offset_r += protoo_strlcpy(result+offset_r,
- u_integer ?
+ number ?
tfstring->true_string :
tfstring->false_string, size-offset_r);
offset_e += protoo_strlcpy(expr+offset_e,
- u_integer ? "1" : "0", size-offset_e);
+ number ? "1" : "0", size-offset_e);
break;
+ /* XXX - make these just FT_NUMBER? */
+ case FT_INT8:
+ case FT_INT16:
+ case FT_INT24:
+ case FT_INT32:
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
case FT_FRAMENUM:
- u_integer = fvalue_get_uinteger(&finfo->value);
+ hf_str_val = NULL;
+ number = IS_FT_INT(hfinfo->type) ?
+ (guint32) fvalue_get_sinteger(&finfo->value) :
+ fvalue_get_uinteger(&finfo->value);
+
if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_CUSTOM) {
gchar tmp[ITEM_LABEL_LENGTH];
custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
DISSECTOR_ASSERT(fmtfunc);
- fmtfunc(tmp, u_integer);
- g_strlcpy(result+offset_r, tmp, size-offset_r);
+ fmtfunc(tmp, number);
+
+ offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
+
} else if (hfinfo->strings) {
- const char *str_val = hf_try_val_to_str(u_integer, hfinfo);
+ number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
+
+ if (!number_out)
+ number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
- if (str_val)
- g_strlcpy(result+offset_r, str_val, size-offset_r);
- else
- g_snprintf(result+offset_r, size-offset_r, "%u", u_integer);
+ offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
} else {
- number_out = hfinfo_number_value_format(hfinfo, number_buf, u_integer);
+ number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
- g_strlcpy(result+offset_r, number_out, size-offset_r);
+ offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
}
- if (hfinfo->strings && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
- g_snprintf(expr+offset_e, size-offset_e,
- "\"%s\"", result+offset_r);
+ if (hf_str_val && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
+ g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
} else {
- number_out = hfinfo_numeric_value_format(hfinfo, number_buf, u_integer);
+ number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
g_strlcpy(expr+offset_e, number_out, size-offset_e);
}
- offset_r = (int)strlen(result);
offset_e = (int)strlen(expr);
break;
eui64_to_str(fvalue_get_integer64(&finfo->value)),
size-offset_r);
break;
- /* XXX - make these just FT_INT? */
- case FT_INT8:
- case FT_INT16:
- case FT_INT24:
- case FT_INT32:
- integer = fvalue_get_sinteger(&finfo->value);
- if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_CUSTOM) {
- gchar tmp[ITEM_LABEL_LENGTH];
- custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
-
- DISSECTOR_ASSERT(fmtfunc);
- fmtfunc(tmp, integer);
- g_strlcpy(result+offset_r, tmp, size-offset_r);
- } else if (hfinfo->strings) {
- const char *str_val = hf_try_val_to_str(integer, hfinfo);
-
- if (str_val)
- g_strlcpy(result+offset_r, str_val, size-offset_r);
- else
- g_snprintf(result+offset_r, size-offset_r, "%d", integer);
-
- } else {
- number_out = hfinfo_number_value_format(hfinfo, number_buf, integer);
-
- g_strlcpy(result+offset_r, number_out, size-offset_r);
- }
-
- if (hfinfo->strings && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
- g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", result+offset_r);
- } else {
- number_out = hfinfo_numeric_value_format(hfinfo, number_buf, (guint32) integer);
-
- g_strlcpy(expr+offset_e, number_out, size-offset_e);
- }
-
- offset_r = (int)strlen(result);
- offset_e = (int)strlen(expr);
- break;
case FT_IPv4:
ipv4 = (ipv4_addr *)fvalue_get(&finfo->value);
if (occurrence == 0) {
/* Fetch next hfinfo with same name (abbrev) */
- hfinfo = hfinfo->same_name_prev;
+ hfinfo = hfinfo_same_name_get_prev(hfinfo);
} else {
hfinfo = NULL;
}
*/
if (fi->rep == NULL) {
ITEM_LABEL_NEW(fi->rep);
- proto_item_fill_label(fi, fi->rep->representation);
- }
+ proto_item_fill_label(fi, representation);
+ } else
+ g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
- g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
va_start(ap, format);
g_vsnprintf(fi->rep->representation,
ITEM_LABEL_LENGTH, format, ap);
return fi ? fi->length : -1;
}
-
-/** clear flags according to the mask and set new flag values */
-#define FI_REPLACE_FLAGS(fi, mask, flags_in) { \
- (fi->flags = (fi)->flags & ~(mask)); \
- (fi->flags = (fi)->flags | (flags_in)); \
-}
-
-gboolean
-proto_item_set_expert_flags(proto_item *pi, const int group, const guint severity)
-{
- if (pi == NULL || PITEM_FINFO(pi) == NULL)
- return FALSE;
-
- /* only change things if severity is worse or at least equal than before */
- if (severity >= FI_GET_FLAG(PITEM_FINFO(pi), PI_SEVERITY_MASK)) {
- FI_REPLACE_FLAGS(PITEM_FINFO(pi), PI_GROUP_MASK, group);
- FI_REPLACE_FLAGS(PITEM_FINFO(pi), PI_SEVERITY_MASK, severity);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
proto_tree *
proto_tree_create_root(packet_info *pinfo)
{
hfinfo->display = BASE_NONE;
hfinfo->strings = protocol;
hfinfo->bitmask = 0;
- hfinfo->bitshift = 0;
hfinfo->ref_type = HF_REF_TYPE_NONE;
hfinfo->blurb = NULL;
hfinfo->parent = -1; /* this field differentiates protos and fields */
proto_get_first_protocol_field(const int proto_id, void **cookie)
{
protocol_t *protocol = find_protocol_by_id(proto_id);
- hf_register_info *ptr;
if ((protocol == NULL) || (protocol->fields == NULL))
return NULL;
*cookie = protocol->fields;
- ptr = (hf_register_info *)protocol->fields->data;
- return &ptr->hfinfo;
+ return (header_field_info *)protocol->fields->data;
}
header_field_info *
proto_get_next_protocol_field(void **cookie)
{
- GList *list_item = (GList *)*cookie;
- hf_register_info *ptr;
+ GSList *list_item = (GSList *)*cookie;
- list_item = g_list_next(list_item);
+ list_item = g_slist_next(list_item);
if (list_item == NULL)
return NULL;
*cookie = list_item;
- ptr = (hf_register_info *)list_item->data;
- return &ptr->hfinfo;
+ return (header_field_info *)list_item->data;
}
protocol_t *
if (proto != NULL) {
if (proto->fields == NULL) {
- proto->fields = g_list_append(NULL, ptr);
+ proto->fields = g_slist_append(NULL, &ptr->hfinfo);
proto->last_field = proto->fields;
} else {
proto->last_field =
- g_list_append(proto->last_field, ptr)->next;
+ g_slist_append(proto->last_field, &ptr->hfinfo)->next;
}
}
field_id = proto_register_field_init(&ptr->hfinfo, parent);
}
}
+void
+proto_register_fields(const int parent, header_field_info **hfi, const int num_records)
+{
+ int i;
+ protocol_t *proto;
+
+ proto = find_protocol_by_id(parent);
+ for (i = 0; i < num_records; i++) {
+ /*
+ * Make sure we haven't registered this yet.
+ */
+ if (hfi[i]->id != -1) {
+ fprintf(stderr,
+ "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
+ hfi[i]->abbrev);
+ return;
+ }
+
+ if (proto != NULL) {
+ if (proto->fields == NULL) {
+ proto->fields = g_slist_append(NULL, hfi[i]);
+ proto->last_field = proto->fields;
+ } else {
+ proto->last_field =
+ g_slist_append(proto->last_field, hfi[i])->next;
+ }
+ }
+ proto_register_field_init(hfi[i], parent);
+ }
+}
+
/* unregister already registered fields */
void
proto_unregister_field (const int parent, gint hf_id)
{
hf_register_info *hf;
protocol_t *proto;
- GList *field;
+ GSList *field;
if (hf_id == -1 || hf_id == 0)
return;
return;
}
- for (field = g_list_first (proto->fields); field; field = g_list_next (field)) {
+ for (field = proto->fields; field; field = field->next) {
hf = (hf_register_info *)field->data;
if (*hf->p_id == hf_id) {
/* Found the hf_id in this protocol */
g_tree_steal (gpa_name_tree, hf->hfinfo.abbrev);
- proto->fields = g_list_remove_link (proto->fields, field);
- proto->last_field = g_list_last (proto->fields);
+ /* XXX, memleak? g_slist_delete_link() */
+ proto->fields = g_slist_remove_link (proto->fields, field);
+ proto->last_field = g_slist_last (proto->fields);
break;
}
}
{ BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
{ BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
{ BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
+ { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
+ { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
+ { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
+ { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
+ { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
+ { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
+ { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
{ ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
{ ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
{ ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
(hfinfo->type == FT_INT32) ||
(hfinfo->type == FT_INT64) ||
(hfinfo->type == FT_BOOLEAN) ||
- (hfinfo->type == FT_PROTOCOL) ||
- (hfinfo->type == FT_FRAMENUM) ))
+ (hfinfo->type == FT_PROTOCOL) ))
g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
" (which is not allowed to have strings)\n",
hfinfo->name, hfinfo->abbrev,
* else, unsigned so don't allow dissectors to register a
* signed field to be displayed unsigned. (Else how would
* we display negative values?)
- *
- * If you want to take out this check, be sure to fix
- * hfinfo_numeric_format() so that it does not assert out
- * when trying to construct a hexadecimal representation of
- * FT_INT*.
*/
- if (hfinfo->display == BASE_HEX ||
- hfinfo->display == BASE_OCT)
- g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
- hfinfo->name, hfinfo->abbrev,
- val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
- val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
+ switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
+ case BASE_HEX:
+ case BASE_OCT:
+ case BASE_DEC_HEX:
+ case BASE_HEX_DEC:
+ g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
+ hfinfo->name, hfinfo->abbrev,
+ val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
+ val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
+ }
/* FALL THROUGH */
case FT_UINT8:
case FT_UINT16:
tmp_fld_check_assert(hfinfo);
- /* if this is a bitfield, compute bitshift */
- if (hfinfo->bitmask) {
- hfinfo->bitshift = wrs_count_bitshift(hfinfo->bitmask);
- }
-
hfinfo->parent = parent;
hfinfo->same_name_next = NULL;
- hfinfo->same_name_prev = NULL;
+ hfinfo->same_name_prev_id = -1;
/* if we always add and never delete, then id == len - 1 is correct */
if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
hfinfo->same_name_next = same_name_next_hfinfo;
if (same_name_next_hfinfo)
- same_name_next_hfinfo->same_name_prev = hfinfo;
+ same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
same_name_hfinfo->same_name_next = hfinfo;
- hfinfo->same_name_prev = same_name_hfinfo;
+ hfinfo->same_name_prev_id = same_name_hfinfo->id;
}
}
* dissector that registers ett values.)
*/
if (tree_is_expanded != NULL) {
- tree_is_expanded =
- (gboolean *)g_realloc(tree_is_expanded,
- (num_tree_types + num_indices)*sizeof (gboolean));
- memset(tree_is_expanded + num_tree_types, 0,
- num_indices*sizeof (gboolean));
+ tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
+
+ /* set new items to 0 */
+ /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
+ for (i = num_tree_types; i < num_tree_types + num_indices; i++)
+ tree_is_expanded[i >> 5] &= ~(1 << (i & 31));
}
/*
}
}
-static int
-label_fill_descr(char *label_str, const header_field_info *hfinfo, const char *text, const char *descr)
+static inline gsize
+label_concat(char *label_str, gsize pos, const char *str)
{
- gint ret;
+ if (pos < ITEM_LABEL_LENGTH)
+ pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
+
+ return pos;
+}
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s: %s (%s)", hfinfo->name, text, descr);
- if (ret >= ITEM_LABEL_LENGTH) {
+static void
+label_mark_truncated(char *label_str, gsize name_pos)
+{
+ static const char trunc_str[] = " [truncated]";
+ const size_t trunc_len = sizeof(trunc_str)-1;
+
+ /* ..... field_name: dataaaaaaaaaaaaa
+ * |
+ * ^^^^^ name_pos
+ *
+ * ..... field_name [truncated]: dataaaaaaaaaaaaa */
+
+ if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
+ memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
+ memcpy(label_str + name_pos, trunc_str, trunc_len);
+ label_str[ITEM_LABEL_LENGTH-1] = '\0';
+
+ } else if (name_pos < ITEM_LABEL_LENGTH)
+ g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
+}
+
+static gsize
+label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
+{
+ gsize name_pos;
+
+ /* "%s: %s", hfinfo->name, text */
+ name_pos = pos = label_concat(label_str, pos, hfinfo->name);
+ pos = label_concat(label_str, pos, ": ");
+ pos = label_concat(label_str, pos, text ? text : "(null)");
+
+ if (pos >= ITEM_LABEL_LENGTH) {
/* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s [truncated]: %s (%s)", hfinfo->name, text, descr);
+ label_mark_truncated(label_str, name_pos);
}
- return ret;
+ return pos;
}
-static int
-label_fill(char *label_str, const header_field_info *hfinfo, const char *text)
+static gsize
+label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
{
- gint ret;
+ gsize name_pos;
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s: %s", hfinfo->name, text);
- if (ret >= ITEM_LABEL_LENGTH) {
+ /* "%s: %s (%s)", hfinfo->name, text, descr */
+ name_pos = pos = label_concat(label_str, pos, hfinfo->name);
+ pos = label_concat(label_str, pos, ": ");
+ pos = label_concat(label_str, pos, text ? text : "(null)");
+ pos = label_concat(label_str, pos, " (");
+ pos = label_concat(label_str, pos, descr ? descr : "(null)");
+ pos = label_concat(label_str, pos, ")");
+
+ if (pos >= ITEM_LABEL_LENGTH) {
/* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s [truncated]: %s", hfinfo->name, text);
+ label_mark_truncated(label_str, name_pos);
}
- return ret;
+ return pos;
}
void
e_guid_t *guid;
guint32 n_addr; /* network-order IPv4 address */
const gchar *name;
+ address addr;
if (!fi) {
if (label_str)
case FT_BYTES:
case FT_UINT_BYTES:
bytes = (guint8 *)fvalue_get(&fi->value);
- label_fill(label_str, hfinfo,
+ label_fill(label_str, 0, hfinfo,
(bytes) ? bytes_to_str(bytes, fvalue_length(&fi->value)) : "<MISSING>");
break;
case FT_UINT24:
case FT_UINT32:
if (hfinfo->bitmask) {
- fill_label_bitfield(fi, label_str);
+ fill_label_bitfield(fi, label_str, FALSE);
} else {
fill_label_number(fi, label_str, FALSE);
}
case FT_INT16:
case FT_INT24:
case FT_INT32:
- DISSECTOR_ASSERT(!hfinfo->bitmask);
- fill_label_number(fi, label_str, TRUE);
+ if (hfinfo->bitmask) {
+ fill_label_bitfield(fi, label_str, TRUE);
+ } else {
+ fill_label_number(fi, label_str, TRUE);
+ }
break;
case FT_INT64:
break;
case FT_ABSOLUTE_TIME:
- label_fill(label_str, hfinfo,
+ label_fill(label_str, 0, hfinfo,
abs_time_to_str((const nstime_t *)fvalue_get(&fi->value),
(absolute_time_display_e)hfinfo->display, TRUE));
break;
case FT_AX25:
bytes = (guint8 *)fvalue_get(&fi->value);
- label_fill_descr(label_str, hfinfo,
+ label_fill_descr(label_str, 0, hfinfo,
get_ax25_name(bytes),
ax25_to_str(bytes));
break;
+ case FT_VINES:
+ addr.type = AT_VINES;
+ addr.len = VINES_ADDR_LEN;
+ addr.data = (guint8 *)fvalue_get(&fi->value);
+
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ "%s: %s", hfinfo->name,
+ address_to_str( &addr ));
+ break;
+
case FT_ETHER:
bytes = (guint8 *)fvalue_get(&fi->value);
- label_fill_descr(label_str, hfinfo,
+ label_fill_descr(label_str, 0, hfinfo,
get_ether_name(bytes),
ether_to_str(bytes));
break;
case FT_IPv4:
ipv4 = (ipv4_addr *)fvalue_get(&fi->value);
n_addr = ipv4_get_net_order_addr(ipv4);
- label_fill_descr(label_str, hfinfo,
+ label_fill_descr(label_str, 0, hfinfo,
get_hostname(n_addr),
ip_to_str((guint8*)&n_addr));
break;
case FT_IPv6:
bytes = (guint8 *)fvalue_get(&fi->value);
- label_fill_descr(label_str, hfinfo,
+ label_fill_descr(label_str, 0, hfinfo,
get_hostname6((struct e_in6_addr *)bytes),
ip6_to_str((struct e_in6_addr*)bytes));
break;
case FT_GUID:
guid = (e_guid_t *)fvalue_get(&fi->value);
- label_fill(label_str, hfinfo, guid_to_str(guid));
+ label_fill(label_str, 0, hfinfo, guid_to_str(guid));
break;
case FT_OID:
bytes = (guint8 *)fvalue_get(&fi->value);
name = oid_resolved_from_encoded(bytes, fvalue_length(&fi->value));
if (name) {
- label_fill_descr(label_str, hfinfo,
+ label_fill_descr(label_str, 0, hfinfo,
oid_encoded2string(bytes, fvalue_length(&fi->value)), name);
} else {
- label_fill(label_str, hfinfo,
+ label_fill(label_str, 0, hfinfo,
oid_encoded2string(bytes, fvalue_length(&fi->value)));
}
break;
case FT_EUI64:
integer64 = fvalue_get_integer64(&fi->value);
- label_fill_descr(label_str, hfinfo,
+ label_fill_descr(label_str, 0, hfinfo,
get_eui64_name(integer64),
eui64_to_str(integer64));
break;
case FT_STRINGZ:
case FT_UINT_STRING:
bytes = (guint8 *)fvalue_get(&fi->value);
- label_fill(label_str, hfinfo, format_text(bytes, strlen(bytes)));
+ label_fill(label_str, 0, hfinfo, format_text(bytes, strlen(bytes)));
break;
default:
/* Un-shift bits */
unshifted_value = value;
- if (hfinfo->bitshift > 0) {
- unshifted_value <<= hfinfo->bitshift;
- }
+ unshifted_value <<= hfinfo_bitshift(hfinfo);
/* Create the bitfield first */
p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
}
/* Fill in the textual info */
- g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
- "%s: %s", hfinfo->name,
- value ? tfstring->true_string : tfstring->false_string);
+ label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
}
static const char *
if (hfinfo->display & BASE_EXT_STRING)
return try_val_to_str_ext(value, (const value_string_ext *) hfinfo->strings);
+ if (hfinfo->display & BASE_VAL64_STRING)
+ return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
+
return try_val_to_str(value, (const value_string *) hfinfo->strings);
}
+static const char *
+hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
+{
+ if (hfinfo->display & BASE_VAL64_STRING)
+ return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
+
+ /* If this is reached somebody registered a 64-bit field with a 32-bit
+ * value-string, which isn't right. */
+ DISSECTOR_ASSERT_NOT_REACHED();
+
+ /* This is necessary to squelch MSVC errors; is there
+ any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
+ never returns? */
+ return NULL;
+}
+
static const char *
hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
{
return (str) ? str : unknown_str;
}
+static const char *
+hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
+{
+ const char *str = hf_try_val64_to_str(value, hfinfo);
+
+ return (str) ? str : unknown_str;
+}
+
/* Fills data for bitfield ints with val_strings */
static void
-fill_label_bitfield(field_info *fi, gchar *label_str)
+fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
{
char *p;
int bitfield_byte_length, bitwidth;
bitwidth = hfinfo_bitwidth(hfinfo);
/* Un-shift bits */
- unshifted_value = fvalue_get_uinteger(&fi->value);
+ if (is_signed)
+ unshifted_value = fvalue_get_sinteger(&fi->value);
+ else
+ unshifted_value = fvalue_get_uinteger(&fi->value);
+
value = unshifted_value;
- if (hfinfo->bitshift > 0) {
- unshifted_value <<= hfinfo->bitshift;
+ if (hfinfo->bitmask) {
+ unshifted_value <<= hfinfo_bitshift(hfinfo);
}
/* Create the bitfield first */
DISSECTOR_ASSERT(fmtfunc);
fmtfunc(tmp, value);
- g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
- "%s: %s", hfinfo->name, tmp);
+ label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
}
else if (hfinfo->strings) {
const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
out = hfinfo_number_vals_format(hfinfo, buf, value);
if (out == NULL) /* BASE_NONE so don't put integer in descr */
- g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
- "%s: %s", hfinfo->name, val_str);
+ label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
else
- g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
- "%s: %s (%s)", hfinfo->name, val_str, out);
+ label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
}
else {
out = hfinfo_number_value_format(hfinfo, buf, value);
- g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
- "%s: %s", hfinfo->name, out);
+ label_fill(label_str, bitfield_byte_length, hfinfo, out);
}
}
DISSECTOR_ASSERT(fmtfunc);
fmtfunc(tmp, value);
- label_fill(label_str, hfinfo, tmp);
+ label_fill(label_str, 0, hfinfo, tmp);
}
else if (hfinfo->strings) {
const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
out = hfinfo_number_vals_format(hfinfo, buf, value);
if (out == NULL) /* BASE_NONE so don't put integer in descr */
- label_fill(label_str, hfinfo, val_str);
+ label_fill(label_str, 0, hfinfo, val_str);
else
- label_fill_descr(label_str, hfinfo, val_str, out);
+ label_fill_descr(label_str, 0, hfinfo, val_str, out);
}
else {
out = hfinfo_number_value_format(hfinfo, buf, value);
- label_fill(label_str, hfinfo, out);
+ label_fill(label_str, 0, hfinfo, out);
}
}
const char *format = NULL;
header_field_info *hfinfo = fi->hfinfo;
guint64 value;
+ char tmp[ITEM_LABEL_LENGTH+1];
/* Pick the proper format string */
if (is_signed)
value = fvalue_get_integer64(&fi->value);
- /* Fill in the textual info */
- if (IS_BASE_DUAL(hfinfo->display)) {
- g_snprintf(label_str, ITEM_LABEL_LENGTH,
- format, hfinfo->name, value, value);
- } else {
- g_snprintf(label_str, ITEM_LABEL_LENGTH,
- format, hfinfo->name, value);
+ /* Format the temporary string */
+ if (IS_BASE_DUAL(hfinfo->display))
+ g_snprintf(tmp, ITEM_LABEL_LENGTH, format, value, value);
+ else
+ g_snprintf(tmp, ITEM_LABEL_LENGTH, format, value);
+
+ if (hfinfo->strings) {
+ const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
+
+ if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
+ label_fill(label_str, 0, hfinfo, val_str);
+ }
+ else {
+ label_fill_descr(label_str, 0, hfinfo, val_str, tmp);
+ }
+ }
+ else {
+ label_fill(label_str, 0, hfinfo, tmp);
}
}
+int
+hfinfo_bitshift(const header_field_info *hfinfo)
+{
+ const guint32 bitmask = hfinfo->bitmask;
+
+#if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+ g_assert(bitmask != 0);
+
+ return __builtin_ctz(bitmask);
+#else
+ /* From http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup */
+ static const int table[32] = {
+ 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
+ 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
+ };
+
+ return table[((guint32)((bitmask & -(gint32)bitmask) * 0x077CB531U)) >> 27];
+#endif
+}
+
int
hfinfo_bitwidth(const header_field_info *hfinfo)
{
char *int_to_str_back(char *ptr, gint32 value);
static const char *
-_hfinfo_number_value_format(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
+hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
{
char *ptr = &buf[31];
gboolean isint = IS_FT_INT(hfinfo->type);
display = BASE_DEC;
}
- return _hfinfo_number_value_format(hfinfo, display, buf, value);
+ return hfinfo_number_value_format_display(hfinfo, display, buf, value);
}
static const char *
break;
}
- return _hfinfo_number_value_format(hfinfo, display, buf, value);
+ return hfinfo_number_value_format_display(hfinfo, display, buf, value);
}
static const char *
if (display == BASE_HEX_DEC)
display = BASE_HEX;
- return _hfinfo_number_value_format(hfinfo, display, buf, value);
+ return hfinfo_number_value_format_display(hfinfo, display, buf, value);
}
static const char *
const char *format = NULL;
/* Pick the proper format string */
- switch (hfinfo->display) {
+ switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
case BASE_DEC:
- format = "%s: %" G_GINT64_MODIFIER "u";
+ format = "%" G_GINT64_MODIFIER "u";
break;
case BASE_DEC_HEX:
- format = "%s: %" G_GINT64_MODIFIER "u (0x%016" G_GINT64_MODIFIER "x)";
+ format = "%" G_GINT64_MODIFIER "u (0x%016" G_GINT64_MODIFIER "x)";
break;
case BASE_OCT: /* I'm lazy */
- format = "%s: %#" G_GINT64_MODIFIER "o";
+ format = "%#" G_GINT64_MODIFIER "o";
break;
case BASE_HEX:
- format = "%s: 0x%016" G_GINT64_MODIFIER "x";
+ format = "0x%016" G_GINT64_MODIFIER "x";
break;
case BASE_HEX_DEC:
- format = "%s: 0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "u)";
+ format = "0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "u)";
break;
default:
DISSECTOR_ASSERT_NOT_REACHED();
const char *format = NULL;
/* Pick the proper format string */
- switch (hfinfo->display) {
+ switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
case BASE_DEC:
- format = "%s: %" G_GINT64_MODIFIER "d";
+ format = "%" G_GINT64_MODIFIER "d";
break;
case BASE_DEC_HEX:
- format = "%s: %" G_GINT64_MODIFIER "d (0x%016" G_GINT64_MODIFIER "x)";
+ format = "%" G_GINT64_MODIFIER "d (0x%016" G_GINT64_MODIFIER "x)";
break;
case BASE_OCT: /* I'm lazy */
- format = "%s: %#" G_GINT64_MODIFIER "o";
+ format = "%#" G_GINT64_MODIFIER "o";
break;
case BASE_HEX:
- format = "%s: 0x%016" G_GINT64_MODIFIER "x";
+ format = "0x%016" G_GINT64_MODIFIER "x";
break;
case BASE_HEX_DEC:
- format = "%s: 0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)";
+ format = "0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)";
break;
default:
DISSECTOR_ASSERT_NOT_REACHED();
header_field_info *hfinfo;
int i, len, vi;
const value_string *vals;
+ const val64_string *vals64;
const range_string *range;
const true_false_string *tfs;
* *maximum* length is 2 bytes, and be used
* for all lengths.)
*/
- if (hfinfo->same_name_prev != NULL)
+ if (hfinfo->same_name_prev_id != -1)
continue;
- vals = NULL;
- range = NULL;
- tfs = NULL;
+ vals = NULL;
+ vals64 = NULL;
+ range = NULL;
+ tfs = NULL;
if (hfinfo->strings != NULL) {
if ((hfinfo->display & BASE_DISPLAY_E_MASK) != BASE_CUSTOM &&
vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
} else if ((hfinfo->display & BASE_RANGE_STRING) == 0) {
vals = (const value_string *)hfinfo->strings;
+ } else if ((hfinfo->display & BASE_VAL64_STRING) == 0) {
+ vals64 = (const val64_string *)hfinfo->strings;
} else {
range = (const range_string *)hfinfo->strings;
}
vi++;
}
}
+ else if (vals64) {
+ vi = 0;
+ while (vals64[vi].strptr) {
+ printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
+ hfinfo->abbrev,
+ vals64[vi].value,
+ vals64[vi].strptr);
+ vi++;
+ }
+ }
/* print range strings? */
else if (range) {
* *maximum* length is 2 bytes, and be used
* for all lengths.)
*/
- if (hfinfo->same_name_prev != NULL)
+ if (hfinfo->same_name_prev_id != -1)
continue;
PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
fields++;
continue;
}
- tmpval = (value & hf->bitmask) >> hf->bitshift;
+ tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
switch (hf->type) {
case FT_INT8:
}
proto_item *
-proto_tree_add_bits_item(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
+proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
const guint bit_offset, const gint no_of_bits,
const guint encoding)
{
header_field_info *hfinfo;
+ gint octet_length;
+ gint octet_offset;
+
+ PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
- TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hfinfo);
+ octet_length = (no_of_bits + 7) >> 3;
+ octet_offset = bit_offset >> 3;
+ test_length(hfinfo, tree, tvb, octet_offset, octet_length, encoding);
- return proto_tree_add_bits_ret_val(tree, hf_index, tvb, bit_offset, no_of_bits, NULL, encoding);
+ /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
+ * but only after doing a bunch more work (which we can, in the common
+ * case, shortcut here).
+ */
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
+
+ return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
}
/*
*/
static proto_item *
-_proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
+_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
const guint bit_offset, const gint no_of_bits,
guint64 *return_value, const guint encoding)
{
const true_false_string *tfstring;
/* We can't fake it just yet. We have to fill in the 'return_value' parameter */
- PROTO_REGISTRAR_GET_NTH(hf_index, hf_field);
+ PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
if (hf_field->bitmask != 0) {
REPORT_DISSECTOR_BUG(ep_strdup_printf("Incompatible use of proto_tree_add_bits_ret_val"
* Calculate the number of octets used to hold the bits
*/
tot_no_bits = ((bit_offset&0x7) + no_of_bits);
- length = tot_no_bits>>3;
- /* If we are using part of the next octet, increase length by 1 */
- if (tot_no_bits & 0x07)
- length++;
+ length = (tot_no_bits + 7) >> 3;
if (no_of_bits < 65) {
value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
}
/* Coast clear. Try and fake it */
- TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
tfstring = (const true_false_string *) &tfs_true_false;
if (hf_field->strings)
tfstring = (const true_false_string *)hf_field->strings;
- return proto_tree_add_boolean_format(tree, hf_index, tvb, offset, length, (guint32)value,
+ return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
"%s = %s: %s",
bf_str, hf_field->name,
(guint32)value ? tfstring->true_string : tfstring->false_string);
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
- pi = proto_tree_add_uint(tree, hf_index, tvb, offset, length, (guint32)value);
+ pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
break;
case FT_INT16:
case FT_INT24:
case FT_INT32:
- pi = proto_tree_add_int(tree, hf_index, tvb, offset, length, (gint32)value);
+ pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
break;
case FT_UINT64:
- pi = proto_tree_add_uint64(tree, hf_index, tvb, offset, length, value);
+ pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
break;
case FT_INT64:
- pi = proto_tree_add_int64(tree, hf_index, tvb, offset, length, (gint64)value);
+ pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
break;
}
proto_item *
-proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
+proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
const guint bit_offset, const crumb_spec_t *crumb_spec,
guint64 *return_value)
{
const true_false_string *tfstring;
/* We can't fake it just yet. We have to fill in the 'return_value' parameter */
- PROTO_REGISTRAR_GET_NTH(hf_index, hf_field);
+ PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
if (hf_field->bitmask != 0) {
REPORT_DISSECTOR_BUG(ep_strdup_printf(
}
/* Coast clear. Try and fake it */
- TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
/* initialise the format string */
bf_str = (char *)ep_alloc(256);
tfstring = (const true_false_string *) &tfs_true_false;
if (hf_field->strings)
tfstring = (const true_false_string *) hf_field->strings;
- return proto_tree_add_boolean_format(tree, hf_index,
+ return proto_tree_add_boolean_format(tree, hfindex,
tvb, octet_offset, octet_length, (guint32)value,
"%s = %s: %s",
bf_str, hf_field->name,
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
- pi = proto_tree_add_uint(tree, hf_index, tvb, octet_offset, octet_length, (guint32)value);
+ pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
break;
case FT_INT16:
case FT_INT24:
case FT_INT32:
- pi = proto_tree_add_int(tree, hf_index, tvb, octet_offset, octet_length, (gint32)value);
+ pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
break;
case FT_UINT64:
- pi = proto_tree_add_uint64(tree, hf_index, tvb, octet_offset, octet_length, value);
+ pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
break;
case FT_INT64:
- pi = proto_tree_add_int64(tree, hf_index, tvb, octet_offset, octet_length, (gint64)value);
+ pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
break;
}
void
-proto_tree_add_split_bits_crumb(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const guint bit_offset,
+proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
const crumb_spec_t *crumb_spec, guint16 crumb_index)
{
- header_field_info *hf_info;
+ header_field_info *hfinfo;
- PROTO_REGISTRAR_GET_NTH(hf_index, hf_info);
+ PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
proto_tree_add_text(tree, tvb,
bit_offset >> 3,
((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
crumb_spec[crumb_index].crumb_bit_length,
ENC_BIG_ENDIAN)),
crumb_index,
- hf_info->name);
+ hfinfo->name);
}
proto_item *
-proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb,
+proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
const guint bit_offset, const gint no_of_bits,
guint64 *return_value, const guint encoding)
{
proto_item *item;
- if ((item = _proto_tree_add_bits_ret_val(tree, hf_index, tvb,
+ if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
bit_offset, no_of_bits,
return_value, encoding))) {
FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
}
static proto_item *
-_proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index,
+_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
tvbuff_t *tvb, const guint bit_offset,
const gint no_of_bits, void *value_ptr,
gchar *value_str)
header_field_info *hf_field;
/* We do not have to return a value, try to fake it as soon as possible */
- TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
if (hf_field->bitmask != 0) {
REPORT_DISSECTOR_BUG(ep_strdup_printf(
*/
switch (hf_field->type) {
case FT_BOOLEAN:
- return proto_tree_add_boolean_format(tree, hf_index, tvb, offset, length, *(guint32 *)value_ptr,
+ return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
"%s: %s", str, value_str);
break;
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
- return proto_tree_add_uint_format(tree, hf_index, tvb, offset, length, *(guint32 *)value_ptr,
+ return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
"%s: %s", str, value_str);
break;
case FT_UINT64:
- return proto_tree_add_uint64_format(tree, hf_index, tvb, offset, length, *(guint64 *)value_ptr,
+ return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
"%s: %s", str, value_str);
break;
case FT_INT16:
case FT_INT24:
case FT_INT32:
- return proto_tree_add_int_format(tree, hf_index, tvb, offset, length, *(gint32 *)value_ptr,
+ return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
"%s: %s", str, value_str);
break;
case FT_INT64:
- return proto_tree_add_int64_format(tree, hf_index, tvb, offset, length, *(gint64 *)value_ptr,
+ return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
"%s: %s", str, value_str);
break;
case FT_FLOAT:
- return proto_tree_add_float_format(tree, hf_index, tvb, offset, length, *(float *)value_ptr,
+ return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
"%s: %s", str, value_str);
break;
}
static proto_item *
-proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index,
+proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
tvbuff_t *tvb, const guint bit_offset,
const gint no_of_bits, void *value_ptr,
gchar *value_str)
{
proto_item *item;
- if ((item = _proto_tree_add_bits_format_value(tree, hf_index,
+ if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
tvb, bit_offset, no_of_bits,
value_ptr, value_str))) {
FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
va_end(ap);
proto_item *
-proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hf_index,
+proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
tvbuff_t *tvb, const guint bit_offset,
const gint no_of_bits, guint32 value,
const char *format, ...)
gchar *dst;
header_field_info *hf_field;
- TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
switch (hf_field->type) {
case FT_UINT8:
CREATE_VALUE_STRING(dst, format, ap);
- return proto_tree_add_bits_format_value(tree, hf_index, tvb, bit_offset, no_of_bits, &value, dst);
+ return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
}
proto_item *
-proto_tree_add_float_bits_format_value(proto_tree *tree, const int hf_index,
+proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
tvbuff_t *tvb, const guint bit_offset,
const gint no_of_bits, float value,
const char *format, ...)
gchar *dst;
header_field_info *hf_field;
- TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
DISSECTOR_ASSERT(hf_field->type == FT_FLOAT);
CREATE_VALUE_STRING(dst, format, ap);
- return proto_tree_add_bits_format_value(tree, hf_index, tvb, bit_offset, no_of_bits, &value, dst);
+ return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
}
proto_item *
-proto_tree_add_int_bits_format_value(proto_tree *tree, const int hf_index,
+proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
tvbuff_t *tvb, const guint bit_offset,
const gint no_of_bits, gint32 value,
const char *format, ...)
gchar *dst;
header_field_info *hf_field;
- TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
switch (hf_field->type) {
case FT_INT8:
CREATE_VALUE_STRING(dst, format, ap);
- return proto_tree_add_bits_format_value(tree, hf_index, tvb, bit_offset, no_of_bits, &value, dst);
+ return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
}
proto_item *
-proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hf_index,
+proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
tvbuff_t *tvb, const guint bit_offset,
const gint no_of_bits, guint32 value,
const char *format, ...)
gchar *dst;
header_field_info *hf_field;
- TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
CREATE_VALUE_STRING(dst, format, ap);
- return proto_tree_add_bits_format_value(tree, hf_index, tvb, bit_offset, no_of_bits, &value, dst);
+ return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
}
guchar
return wrs_check_charset(fld_abbrev_chars, field_name);
}
+gboolean
+tree_expanded(int tree_type)
+{
+ g_assert(tree_type >= 0 && tree_type < num_tree_types);
+ return tree_is_expanded[tree_type >> 5] & (1 << (tree_type & 31));
+}
+
+void
+tree_expanded_set(int tree_type, gboolean value)
+{
+ g_assert(tree_type >= 0 && tree_type < num_tree_types);
+
+ if (value)
+ tree_is_expanded[tree_type >> 5] |= (1 << (tree_type & 31));
+ else
+ tree_is_expanded[tree_type >> 5] &= ~(1 << (tree_type & 31));
+}
+
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*