#include "charsets.h"
#include "asm_utils.h"
#include "column-utils.h"
+#include "to_str.h"
#include "wspython/wspy_register.h"
/* Candidates for assembler */
static int
-wrs_count_bitshift(guint32 bitmask)
+wrs_count_bitshift(const guint32 bitmask)
{
int bitshift = 0;
static void fill_label_int(field_info *fi, gchar *label_str);
static void fill_label_int64(field_info *fi, gchar *label_str);
-static const char* hfinfo_uint_vals_format(header_field_info *hfinfo);
-static const char* hfinfo_uint_format(header_field_info *hfinfo);
-static const char* hfinfo_uint_value_format(header_field_info *hfinfo);
-static const char* hfinfo_uint64_format(header_field_info *hfinfo);
-static const char* hfinfo_int_vals_format(header_field_info *hfinfo);
-static const char* hfinfo_int_format(header_field_info *hfinfo);
-static const char* hfinfo_int_value_format(header_field_info *hfinfo);
-static const char* hfinfo_int64_format(header_field_info *hfinfo);
+static const char* hfinfo_uint_vals_format(const header_field_info *hfinfo);
+static const char* hfinfo_uint_format(const header_field_info *hfinfo);
+static const char* hfinfo_uint_value_format(const header_field_info *hfinfo);
+static const char* hfinfo_uint64_format(const header_field_info *hfinfo);
+static const char* hfinfo_int_vals_format(const header_field_info *hfinfo);
+static const char* hfinfo_int_format(const header_field_info *hfinfo);
+static const char* hfinfo_int_value_format(const header_field_info *hfinfo);
+static const char* hfinfo_int64_format(const header_field_info *hfinfo);
static proto_item*
proto_tree_add_node(proto_tree *tree, field_info *fi);
static header_field_info *
-get_hfi_and_length(int hfindex, tvbuff_t *tvb, gint start, gint *length,
+get_hfi_and_length(int hfindex, 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,
- gint start, gint item_length);
+ const gint start, const gint item_length);
static field_info *
alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb,
- gint start, gint *length);
+ const gint start, gint *length);
static proto_item *
proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb,
static void
proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, guint length, gboolean little_endian);
static gboolean
-proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, int offset, int len, gint ett,
- const gint **fields, gboolean little_endian, int flags, gboolean first);
+proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset, const int len, const gint ett,
+ const gint **fields, const gboolean little_endian, const int flags, gboolean first);
-static int proto_register_field_init(header_field_info *hfinfo, int parent);
+static int proto_register_field_init(header_field_info *hfinfo, const int parent);
/* special-case header field used within proto.c */
int hf_text_only = -1;
/* List of all protocols */
static GList *protocols = NULL;
-#define INITIAL_NUM_PROTOCOL_HFINFO 200
-
+#define INITIAL_NUM_PROTOCOL_HFINFO 1500
/* Contains information about protocols and header fields. Used when
* dissectors register their data */
+#if GLIB_CHECK_VERSION(2,10,0)
+#else
static GMemChunk *gmc_hfinfo = NULL;
+#endif
/* Contains information about a field when a dissector calls
* proto_tree_add_item. */
#define FIELD_INFO_FREE(fi) \
SLAB_FREE(fi, field_info)
-
-
/* Contains the space for proto_nodes. */
SLAB_ITEM_TYPE_DEFINE(proto_node)
static SLAB_FREE_LIST_DEFINE(proto_node)
#define PROTO_NODE_FREE(node) \
SLAB_FREE(node, proto_node)
-
-
/* String space for protocol and field items for the GUI */
SLAB_ITEM_TYPE_DEFINE(item_label_t)
static SLAB_FREE_LIST_DEFINE(item_label_t)
#define ITEM_LABEL_FREE(il) \
SLAB_FREE(il, item_label_t)
-
#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
DISSECTOR_ASSERT((guint)hfindex < gpa_hfinfo.len); \
hfinfo=gpa_hfinfo.hfi[hfindex];
-
/* List which stores protocols and fields that have been registered */
typedef struct _gpa_hfinfo_t {
guint32 len;
proto_short_names = g_hash_table_new(wrs_str_hash, g_str_equal);
proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
+#if GLIB_CHECK_VERSION(2,10,0)
+#else
gmc_hfinfo = g_mem_chunk_new("gmc_hfinfo",
sizeof(header_field_info),
INITIAL_NUM_PROTOCOL_HFINFO * sizeof(header_field_info),
G_ALLOC_ONLY);
+#endif
gpa_hfinfo.len=0;
gpa_hfinfo.allocated_len=0;
/* We've assigned all the subtree type values; allocate the array
for them, and zero it out. */
- tree_is_expanded = g_malloc(num_tree_types*sizeof (gboolean));
- memset(tree_is_expanded, 0, num_tree_types*sizeof (gboolean));
+ tree_is_expanded = g_new0(gboolean, num_tree_types);
}
void
while (protocols) {
protocol_t *protocol = protocols->data;
+ header_field_info *hfinfo;
+ PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
+ DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
+
+#if GLIB_CHECK_VERSION(2,10,0)
+ g_slice_free(header_field_info, hfinfo);
+#else
+ g_mem_chunk_free(gmc_hfinfo, hfinfo);
+#endif
g_list_free(protocol->fields);
protocols = g_list_remove(protocols, protocol);
proto_filter_names = NULL;
}
+#if GLIB_CHECK_VERSION(2,10,0)
+#else
if (gmc_hfinfo) {
g_mem_chunk_destroy(gmc_hfinfo);
gmc_hfinfo = NULL;
}
+#endif
if(gpa_hfinfo.allocated_len){
gpa_hfinfo.len=0;
gpa_hfinfo.hfi=NULL;
}
g_free(tree_is_expanded);
-
+ tree_is_expanded = NULL;
}
static gboolean
/* 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, int hfindex, tvbuff_t *tvb,
- gint start, gint length, gboolean little_endian)
+proto_tree_add_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
+ const gint start, gint length, const gboolean little_endian)
{
field_info *new_fi;
header_field_info *hfinfo;
/* Add a FT_NONE to a proto_tree */
proto_item *
-proto_tree_add_none_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const gint start,
gint length, const char *format, ...)
{
proto_item *pi;
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
- proto_tree_set_protocol_tvb(new_fi, (start == 0 ? tvb : NULL));
+ proto_tree_set_protocol_tvb(new_fi, (start == 0 ? tvb : tvb_new_subset(tvb, start, length, length)));
TRY_TO_FAKE_THIS_REPR(tree, pi);
static header_field_info *
-get_hfi_and_length(int hfindex, tvbuff_t *tvb, gint start, gint *length,
+get_hfi_and_length(int hfindex, tvbuff_t *tvb, const gint start, gint *length,
gint *item_length)
{
header_field_info *hfinfo;
static field_info *
new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
- gint start, gint item_length)
+ const gint start, const gint item_length)
{
field_info *fi;
}
static field_info *
-alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
+alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb, const gint start,
gint *length)
{
header_field_info *hfinfo;
/* -------------------------- */
const gchar *
-proto_custom_set(proto_tree* tree, int field_id,
+proto_custom_set(proto_tree* tree, const int field_id,
gchar *result,
- gchar *expr, int size )
+ gchar *expr, const int size )
{
guint32 u_integer;
gint32 integer;
guint8 *bytes;
ipv4_addr *ipv4;
+ struct e_in6_addr *ipv6;
+ address addr;
guint32 n_addr; /* network-order IPv4 address */
const true_false_string *tfstring;
switch(hfinfo->type) {
+ case FT_NONE: /* Nothing to add */
+ result[0] = '\0';
+ break;
+
+ case FT_PROTOCOL:
+ g_strlcpy(result, "Yes", size);
+ break;
+
case FT_UINT_BYTES:
case FT_BYTES:
bytes = fvalue_get(&finfo->value);
break;
case FT_ABSOLUTE_TIME:
- g_strlcpy(result, abs_time_to_str(fvalue_get(&finfo->value)), size);
+ g_strlcpy(result,
+ abs_time_to_str(fvalue_get(&finfo->value), hfinfo->display),
+ size);
break;
case FT_RELATIVE_TIME:
g_strlcpy(result, ip_to_str((guint8 *)&n_addr), size);
break;
+ case FT_IPv6:
+ ipv6 = fvalue_get(&finfo->value);
+ SET_ADDRESS (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
+ address_to_str_buf(&addr, result, size);
+ break;
+
case FT_ETHER:
g_strlcpy(result, bytes_to_str_punct(fvalue_get(&finfo->value), 6, ':'), size);
break;
break;
case FT_IPXNET: /*XXX really No column custom ?*/
- case FT_IPv6:
+ case FT_PCRE:
default:
g_error("hfinfo->type %d (%s) not handled\n",
hfinfo->type,
}
void
-proto_item_set_len(proto_item *pi, gint length)
+proto_item_set_len(proto_item *pi, const gint length)
{
field_info *fi;
}
int
-proto_item_get_len(proto_item *pi)
+proto_item_get_len(const proto_item *pi)
{
field_info *fi = PITEM_FINFO(pi);
return fi ? fi->length : -1;
}
gboolean
-proto_item_set_expert_flags(proto_item *pi, int group, guint severity)
+proto_item_set_expert_flags(proto_item *pi, const int group, const guint severity)
{
if(pi == NULL || PITEM_FINFO(pi) == NULL)
return FALSE;
/* "prime" a proto_tree with a single hfid that a dfilter
* is interested in. */
void
-proto_tree_prime_hfid(proto_tree *tree _U_, gint hfid)
+proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
{
header_field_info *hfinfo;
}
proto_tree*
-proto_item_add_subtree(proto_item *pi, gint idx) {
+proto_item_add_subtree(proto_item *pi, const gint idx) {
field_info *fi;
if (!pi)
}
proto_tree*
-proto_item_get_subtree(proto_item *pi) {
+proto_item_get_subtree(const proto_item *pi) {
field_info *fi;
if (!pi)
}
proto_item*
-proto_item_get_parent(proto_item *ti) {
+proto_item_get_parent(const proto_item *ti) {
if (!ti)
return (NULL);
return ti->parent;
proto_item*
-proto_tree_get_parent(proto_tree *tree) {
+proto_tree_get_parent(const proto_tree *tree) {
if (!tree)
return (NULL);
return (proto_item*) tree;
}
void
-proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
+proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start, const gint length)
{
field_info *fi;
/* Add this protocol to the list of known protocols; the list
is sorted by protocol short name. */
- protocol = g_malloc(sizeof (protocol_t));
+ protocol = g_new(protocol_t, 1);
protocol->name = name;
protocol->short_name = short_name;
protocol->filter_name = filter_name;
protocols = g_list_prepend(protocols, protocol);
/* Here we do allocate a new header_field_info struct */
+#if GLIB_CHECK_VERSION(2,10,0)
+ hfinfo = g_slice_new(header_field_info);
+#else
hfinfo = g_mem_chunk_alloc(gmc_hfinfo);
+#endif
hfinfo->name = name;
hfinfo->abbrev = filter_name;
hfinfo->type = FT_PROTOCOL;
}
void
-proto_mark_private(int proto_id)
+proto_mark_private(const int proto_id)
{
protocol_t *protocol = find_protocol_by_id(proto_id);
if (protocol)
}
gboolean
-proto_is_private(int proto_id)
+proto_is_private(const int proto_id)
{
protocol_t *protocol = find_protocol_by_id(proto_id);
if (protocol)
}
header_field_info *
-proto_get_first_protocol_field(int proto_id, void **cookie)
+proto_get_first_protocol_field(const int proto_id, void **cookie)
{
protocol_t *protocol = find_protocol_by_id(proto_id);
hf_register_info *ptr;
}
protocol_t *
-find_protocol_by_id(int proto_id)
+find_protocol_by_id(const int proto_id)
{
header_field_info *hfinfo;
}
int
-proto_get_id(protocol_t *protocol)
+proto_get_id(const protocol_t *protocol)
{
return protocol->proto_id;
}
}
const char *
-proto_get_protocol_name(int proto_id)
+proto_get_protocol_name(const int proto_id)
{
protocol_t *protocol;
}
const char *
-proto_get_protocol_short_name(protocol_t *protocol)
+proto_get_protocol_short_name(const protocol_t *protocol)
{
if (protocol == NULL)
return "(none)";
}
const char *
-proto_get_protocol_long_name(protocol_t *protocol)
+proto_get_protocol_long_name(const protocol_t *protocol)
{
if (protocol == NULL)
return "(none)";
}
const char *
-proto_get_protocol_filter_name(int proto_id)
+proto_get_protocol_filter_name(const int proto_id)
{
protocol_t *protocol;
}
gboolean
-proto_is_protocol_enabled(protocol_t *protocol)
+proto_is_protocol_enabled(const protocol_t *protocol)
{
return protocol->is_enabled;
}
gboolean
-proto_can_toggle_protocol(int proto_id)
+proto_can_toggle_protocol(const int proto_id)
{
protocol_t *protocol;
}
void
-proto_set_decoding(int proto_id, gboolean enabled)
+proto_set_decoding(const int proto_id, const gboolean enabled)
{
protocol_t *protocol;
}
void
-proto_set_cant_toggle(int proto_id)
+proto_set_cant_toggle(const int proto_id)
{
protocol_t *protocol;
/* for use with static arrays only, since we don't allocate our own copies
of the header_field_info struct contained within the hf_register_info struct */
void
-proto_register_field_array(int parent, hf_register_info *hf, int num_records)
+proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
{
int field_id, i;
hf_register_info *ptr = hf;
case FT_BOOLEAN:
break;
+ case FT_ABSOLUTE_TIME:
+ DISSECTOR_ASSERT(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
+ hfinfo->display == ABSOLUTE_TIME_UTC ||
+ hfinfo->display == ABSOLUTE_TIME_DOY_UTC);
+ DISSECTOR_ASSERT(hfinfo->bitmask == 0);
+ DISSECTOR_ASSERT(hfinfo->strings == NULL);
+ break;
+
default:
DISSECTOR_ASSERT(hfinfo->display == BASE_NONE);
DISSECTOR_ASSERT(hfinfo->bitmask == 0);
}
static int
-proto_register_field_init(header_field_info *hfinfo, int parent)
+proto_register_field_init(header_field_info *hfinfo, const int parent)
{
tmp_fld_check_assert(hfinfo);
}
void
-proto_register_subtree_array(gint *const *indices, int num_indices)
+proto_register_subtree_array(gint *const *indices, const int num_indices)
{
int i;
gint *const *ptr = indices;
case FT_ABSOLUTE_TIME:
g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s", hfinfo->name,
- abs_time_to_str(fvalue_get(&fi->value)));
+ abs_time_to_str(fvalue_get(&fi->value), hfinfo->display));
break;
case FT_RELATIVE_TIME:
}
int
-hfinfo_bitwidth(header_field_info *hfinfo)
+hfinfo_bitwidth(const header_field_info *hfinfo)
{
int bitwidth = 0;
}
static const char*
-hfinfo_uint_vals_format(header_field_info *hfinfo)
+hfinfo_uint_vals_format(const header_field_info *hfinfo)
{
const char *format = NULL;
- /* bit operation to reset the potential BASE_RANGE_STRING (or others in
- * the future?) */
- switch(hfinfo->display & BASE_STRUCTURE_RESET) {
+ /* Get the underlying BASE_ value */
+ switch(hfinfo->display & BASE_DISPLAY_E_MASK) {
case BASE_NONE:
format = "%s: %s";
break;
format = "%s: %s (%u)";
break;
case BASE_OCT: /* I'm lazy */
- format = "%s: %s (%o)";
+ format = "%s: %s (%#o)";
break;
case BASE_HEX:
case BASE_HEX_DEC:
}
static const char*
-hfinfo_uint_format(header_field_info *hfinfo)
+hfinfo_uint_format(const header_field_info *hfinfo)
{
const char *format = NULL;
}
break;
case BASE_OCT: /* I'm lazy */
- format = "%s: %o";
+ format = "%s: %#o";
break;
case BASE_HEX:
switch(hfinfo->type) {
}
static const char*
-hfinfo_uint_value_format(header_field_info *hfinfo)
+hfinfo_uint_value_format(const header_field_info *hfinfo)
{
const char *format = NULL;
}
break;
case BASE_OCT:
- format = "%o";
+ format = "%#o";
break;
case BASE_HEX:
switch(hfinfo->type) {
}
static const char*
-hfinfo_int_vals_format(header_field_info *hfinfo)
+hfinfo_int_vals_format(const header_field_info *hfinfo)
{
const char *format = NULL;
- /* bit operation to reset the potential BASE_RANGE_STRING (or others in
- * the future?)*/
- switch(hfinfo->display & BASE_STRUCTURE_RESET) {
+ /* Get the underlying BASE_ value */
+ switch(hfinfo->display & BASE_DISPLAY_E_MASK) {
case BASE_NONE:
format = "%s: %s";
break;
format = "%s: %s (%d)";
break;
case BASE_OCT: /* I'm lazy */
- format = "%s: %s (%o)";
+ format = "%s: %s (%#o)";
break;
case BASE_HEX:
case BASE_HEX_DEC:
}
static const char*
-hfinfo_uint64_format(header_field_info *hfinfo)
+hfinfo_uint64_format(const header_field_info *hfinfo)
{
const char *format = NULL;
format = "%s: %" G_GINT64_MODIFIER "u (%" G_GINT64_MODIFIER "x)";
break;
case BASE_OCT: /* I'm lazy */
- format = "%s: %" G_GINT64_MODIFIER "o";
+ format = "%s: %#" G_GINT64_MODIFIER "o";
break;
case BASE_HEX:
format = "%s: 0x%016" G_GINT64_MODIFIER "x";
}
static const char*
-hfinfo_int_format(header_field_info *hfinfo)
+hfinfo_int_format(const header_field_info *hfinfo)
{
const char *format = NULL;
}
break;
case BASE_OCT: /* I'm lazy */
- format = "%s: %o";
+ format = "%s: %#o";
break;
case BASE_HEX:
switch(hfinfo->type) {
}
static const char*
-hfinfo_int_value_format(header_field_info *hfinfo)
+hfinfo_int_value_format(const header_field_info *hfinfo)
{
const char *format = NULL;
}
break;
case BASE_OCT:
- format = "%o";
+ format = "%#o";
break;
case BASE_HEX:
switch(hfinfo->type) {
}
static const char*
-hfinfo_int64_format(header_field_info *hfinfo)
+hfinfo_int64_format(const header_field_info *hfinfo)
{
const char *format = NULL;
format = "%s: %" G_GINT64_MODIFIER "d (%" G_GINT64_MODIFIER "x)";
break;
case BASE_OCT: /* I'm lazy */
- format = "%s: %" G_GINT64_MODIFIER "o";
+ format = "%s: %#" G_GINT64_MODIFIER "o";
break;
case BASE_HEX:
format = "%s: 0x%016" G_GINT64_MODIFIER "x";
}
const char*
-proto_registrar_get_name(int n)
+proto_registrar_get_name(const int n)
{
header_field_info *hfinfo;
}
const char*
-proto_registrar_get_abbrev(int n)
+proto_registrar_get_abbrev(const int n)
{
header_field_info *hfinfo;
}
int
-proto_registrar_get_ftype(int n)
+proto_registrar_get_ftype(const int n)
{
header_field_info *hfinfo;
}
int
-proto_registrar_get_parent(int n)
+proto_registrar_get_parent(const int n)
{
header_field_info *hfinfo;
}
gboolean
-proto_registrar_is_protocol(int n)
+proto_registrar_is_protocol(const int n)
{
header_field_info *hfinfo;
* 0 means undeterminable at time of registration
* -1 means the field is not registered. */
gint
-proto_registrar_get_length(int n)
+proto_registrar_get_length(const int n)
{
header_field_info *hfinfo;
/* Looks for a protocol or a field in a proto_tree. Returns TRUE if
* it exists anywhere, or FALSE if it exists nowhere. */
gboolean
-proto_check_for_protocol_or_field(proto_tree* tree, int id)
+proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
{
GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
* The caller should *not* free the GPtrArray*; proto_tree_free_node()
* handles that. */
GPtrArray*
-proto_get_finfo_ptr_array(proto_tree *tree, int id)
+proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
{
+ if (!tree)
+ return NULL;
+
if (PTREE_DATA(tree)->interesting_hfids != NULL)
return g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
GINT_TO_POINTER(id));
}
gboolean
-proto_tracking_interesting_fields(proto_tree *tree)
+proto_tracking_interesting_fields(const proto_tree *tree)
{
+ if (!tree)
+ return FALSE;
+
return (PTREE_DATA(tree)->interesting_hfids != NULL);
}
* g_ptr_array_free(<array>, TRUE).
*/
GPtrArray*
-proto_find_finfo(proto_tree *tree, int id)
+proto_find_finfo(proto_tree *tree, const int id)
{
ffdata_t ffdata;
} offset_search_t;
static gboolean
-check_for_offset(proto_node *node, gpointer data)
+check_for_offset(proto_node *node, const gpointer data)
{
field_info *fi = PNODE_FINFO(node);
offset_search_t *offsearch = data;
range = NULL;
tfs = NULL;
- if ((hfinfo->display & BASE_STRUCTURE_RESET) != BASE_CUSTOM &&
+ if ((hfinfo->display & BASE_DISPLAY_E_MASK) != BASE_CUSTOM &&
(hfinfo->type == FT_UINT8 ||
hfinfo->type == FT_UINT16 ||
hfinfo->type == FT_UINT24 ||
vi = 0;
while (range[vi].strptr) {
/* Print in the proper base */
- if ((hfinfo->display & BASE_STRUCTURE_RESET) == BASE_HEX) {
+ if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_HEX) {
printf("R\t%s\t0x%x\t0x%x\t%s\n",
hfinfo->abbrev,
range[vi].value_min,
* Field 8 = bitmask: format: hex: 0x....
*/
void
-proto_registrar_dump_fields(int format)
+proto_registrar_dump_fields(const int format)
{
header_field_info *hfinfo, *parent_hfinfo;
int i, len;
hfinfo->type == FT_INT64) {
- switch(hfinfo->display & BASE_STRUCTURE_RESET) {
+ switch(hfinfo->display & BASE_DISPLAY_E_MASK) {
case BASE_NONE:
base_name = "BASE_NONE";
break;
}
static const char*
-hfinfo_numeric_format(header_field_info *hfinfo)
+hfinfo_numeric_format(const header_field_info *hfinfo)
{
const char *format = NULL;
*/
format = "%s == %u";
} else {
- /* Pick the proper format string, ignoring BASE_RANGE_STRING flag */
- switch(hfinfo->display & ~BASE_RANGE_STRING) {
+ /* Get the underlying BASE_ value */
+ switch(hfinfo->display & BASE_DISPLAY_E_MASK) {
case BASE_DEC:
case BASE_DEC_HEX:
case BASE_OCT: /* I'm lazy */
DISSECTOR_ASSERT(hfinfo);
abbrev_len = (int) strlen(hfinfo->abbrev);
- if (hfinfo->strings && (hfinfo->display & BASE_STRUCTURE_RESET) == BASE_NONE) {
+ if (hfinfo->strings && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
const gchar *str = NULL;
switch(hfinfo->type) {
* proto_tree_add_bitmask_text() functions.
*/
static gboolean
-proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, int offset, int len, gint ett,
- const int **fields, gboolean little_endian, int flags, gboolean first)
+proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset, const int len, const gint ett,
+ const int **fields, const gboolean little_endian, const int flags, gboolean first)
{
guint32 value = 0, tmpval;
proto_tree *tree = NULL;
* matched string displayed on the expansion line.
*/
proto_item *
-proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb, guint offset, int hf_hdr,
- gint ett, const int **fields, gboolean little_endian)
+proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset, const int hf_hdr,
+ const gint ett, const int **fields, const gboolean little_endian)
{
proto_item *item = NULL;
header_field_info *hf;
/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
proto_item *
-proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb, guint offset, guint len,
+proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset, const guint len,
const char *name, const char *fallback,
- gint ett, const int **fields, gboolean little_endian, int flags)
+ const gint ett, const int **fields, const gboolean little_endian, const int flags)
{
proto_item *item = NULL;
}
proto_item *
-proto_tree_add_bits_item(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian)
+proto_tree_add_bits_item(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, const gboolean little_endian)
{
header_field_info *hfinfo;
return proto_tree_add_bits_ret_val(tree, hf_index, tvb, bit_offset, no_of_bits, NULL, little_endian);
}
+
/*
* This function will dissect a sequence of bits that does not need to be byte aligned; the bits
- * set vill be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
+ * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
* Offset should be given in bits from the start of the tvb.
*/
proto_item *
-proto_tree_add_bits_ret_val(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint bit_offset, gint no_of_bits, guint64 *return_value, gboolean little_endian)
+proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, guint64 *return_value, const gboolean little_endian)
{
const char *format = NULL;
gint offset;
guint length;
guint8 tot_no_bits;
- guint8 remaining_bits;
- guint64 mask = 0,tmp;
char *str;
header_field_info *hf_field;
guint64 value = 0;
- int bit;
- int i;
+ 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);
*/
tot_no_bits = ((bit_offset&0x7)+no_of_bits);
length = tot_no_bits>>3;
- remaining_bits = tot_no_bits % 8;
- if ((remaining_bits)!=0)
+ /* If we are using part of the next octet, increase length by 1 */
+ if (tot_no_bits & 0x07)
length++;
if (no_of_bits < 9){
/* Coast clear. Try and fake it */
TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
- mask = 1;
- mask = mask << (no_of_bits-1);
-
- /* prepare the string */
- str=ep_alloc(256);
- str[0]='\0';
- for(bit=0;bit<((int)(bit_offset&0x07));bit++){
- if(bit&&(!(bit%4))){
- strcat(str, " ");
- }
- strcat(str,".");
- }
-
- /* read the bits for the int */
- for(i=0;i<no_of_bits;i++){
- if(bit&&(!(bit%4))){
- strcat(str, " ");
- }
- if(bit&&(!(bit%8))){
- strcat(str, " ");
- }
- bit++;
- tmp = value & mask;
- if(tmp != 0){
- strcat(str, "1");
- } else {
- strcat(str, "0");
- }
- mask = mask>>1;
- }
-
- for(;bit%8;bit++){
- if(bit&&(!(bit%4))){
- strcat(str, " ");
- }
- strcat(str,".");
- }
+ str = decode_bits_in_field(bit_offset, no_of_bits, value);
strcat(str," = ");
strcat(str,hf_field->name);
switch(hf_field->type){
case FT_BOOLEAN:
/* Boolean field */
- if (hf_field->strings) {
- const true_false_string *tfstring =
- (const true_false_string *) hf_field->strings;
- return proto_tree_add_boolean_format(tree, hf_index, tvb, offset, length, (guint32)value,
- "%s: %s",
- str,
- (guint32)value ? tfstring->true_string : tfstring->false_string);
- }else{
- return proto_tree_add_boolean_format(tree, hf_index, tvb, offset, length, (guint32)value,
- "%s: %u",
- str,
- (guint32)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,
+ "%s: %s",
+ str,
+ (guint32)value ? tfstring->true_string : tfstring->false_string);
break;
case FT_UINT8:
}
}
+proto_item *
+proto_tree_add_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, void *value_ptr, gchar *value_str)
+{
+ gint offset;
+ guint length;
+ guint8 tot_no_bits;
+ char *str;
+ header_field_info *hf_field;
+ guint64 value = 0;
+
+ /* 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);
+
+ if(hf_field -> bitmask != 0) {
+ REPORT_DISSECTOR_BUG(ep_strdup_printf("Incompatible use of proto_tree_add_bits_ret_val with field '%s' (%s) with bitmask != 0",
+ hf_field->abbrev, hf_field->name));
+ }
+
+ DISSECTOR_ASSERT(bit_offset >= 0);
+ DISSECTOR_ASSERT(no_of_bits > 0);
+
+ /* Byte align offset */
+ offset = bit_offset>>3;
+
+ /*
+ * 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++;
+
+ if (no_of_bits < 9){
+ value = tvb_get_bits8(tvb, bit_offset, no_of_bits);
+ }else if(no_of_bits < 17){
+ value = tvb_get_bits16(tvb, bit_offset, no_of_bits, FALSE);
+ }else if(no_of_bits < 33){
+ value = tvb_get_bits32(tvb, bit_offset, no_of_bits, FALSE);
+ }else if(no_of_bits < 65){
+ value = tvb_get_bits64(tvb, bit_offset, no_of_bits, FALSE);
+ }else{
+ DISSECTOR_ASSERT_NOT_REACHED();
+ return NULL;
+ }
+
+ str = decode_bits_in_field(bit_offset, no_of_bits, value);
+
+ strcat(str," = ");
+ strcat(str,hf_field->name);
+
+ /*
+ * This function does not receive an actual value but a dimensionless pointer to that value.
+ * For this reason, the type of the header field is examined in order to determine
+ * what kind of value we should read from this address.
+ * The caller of this function must make sure that for the specific header field type the address of
+ * a compatible value is provided.
+ */
+ switch(hf_field->type){
+ case FT_BOOLEAN:
+ return proto_tree_add_boolean_format(tree, hf_index, tvb, offset, length, *(guint32 *)value_ptr,
+ "%s: %s", str, value_str);
+ break;
+
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ return proto_tree_add_uint_format(tree, hf_index, 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,
+ "%s: %s", str, value_str);
+ break;
+
+ case FT_INT8:
+ case FT_INT16:
+ case FT_INT24:
+ case FT_INT32:
+ return proto_tree_add_int_format(tree, hf_index, tvb, offset, length, *(gint32 *)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,
+ "%s: %s", str, value_str);
+ break;
+
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ return NULL;
+ break;
+ }
+}
+
+#define CREATE_VALUE_STRING(dst,format,ap) \
+ va_start(ap,format); \
+ dst = ep_strdup_vprintf(format, ap); \
+ va_end(ap);
+
+proto_item *
+proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits,
+ guint32 value, const char *format, ...)
+{
+ va_list ap;
+ gchar* dst;
+ header_field_info *hf_field;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+
+ switch(hf_field->type){
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ break;
+
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ return NULL;
+ break;
+ }
+
+ CREATE_VALUE_STRING(dst,format,ap);
+
+ return proto_tree_add_bits_format_value(tree, hf_index, tvb, bit_offset, no_of_bits, &value, dst);
+}
+
+proto_item *
+proto_tree_add_float_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits,
+ float value, const char *format, ...)
+{
+ va_list ap;
+ gchar* dst;
+ header_field_info *hf_field;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hf_index, 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);
+}
+
+proto_item *
+proto_tree_add_int_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits,
+ gint32 value, const char *format, ...)
+{
+ va_list ap;
+ gchar* dst;
+ header_field_info *hf_field;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
+
+ switch(hf_field->type){
+ case FT_INT8:
+ case FT_INT16:
+ case FT_INT24:
+ case FT_INT32:
+ break;
+
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ return NULL;
+ break;
+ }
+
+ CREATE_VALUE_STRING(dst,format,ap);
+
+ return proto_tree_add_bits_format_value(tree, hf_index, tvb, bit_offset, no_of_bits, &value, dst);
+}
+
+proto_item *
+proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits,
+ guint32 value, const char *format, ...)
+{
+ va_list ap;
+ gchar* dst;
+ header_field_info *hf_field;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hf_index, 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);
+}
+
guchar
proto_check_field_name(const gchar *field_name)
{
return wrs_check_charset(fld_abbrev_chars, field_name);
}
-