#include "charsets.h"
#include "asm_utils.h"
#include "column-utils.h"
+#include "to_str.h"
+
+#include "wspython/wspy_register.h"
#define SUBTREE_ONCE_ALLOCATION_NUMBER 8
#define SUBTREE_MAX_LEVELS 256
+/* Throw an exception if we exceed this many tree items. */
+/* XXX - This should probably be a preference */
+#define MAX_TREE_ITEMS (1 * 1000 * 1000)
typedef struct __subtree_lvl {
};
/* Candidates for assembler */
-int
-wrs_count_bitshift(guint32 bitmask)
+static int
+wrs_count_bitshift(const guint32 bitmask)
{
int bitshift = 0;
return bitshift;
}
-
-
#define cVALS(x) (const value_string*)(x)
-#if 1
-#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex) \
+/** See inlined comments.
+ @param tree the tree to append this item to
+ @param hfindex field index
+ @param hfinfo header_field
+ @return the header field matching 'hfinfo' */
+#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
/* If this item is not referenced we dont have to do much work \
at all but we should still return a node so that \
field items below this node ( think proto_item_add_subtree() )\
will still have somewhere to attach to \
or else filtering will not work (they would be ignored since tree\
would be NULL). \
- DONT try to fake a node where PITEM_FINFO(pi) is NULL \
- since dissectors that want to do proto_item_set_len() or \
- other operations that dereference this would crash. \
- We dont fake FT_PROTOCOL either since these are cheap and \
- some stuff (proto hier stat) assumes they always exist. \
+ We fake FT_PROTOCOL unless some clients have requested us \
+ not to do so. \
*/ \
+ if (!tree) \
+ return(NULL); \
+ PTREE_DATA(tree)->count++; \
+ if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
+ /* Let the exception handler add items to the tree */ \
+ PTREE_DATA(tree)->count = 0; \
+ THROW_MESSAGE(DissectorError, \
+ ep_strdup_printf("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
+ } \
+ PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
if(!(PTREE_DATA(tree)->visible)){ \
- if(PITEM_FINFO(tree)){ \
- register header_field_info *hfinfo; \
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
- if((hfinfo->ref_count == 0) \
- && (hfinfo->type!=FT_PROTOCOL)){ \
+ if((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
+ && (hfinfo->type!=FT_PROTOCOL || \
+ PTREE_DATA(tree)->fake_protocols)){ \
/* just return tree back to the caller */\
return tree; \
} \
- } \
+ }
+
+/** See inlined comments.
+ @param tree the tree to append this item to
+ @param pi the created protocol item we're about to return */
+#if 1
+#define TRY_TO_FAKE_THIS_REPR(tree, pi) \
+ DISSECTOR_ASSERT(tree); \
+ if(!(PTREE_DATA(tree)->visible)) { \
+ /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
+ * items string representation */ \
+ return pi; \
}
#else
-#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex) ;
+#define TRY_TO_FAKE_THIS_REPR(tree, pi)
#endif
static gboolean
static void fill_label_int(field_info *fi, gchar *label_str);
static void fill_label_int64(field_info *fi, gchar *label_str);
-int hfinfo_bitwidth(header_field_info *hfinfo);
-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,
- gint *item_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,
- gint start, gint *length, field_info **pfi);
+ gint start, gint *length, field_info **pfi);
static void
proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
static void
proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
static void
-proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start);
+proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
static void
proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
static void
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;
{
static hf_register_info hf[] = {
{ &hf_text_only,
- { "Text item", "", FT_NONE, BASE_NONE, NULL, 0x0,
+ { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
};
+ proto_cleanup();
- proto_names = g_hash_table_new(g_int_hash, g_int_equal);
+ proto_names = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
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);
- proto_cleanup();
-
+#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);
+ INITIAL_NUM_PROTOCOL_HFINFO * sizeof(header_field_info),
+ G_ALLOC_ONLY);
+#endif
gpa_hfinfo.len=0;
gpa_hfinfo.allocated_len=0;
handle, and do whatever one-time initialization it needs to
do. */
register_all_protocols_func(cb, client_data);
+#ifdef HAVE_PYTHON
+ /* Now scan for python protocols */
+ register_all_py_protocols_func(cb, client_data);
+#endif
#ifdef HAVE_PLUGINS
/* Now scan for plugins and load all the ones we find, calling
they need. */
register_all_handoffs_func(cb, client_data);
+#ifdef HAVE_PYTHON
+ /* Now do the same with python dissectors */
+ register_all_py_handoffs_func(cb, client_data);
+#endif
+
#ifdef HAVE_PLUGINS
/* Now do the same with plugins. */
if(cb)
/* 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
gpa_name_tree = NULL;
}
- if (gmc_hfinfo)
+ 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);
+ g_free(protocol);
+ }
+
+ if (proto_names) {
+ g_hash_table_destroy(proto_names);
+ proto_names = NULL;
+ }
+
+ if (proto_short_names) {
+ g_hash_table_destroy(proto_short_names);
+ proto_short_names = NULL;
+ }
+
+ if (proto_filter_names) {
+ g_hash_table_destroy(proto_filter_names);
+ 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;
g_free(gpa_hfinfo.hfi);
gpa_hfinfo.hfi=NULL;
}
- if (tree_is_expanded != NULL)
- g_free(tree_is_expanded);
-
+ g_free(tree_is_expanded);
+ tree_is_expanded = NULL;
}
static gboolean
proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
- gpointer data)
+ gpointer data)
{
proto_node *pnode = tree;
proto_node *child;
current = child;
child = current->next;
if (proto_tree_traverse_pre_order((proto_tree *)current, func,
- data))
+ data))
return TRUE;
}
gboolean
proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
- gpointer data)
+ gpointer data)
{
proto_node *pnode = tree;
proto_node *child;
current = child;
child = current->next;
if (proto_tree_traverse_post_order((proto_tree *)current, func,
- data))
+ data))
return TRUE;
}
if (func(pnode, data))
void
proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
- gpointer data)
+ gpointer data)
{
proto_node *node = tree;
proto_node *current;
static void
free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
{
- GPtrArray *ptrs = value;
+ GPtrArray *ptrs = value;
gint hfid = (gint)(long)key;
header_field_info *hfinfo;
-
PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
- if(hfinfo->ref_count){
+ if(hfinfo->ref_type != HF_REF_TYPE_NONE) {
/* when a field is referenced by a filter this also
affects the refcount for the parent protocol so we need
to adjust the refcount for the parent as well
*/
- if( (hfinfo->parent != -1) && (hfinfo->ref_count) ){
+ if( hfinfo->parent != -1 ) {
header_field_info *parent_hfinfo;
PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
- parent_hfinfo->ref_count -= hfinfo->ref_count;
+ parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
}
- hfinfo->ref_count = 0;
+ hfinfo->ref_type = HF_REF_TYPE_NONE;
}
g_ptr_array_free(ptrs, TRUE);
static void
free_node_tree_data(tree_data_t *tree_data)
{
- /* Free all the GPtrArray's in the interesting_hfids hash. */
- g_hash_table_foreach(tree_data->interesting_hfids,
- free_GPtrArray_value, NULL);
+ if (tree_data->interesting_hfids) {
+ /* Free all the GPtrArray's in the interesting_hfids hash. */
+ g_hash_table_foreach(tree_data->interesting_hfids,
+ free_GPtrArray_value, NULL);
- /* And then destroy the hash. */
- g_hash_table_destroy(tree_data->interesting_hfids);
+ /* And then destroy the hash. */
+ g_hash_table_destroy(tree_data->interesting_hfids);
+ }
- /* And finally the tree_data_t itself. */
- g_free(tree_data);
+ /* And finally the tree_data_t itself. */
+ g_free(tree_data);
}
#define FREE_NODE_FIELD_INFO(finfo) \
static gboolean
proto_tree_free_node(proto_node *node, gpointer data _U_)
{
- field_info *finfo = PITEM_FINFO(node);
+ field_info *finfo = PNODE_FINFO(node);
#if 0
proto_node *parent = node->parent;
#endif
* By setting this correctly, the proto_tree creation is sped up by not
* having to call g_vsnprintf and copy strings around.
*/
-void
+gboolean
proto_tree_set_visible(proto_tree *tree, gboolean visible)
{
+ gboolean old_visible = PTREE_DATA(tree)->visible;
+
PTREE_DATA(tree)->visible = visible;
+
+ return old_visible;
+}
+
+void
+proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
+{
+ PTREE_DATA(tree)->fake_protocols = fake_protocols;
}
/* Assume dissector set only its protocol fields.
- This function is called by dissectors and allowes to speed up filtering
- in wireshark, if this function returns FALSE it is safe to reset tree to NULL
+ This function is called by dissectors and allows the speeding up of filtering
+ in wireshark; if this function returns FALSE it is safe to reset tree to NULL
and thus skip calling most of the expensive proto_tree_add_...()
functions.
- If the tree is visible we implicitely assume the field is referenced.
+ If the tree is visible we implicitly assume the field is referenced.
*/
gboolean
proto_field_is_referenced(proto_tree *tree, int proto_id)
return TRUE;
PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
- if (hfinfo->ref_count != 0)
+ if (hfinfo->ref_type != HF_REF_TYPE_NONE)
+ return TRUE;
+
+ if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
return TRUE;
return FALSE;
}
-/* Prefix initialization
- * this allows for a dissector to register a display filter name prefix
- * so that it can delay the initialization of the hf array as long as
- * possible.
+/* Prefix initialization
+ * this allows for a dissector to register a display filter name prefix
+ * so that it can delay the initialization of the hf array as long as
+ * possible.
*/
/* compute a hash for the part before the dot of a display filter */
-static guint prefix_hash (gconstpointer key) {
+static guint
+prefix_hash (gconstpointer key) {
/* end the string at the dot and compute its hash */
gchar* copy = ep_strdup(key);
gchar* c = copy;
break;
}
}
-
+
return g_str_hash(copy);
}
/* are both strings equal up to the end or the dot? */
-static gboolean prefix_equal (gconstpointer ap,gconstpointer bp) {
+static gboolean
+prefix_equal (gconstpointer ap,gconstpointer bp) {
const gchar* a = ap;
const gchar* b = bp;
-
+
do {
gchar ac = *a++;
gchar bc = *b++;
-
+
if ((ac == '.' || ac == '\0') && (bc == '.' || bc == '\0')) return TRUE;
-
+
if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
-
+
if (ac != bc) return FALSE;
} while(1);
-
+
return FALSE;
}
if (! prefixes ) {
prefixes = g_hash_table_new(prefix_hash,prefix_equal);
}
-
+
g_hash_table_insert(prefixes,(gpointer)prefix,pi);
}
/* helper to call all prefix initializers */
-static gboolean initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
+static gboolean
+initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
((prefix_initializer_t)v)(k);
return TRUE;
}
/** Initialize every remaining uninitialized prefix. */
-void proto_initialize_all_prefixes(void) {
+void
+proto_initialize_all_prefixes(void) {
g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
}
{
header_field_info* hfinfo;
prefix_initializer_t pi;
-
- DISSECTOR_ASSERT(field_name != NULL);
+
+ if (!field_name)
+ return NULL;
hfinfo = g_tree_lookup(gpa_name_tree, field_name);
-
+
if (hfinfo) return hfinfo;
-
- if (!prefixes) return NULL;
-
+
+ if (!prefixes) return NULL;
+
if(( pi = g_hash_table_lookup(prefixes,field_name) )) {
pi(field_name);
g_hash_table_remove(prefixes,field_name);
} else {
return NULL;
}
-
+
return g_tree_lookup(gpa_name_tree, field_name);
}
-void ptvcursor_new_subtree_levels(ptvcursor_t * ptvc)
+void
+ptvcursor_new_subtree_levels(ptvcursor_t * ptvc)
{
- subtree_lvl * pushed_tree;
+ subtree_lvl * pushed_tree;
- DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
- ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
+ DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
+ ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
- pushed_tree = ep_alloc(sizeof(subtree_lvl) * ptvc->pushed_tree_max);
- DISSECTOR_ASSERT(pushed_tree != NULL);
- if (ptvc->pushed_tree)
- memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
- ptvc->pushed_tree = pushed_tree;
+ pushed_tree = ep_alloc(sizeof(subtree_lvl) * ptvc->pushed_tree_max);
+ DISSECTOR_ASSERT(pushed_tree != NULL);
+ if (ptvc->pushed_tree)
+ memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
+ ptvc->pushed_tree = pushed_tree;
}
-void ptvcursor_free_subtree_levels(ptvcursor_t * ptvc)
+void
+ptvcursor_free_subtree_levels(ptvcursor_t * ptvc)
{
- ptvc->pushed_tree = NULL;
- ptvc->pushed_tree_max = 0;
- DISSECTOR_ASSERT(ptvc->pushed_tree_index ==0);
- ptvc->pushed_tree_index = 0;
+ ptvc->pushed_tree = NULL;
+ ptvc->pushed_tree_max = 0;
+ DISSECTOR_ASSERT(ptvc->pushed_tree_index ==0);
+ ptvc->pushed_tree_index = 0;
}
/* Allocates an initializes a ptvcursor_t with 3 variables:
- * proto_tree, tvbuff, and offset. */
+ * proto_tree, tvbuff, and offset. */
ptvcursor_t*
ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
{
proto_tree*
ptvcursor_tree(ptvcursor_t* ptvc)
{
- if (!ptvc)
- return NULL;
+ if (!ptvc)
+ return NULL;
- return ptvc->tree;
+ return ptvc->tree;
}
void
proto_tree*
ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
{
- subtree_lvl * subtree;
- if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
- ptvcursor_new_subtree_levels(ptvc);
+ subtree_lvl * subtree;
+ if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
+ ptvcursor_new_subtree_levels(ptvc);
- subtree = ptvc->pushed_tree+ptvc->pushed_tree_index;
- subtree->tree = ptvc->tree;
- subtree->it= NULL;
- ptvc->pushed_tree_index++;
- return ptvcursor_set_subtree(ptvc, it, ett_subtree);
+ subtree = ptvc->pushed_tree+ptvc->pushed_tree_index;
+ subtree->tree = ptvc->tree;
+ subtree->it= NULL;
+ ptvc->pushed_tree_index++;
+ return ptvcursor_set_subtree(ptvc, it, ett_subtree);
}
/* pops a subtree */
void
ptvcursor_pop_subtree(ptvcursor_t *ptvc)
{
- subtree_lvl * subtree;
- if (ptvc->pushed_tree_index <= 0)
- return;
+ subtree_lvl * subtree;
+ if (ptvc->pushed_tree_index <= 0)
+ return;
- ptvc->pushed_tree_index--;
- subtree = ptvc->pushed_tree+ptvc->pushed_tree_index;
- if (subtree->it != NULL)
- proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
- ptvc->tree = subtree->tree;
+ ptvc->pushed_tree_index--;
+ subtree = ptvc->pushed_tree+ptvc->pushed_tree_index;
+ if (subtree->it != NULL)
+ proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
+
+ ptvc->tree = subtree->tree;
}
/* saves the current tvb offset and the item in the current subtree level */
static void
ptvcursor_subtree_set_item(ptvcursor_t * ptvc, proto_item * it)
{
- subtree_lvl * subtree;
+ subtree_lvl * subtree;
- DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
+ DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
- subtree = ptvc->pushed_tree+ptvc->pushed_tree_index-1;
- subtree->it = it;
- subtree->cursor_offset = ptvcursor_current_offset(ptvc);
+ subtree = ptvc->pushed_tree+ptvc->pushed_tree_index-1;
+ subtree->it = it;
+ subtree->cursor_offset = ptvcursor_current_offset(ptvc);
}
/* Creates a subtree and adds it to the cursor as the working tree but does not
proto_tree*
ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
{
- ptvc->tree = proto_item_add_subtree(it, ett_subtree);
- return ptvc->tree;
+ ptvc->tree = proto_item_add_subtree(it, ett_subtree);
+ return ptvc->tree;
}
-proto_tree* ptvcursor_add_subtree_item(ptvcursor_t * ptvc, proto_item * it, gint ett_subtree, gint length)
+proto_tree*
+ptvcursor_add_subtree_item(ptvcursor_t * ptvc, proto_item * it, gint ett_subtree, gint length)
{
- ptvcursor_push_subtree(ptvc, it, ett_subtree);
- if (length == SUBTREE_UNDEFINED_LENGTH)
- ptvcursor_subtree_set_item(ptvc, it);
- return ptvcursor_tree(ptvc);
+ ptvcursor_push_subtree(ptvc, it, ett_subtree);
+ if (length == SUBTREE_UNDEFINED_LENGTH)
+ ptvcursor_subtree_set_item(ptvc, it);
+ return ptvcursor_tree(ptvc);
}
/* Add an item to the tree and create a subtree
* In this case, when the subtree will be closed, the parent item length will
* be equal to the advancement of the cursor since the creation of the subtree.
*/
-proto_tree* ptvcursor_add_with_subtree(ptvcursor_t * ptvc, int hfindex, gint length,
-gboolean little_endian, gint ett_subtree)
+proto_tree*
+ptvcursor_add_with_subtree(ptvcursor_t * ptvc, int hfindex, gint length,
+ gboolean little_endian, gint ett_subtree)
{
- proto_item * it;
- it = ptvcursor_add_no_advance(ptvc, hfindex, length, little_endian);
- return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
+ proto_item * it;
+
+ it = ptvcursor_add_no_advance(ptvc, hfindex, length, little_endian);
+ return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
}
static proto_item *
* In this case, when the subtree will be closed, the item length will be equal
* to the advancement of the cursor since the creation of the subtree.
*/
-proto_tree * ptvcursor_add_text_with_subtree(ptvcursor_t * ptvc, gint length,
- gint ett_subtree, const char *format, ...)
+proto_tree *
+ptvcursor_add_text_with_subtree(ptvcursor_t * ptvc, gint length,
+ gint ett_subtree, const char *format, ...)
{
- proto_item * it;
- va_list ap;
+ proto_item * it;
+ va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(ptvcursor_tree(ptvc), hf_text_only, hfinfo);
+
+ it = proto_tree_add_text_node(ptvcursor_tree(ptvc), ptvcursor_tvbuff(ptvc),
+ ptvcursor_current_offset(ptvc), length);
- it = proto_tree_add_text_node(ptvcursor_tree(ptvc), ptvcursor_tvbuff(ptvc),
- ptvcursor_current_offset(ptvc), length);
+ if (it == NULL)
+ return(NULL);
- va_start(ap, format);
- proto_tree_set_representation(it, format, ap);
- va_end(ap);
+ va_start(ap, format);
+ proto_tree_set_representation(it, format, ap);
+ va_end(ap);
- return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
+ return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
}
/* Add a text-only node, leaving it to our caller to fill the text in */
/* Add a text-only node to the proto_tree */
proto_item *
proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
- const char *format, ...)
+ const char *format, ...)
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
pi = proto_tree_add_text_node(tree, tvb, start, length);
if (pi == NULL)
return(NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
/* Add a text-only node to the proto_tree (va_list version) */
proto_item *
proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start,
- gint length, const char *format, va_list ap)
+ gint length, const char *format, va_list ap)
{
proto_item *pi;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
pi = proto_tree_add_text_node(tree, tvb, start, length);
if (pi == NULL)
return(NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
proto_tree_set_representation(pi, format, ap);
return pi;
case 2:
value = little_endian ? tvb_get_letohs(tvb, offset)
- : tvb_get_ntohs(tvb, offset);
+ : tvb_get_ntohs(tvb, offset);
break;
case 3:
value = little_endian ? tvb_get_letoh24(tvb, offset)
- : tvb_get_ntoh24(tvb, offset);
+ : tvb_get_ntoh24(tvb, offset);
break;
case 4:
value = little_endian ? tvb_get_letohl(tvb, offset)
- : tvb_get_ntohl(tvb, offset);
+ : tvb_get_ntohl(tvb, offset);
break;
default:
case 3:
value = little_endian ? tvb_get_letoh24(tvb, offset)
- : tvb_get_ntoh24(tvb, offset);
+ : tvb_get_ntoh24(tvb, offset);
if (value & 0x00800000) {
/* Sign bit is set; sign-extend it. */
value |= 0xFF000000;
case 4:
value = little_endian ? tvb_get_letohl(tvb, offset)
- : tvb_get_ntohl(tvb, offset);
+ : tvb_get_ntohl(tvb, offset);
break;
default:
return value;
}
+static GPtrArray *proto_lookup_or_create_interesting_hfids(proto_tree *tree,
+ header_field_info *hfinfo)
+{
+ GPtrArray *ptrs = NULL;
+
+ DISSECTOR_ASSERT(tree);
+ DISSECTOR_ASSERT(hfinfo);
+
+ if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
+ if (PTREE_DATA(tree)->interesting_hfids == NULL) {
+ /* Initialize the hash because we now know that it is needed */
+ PTREE_DATA(tree)->interesting_hfids =
+ g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
+ }
+
+ ptrs = g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
+ GINT_TO_POINTER(hfinfo->id));
+ if (!ptrs) {
+ /* First element triggers the creation of pointer array */
+ ptrs = g_ptr_array_new();
+ g_hash_table_insert(PTREE_DATA(tree)->interesting_hfids,
+ GINT_TO_POINTER(hfinfo->id), ptrs);
+ }
+ }
+
+ return ptrs;
+}
+
/* 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. */
static proto_item *
-proto_tree_new_item(field_info *new_fi, proto_tree *tree, int hfindex,
- tvbuff_t *tvb, gint start, gint length, gboolean little_endian)
+proto_tree_new_item(field_info *new_fi, proto_tree *tree,
+ tvbuff_t *tvb, gint start, gint length, gboolean little_endian)
{
proto_item *pi;
guint32 value, n;
float floatval;
double doubleval;
char *string;
- GHashTable *hash;
GPtrArray *ptrs;
/* there is a possibility here that we might raise an exception
case FT_BOOLEAN:
proto_tree_set_boolean(new_fi,
- get_uint_value(tvb, start, length, little_endian));
+ get_uint_value(tvb, start, length, little_endian));
break;
/* XXX - make these just FT_UINT? */
case FT_UINT24:
case FT_UINT32:
proto_tree_set_uint(new_fi,
- get_uint_value(tvb, start, length, little_endian));
+ get_uint_value(tvb, start, length, little_endian));
break;
case FT_INT64:
case FT_INT24:
case FT_INT32:
proto_tree_set_int(new_fi,
- get_int_value(tvb, start, length, little_endian));
+ get_int_value(tvb, start, length, little_endian));
break;
case FT_IPv4:
- DISSECTOR_ASSERT(length == 4);
+ DISSECTOR_ASSERT(length == FT_IPv4_LEN);
value = tvb_get_ipv4(tvb, start);
proto_tree_set_ipv4(new_fi, little_endian ? GUINT32_SWAP_LE_BE(value) : value);
break;
case FT_IPXNET:
- DISSECTOR_ASSERT(length == 4);
+ DISSECTOR_ASSERT(length == FT_IPXNET_LEN);
proto_tree_set_ipxnet(new_fi,
- get_uint_value(tvb, start, 4, FALSE));
+ get_uint_value(tvb, start, 4, FALSE));
break;
case FT_IPv6:
- DISSECTOR_ASSERT(length == 16);
- proto_tree_set_ipv6_tvb(new_fi, tvb, start);
+ DISSECTOR_ASSERT(length >=0 && length <= FT_IPv6_LEN);
+ proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
break;
case FT_ETHER:
- DISSECTOR_ASSERT(length == 6);
+ DISSECTOR_ASSERT(length == FT_ETHER_LEN);
proto_tree_set_ether_tvb(new_fi, tvb, start);
break;
case FT_GUID:
- DISSECTOR_ASSERT(length == 16);
+ DISSECTOR_ASSERT(length == FT_GUID_LEN);
proto_tree_set_guid_tvb(new_fi, tvb, start, little_endian);
break;
* '\0' there, as the packet might
* be malformed. (XXX - should we
* throw an exception if there's no
- * trailing '\0'?) Therefore, we
+ * trailing '\0'?) Therefore, we
* allocate a buffer of length
* "length+1", and put in a trailing
* '\0', just to be safe.
proto_tree_set_string(new_fi, string);
break;
- case FT_EBCDIC:
+ case FT_EBCDIC:
proto_tree_set_ebcdic_string_tvb(new_fi, tvb, start, length);
break;
/* If the proto_tree wants to keep a record of this finfo
* for quick lookup, then record it. */
- if (new_fi->hfinfo->ref_count) {
- /*HERE*/
- hash = PTREE_DATA(tree)->interesting_hfids;
- ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
- if (ptrs) {
- g_ptr_array_add(ptrs, new_fi);
- }
- }
+ ptrs = proto_lookup_or_create_interesting_hfids(tree, new_fi->hfinfo);
+ if (ptrs)
+ g_ptr_array_add(ptrs, new_fi);
return pi;
}
and returns proto_item* */
proto_item*
ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
- gboolean little_endian)
+ gboolean little_endian)
{
field_info *new_fi;
header_field_info *hfinfo;
guint32 n;
int offset;
+ /* We can't fake it just yet. We have to advance the cursor
+ TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo); */
+
offset = ptvc->offset;
hfinfo = get_hfi_and_length(hfindex, ptvc->tvb, offset, &length,
- &item_length);
+ &item_length);
ptvc->offset += length;
if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
/*
n = get_uint_value(ptvc->tvb, offset, length, little_endian);
ptvc->offset += n;
}
- if (ptvc->tree == NULL)
- return NULL;
- TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex);
+ /* Coast clear. Try and fake it */
+ TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
- new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset,
- item_length);
+ new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
if (new_fi == NULL)
return NULL;
- return proto_tree_new_item(new_fi, ptvc->tree, hfindex, ptvc->tvb,
- offset, length, little_endian);
+ return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
+ offset, length, little_endian);
}
/* 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;
- if (!tree)
- return(NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
new_fi = alloc_field_info(tree, hfindex, tvb, start, &length);
if (new_fi == NULL)
return(NULL);
- return proto_tree_new_item(new_fi, tree, hfindex, tvb, start,
- length, little_endian);
+ return proto_tree_new_item(new_fi, tree, tvb, start,
+ length, little_endian);
}
/* 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;
va_list ap;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_NONE);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
* offset, and returns proto_item* */
proto_item*
ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
- gboolean endianness)
+ gboolean endianness)
{
proto_item *item;
item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
- length, endianness);
+ length, endianness);
return item;
}
{
proto_item *pi;
va_list ap;
- header_field_info *hfinfo;
field_info *new_fi;
+ header_field_info *hfinfo;
- if (!tree)
- return (NULL);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
+ proto_tree_set_protocol_tvb(new_fi, (start == 0 ? tvb : tvb_new_subset(tvb, start, length, length)));
+
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
- if (start == 0) {
- proto_tree_set_protocol_tvb(new_fi, tvb);
- }
- else {
- proto_tree_set_protocol_tvb(new_fi, NULL);
- }
return pi;
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_BYTES);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
if (length > 0) {
g_byte_array_append(bytes, start_ptr, length);
}
- col_custom_set_fstr(fi->hfinfo, "%s", bytes_to_str(bytes->data,
- length));
fvalue_set(&fi->value, bytes, TRUE);
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_ABSOLUTE_TIME ||
hfinfo->type == FT_RELATIVE_TIME);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
static void
proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
{
- header_field_info *hfinfo;
-
DISSECTOR_ASSERT(value_ptr != NULL);
- hfinfo = fi->hfinfo;
- if (hfinfo->type == FT_ABSOLUTE_TIME) {
- col_custom_set_fstr(fi->hfinfo, "%s", abs_time_to_str(value_ptr));
- } else if (hfinfo->type == FT_RELATIVE_TIME) {
- col_custom_set_fstr(fi->hfinfo, "%s", rel_time_to_secs_str(value_ptr));
- }
fvalue_set(&fi->value, value_ptr, FALSE);
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_IPXNET);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
-
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_IPv4);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
static void
proto_tree_set_ipv4(field_info *fi, guint32 value)
{
- col_custom_set_fstr(fi->hfinfo, "%s",
- ip_to_str((guint8 *)&value));
fvalue_set_uinteger(&fi->value, value);
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_IPv6);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
}
static void
-proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start)
+proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
{
- proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, 16));
+ proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
}
/* Add a FT_GUID to a proto_tree */
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_GUID);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
{
DISSECTOR_ASSERT(value_ptr != NULL);
- col_custom_set_fstr(fi->hfinfo, "%s",
- guid_to_str(value_ptr));
fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
-
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_OID);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
if (length > 0) {
g_byte_array_append(bytes, value_ptr, length);
}
- col_custom_set_fstr(fi->hfinfo, "%s",
- oid_resolved_from_encoded(value_ptr, length));
fvalue_set(&fi->value, bytes, TRUE);
}
static void
proto_tree_set_uint64(field_info *fi, guint64 value)
{
- col_custom_set_fstr(fi->hfinfo, "%" G_GINT64_MODIFIER "u",
- value);
fvalue_set_integer64(&fi->value, value);
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
return;
fi = PITEM_FINFO(pi);
+ DISSECTOR_ASSERT(fi && "proto_tree_set_visible(tree, TRUE) should have been called previously");
+
hfinfo = fi->hfinfo;
if (hfinfo->type == FT_PROTOCOL) {
/* TRY_TO_FAKE_THIS_ITEM() speed optimization: silently skip */
proto_tree_set_string(field_info *fi, const char* value)
{
if (value) {
- col_custom_set_fstr(fi->hfinfo, "%s",
- format_text(value, strlen(value)));
fvalue_set(&fi->value, (gpointer) value, FALSE);
} else {
- col_custom_set_fstr(fi->hfinfo, "[ Null ]");
fvalue_set(&fi->value, (gpointer) "[ Null ]", FALSE);
}
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_ETHER);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
static void
proto_tree_set_ether(field_info *fi, const guint8* value)
{
- col_custom_set_fstr(fi->hfinfo, "%s", bytes_to_str_punct(value, 6, ':'));
fvalue_set(&fi->value, (gpointer) value, FALSE);
}
static void
proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
{
- proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, 6));
+ proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
}
/* Add a FT_BOOLEAN to a proto_tree */
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_BOOLEAN);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_FLOAT);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
static void
proto_tree_set_float(field_info *fi, float value)
{
- col_custom_set_fstr(fi->hfinfo, "%." STRINGIFY(FLT_DIG) "f",
- value);
fvalue_set_floating(&fi->value, value);
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
-
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_DOUBLE);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
static void
proto_tree_set_double(field_info *fi, double value)
{
- col_custom_set_fstr(fi->hfinfo, "%." STRINGIFY(DBL_DIG) "g",
- value);
fvalue_set_floating(&fi->value, value);
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
-
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
switch(hfinfo->type) {
case FT_UINT8:
case FT_UINT16:
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
}
}
- if (hfinfo->type == FT_BOOLEAN) {
- const true_false_string *tfstring = &tfs_true_false;
- if (hfinfo->strings) {
- tfstring = (const struct true_false_string*) hfinfo->strings;
- }
- col_custom_set_fstr(fi->hfinfo, "%s", integer ? tfstring->true_string : tfstring->false_string);
- } else if (hfinfo->strings) {
- if (hfinfo->display & BASE_RANGE_STRING) {
- col_custom_set_fstr(fi->hfinfo, "%s", rval_to_str(integer, hfinfo->strings, "%u"));
- } else {
- col_custom_set_fstr(fi->hfinfo, "%s", val_to_str(integer, cVALS(hfinfo->strings), "%u"));
- }
- } else if (IS_BASE_DUAL(hfinfo->display)) {
- col_custom_set_fstr(fi->hfinfo, hfinfo_uint_value_format(hfinfo), integer, integer);
- } else {
- col_custom_set_fstr(fi->hfinfo, hfinfo_uint_value_format(hfinfo), integer);
- }
fvalue_set_uinteger(&fi->value, integer);
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
switch(hfinfo->type) {
case FT_INT8:
case FT_INT16:
{
proto_item *pi = NULL;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi = NULL;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
}
}
- if (hfinfo->strings) {
- if (hfinfo->display & BASE_RANGE_STRING) {
- col_custom_set_fstr(fi->hfinfo, "%s", rval_to_str(integer, hfinfo->strings, "%d"));
- } else {
- col_custom_set_fstr(fi->hfinfo, "%s", val_to_str(integer, cVALS(hfinfo->strings), "%d"));
- }
- } else if (IS_BASE_DUAL(hfinfo->display)) {
- col_custom_set_fstr(fi->hfinfo, hfinfo_int_value_format(hfinfo), integer, integer);
- } else {
- col_custom_set_fstr(fi->hfinfo, hfinfo_int_value_format(hfinfo), integer);
- }
fvalue_set_sinteger(&fi->value, integer);
}
field_info *new_fi;
header_field_info *hfinfo;
- if (!tree)
- return (NULL);
-
- TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
- PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
DISSECTOR_ASSERT(hfinfo->type == FT_INT64);
pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation_value(pi, format, ap);
va_end(ap);
{
proto_item *pi;
va_list ap;
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
if (pi == NULL)
return (NULL);
+ TRY_TO_FAKE_THIS_REPR(tree, pi);
+
va_start(ap, format);
proto_tree_set_representation(pi, format, ap);
va_end(ap);
return pi;
}
-/* Throw an exception if we exceed this many tree items. */
-/* XXX - This should probably be a preference */
-#define MAX_TREE_ITEMS (1 * 1000 * 1000)
/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
static proto_item *
proto_tree_add_node(proto_tree *tree, field_info *fi)
* Make sure "tree" is ready to have subtrees under it, by
* checking whether it's been given an ett_ value.
*
- * "tnode->finfo" may be null; that's the case for the root
+ * "PNODE_FINFO(tnode)" may be null; that's the case for the root
* node of the protocol tree. That node is not displayed,
* so it doesn't need an ett_ value to remember whether it
* was expanded.
*/
tnode = tree;
- tfi = tnode->finfo;
+ tfi = PNODE_FINFO(tnode);
if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
REPORT_DISSECTOR_BUG(ep_strdup_printf("\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
}
DISSECTOR_ASSERT(tfi == NULL ||
- (tfi->tree_type >= 0 && tfi->tree_type < num_tree_types));
-
- PTREE_DATA(tree)->count++;
- if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) {
- /* Let the exception handler add items to the tree */
- PTREE_DATA(tree)->count = 0;
- THROW_MESSAGE(DissectorError,
- ep_strdup_printf("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS));
- }
+ (tfi->tree_type >= 0 && tfi->tree_type < num_tree_types));
PROTO_NODE_NEW(pnode);
pnode->parent = tnode;
- pnode->finfo = fi;
+ PNODE_FINFO(pnode) = fi;
pnode->tree_data = PTREE_DATA(tree);
if (tnode->last_child != NULL) {
* non-NULL. */
static proto_item *
proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
- gint *length, field_info **pfi)
+ gint *length, field_info **pfi)
{
proto_item *pi;
field_info *fi;
- GHashTable *hash;
GPtrArray *ptrs;
if (!tree)
/* If the proto_tree wants to keep a record of this finfo
* for quick lookup, then record it. */
- if (fi->hfinfo->ref_count) {
- /*HERE*/
- hash = PTREE_DATA(tree)->interesting_hfids;
- ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
- if (ptrs) {
- g_ptr_array_add(ptrs, fi);
- }
- }
+ ptrs = proto_lookup_or_create_interesting_hfids(tree, fi->hfinfo);
+ if (ptrs)
+ g_ptr_array_add(ptrs, fi);
/* Does the caller want to know the fi pointer? */
if (pfi) {
static header_field_info *
-get_hfi_and_length(int hfindex, tvbuff_t *tvb, gint start, gint *length,
- gint *item_length)
+get_hfi_and_length(int hfindex, tvbuff_t *tvb, const gint start, gint *length,
+ gint *item_length)
{
header_field_info *hfinfo;
gint length_remaining;
if (tvb) {
length_remaining = tvb_length_remaining(tvb, start);
if (*item_length < 0 ||
- (*item_length > 0 &&
- (length_remaining < *item_length)))
+ (*item_length > 0 &&
+ (length_remaining < *item_length)))
*item_length = length_remaining;
}
}
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,
- gint *length)
+alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb, const gint start,
+ gint *length)
{
header_field_info *hfinfo;
gint item_length;
proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
{
int ret; /*tmp return value */
- int replen;
field_info *fi = PITEM_FINFO(pi);
- header_field_info *hf = fi->hfinfo;
+ header_field_info *hf;
+
+ DISSECTOR_ASSERT(fi);
+
+ hf = fi->hfinfo;
if (!PROTO_ITEM_IS_HIDDEN(pi)) {
ITEM_LABEL_NEW(fi->rep);
- replen = 0;
if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
char tmpbuf[64];
guint32 val;
ret = g_snprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
"%s: ", fi->hfinfo->name);
}
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH)) {
- /* That's all we can put in the representation. */
- fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
- return;
- }
- replen = ret;
- /* Put in the value of the string */
- ret = g_vsnprintf(fi->rep->representation + replen,
- ITEM_LABEL_LENGTH - replen, format, ap);
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH - replen)) {
+ /* If possible, Put in the value of the string */
+ if (ret < ITEM_LABEL_LENGTH) {
+ ret += g_vsnprintf(fi->rep->representation + ret,
+ ITEM_LABEL_LENGTH - ret, format, ap);
+ }
+ if (ret >= ITEM_LABEL_LENGTH) {
/* Uh oh, we don't have enough room. Tell the user
* that the field is truncated.
*/
char *oldrep;
- fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
-
- /* Argh, we cannot reuse 'ap' here. So make a copy
- * of what we formatted for (re)use below.
+ /* Argh, we cannot reuse 'ap' here. So make a copy
+ * of what we formatted for (re)use below.
*/
oldrep = g_strdup(fi->rep->representation);
- ret = g_snprintf(fi->rep->representation,
- ITEM_LABEL_LENGTH,
- "[truncated] %s",
- oldrep);
- fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
+ g_snprintf(fi->rep->representation,
+ ITEM_LABEL_LENGTH,
+ "[truncated] %s",
+ oldrep);
g_free(oldrep);
}
}
int ret; /*tmp return value */
field_info *fi = PITEM_FINFO(pi);
+ DISSECTOR_ASSERT(fi);
+
if (!PROTO_ITEM_IS_HIDDEN(pi)) {
ITEM_LABEL_NEW(fi->rep);
ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
format, ap);
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH)) {
+ if (ret >= ITEM_LABEL_LENGTH) {
/* Uh oh, we don't have enough room. Tell the user
* that the field is truncated.
*/
char *oldrep;
- fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
-
- /* Argh, we cannot reuse 'ap' here. So make a copy
- * of what we formatted for (re)use below.
+ /* 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);
- fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
g_free(oldrep);
}
}
}
+/* -------------------------- */
+const gchar *
+proto_custom_set(proto_tree* tree, const int field_id,
+ gchar *result,
+ 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;
+ int len;
+ GPtrArray *finfos;
+ field_info *finfo;
+ header_field_info* hfinfo;
+
+ g_assert(field_id >= 0);
+
+ hfinfo = proto_registrar_get_nth((guint)field_id);
+
+ /* do we need to rewind ? */
+ if (!hfinfo)
+ return "";
+
+ while (hfinfo) {
+ finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
+
+ if (!finfos || !(len = g_ptr_array_len(finfos))) {
+ hfinfo = hfinfo->same_name_next;
+ continue;
+ }
+ /* get the last one */
+ finfo = g_ptr_array_index(finfos, len -1);
+
+ 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);
+ g_strlcpy(result, bytes_to_str(bytes, fvalue_length(&finfo->value)), size);
+ break;
+
+ case FT_ABSOLUTE_TIME:
+ g_strlcpy(result,
+ abs_time_to_str(fvalue_get(&finfo->value), hfinfo->display),
+ size);
+ break;
+
+ case FT_RELATIVE_TIME:
+ g_strlcpy(result, rel_time_to_secs_str(fvalue_get(&finfo->value)), size);
+ break;
+
+ case FT_BOOLEAN:
+ u_integer = fvalue_get_uinteger(&finfo->value);
+ tfstring = (const true_false_string *)&tfs_true_false;
+ if (hfinfo->strings) {
+ tfstring = (const struct true_false_string*) hfinfo->strings;
+ }
+ g_strlcpy(result, u_integer ? tfstring->true_string : tfstring->false_string, size);
+ break;
+
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ case FT_FRAMENUM:
+ u_integer = fvalue_get_uinteger(&finfo->value);
+ if (hfinfo->strings) {
+ if (hfinfo->display & BASE_RANGE_STRING) {
+ g_strlcpy(result, rval_to_str(u_integer, hfinfo->strings, "%u"), size);
+ } else {
+ g_strlcpy(result, val_to_str(u_integer, cVALS(hfinfo->strings), "%u"), size);
+ }
+ } else if (IS_BASE_DUAL(hfinfo->display)) {
+ g_snprintf(result, size, hfinfo_uint_value_format(hfinfo), u_integer, u_integer);
+ } else {
+ g_snprintf(result, size, hfinfo_uint_value_format(hfinfo), u_integer);
+ }
+ break;
+
+ case FT_INT64:
+ case FT_UINT64:
+ g_snprintf(result, size, "%" G_GINT64_MODIFIER "u", fvalue_get_integer64(&finfo->value));
+ 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->strings) {
+ if (hfinfo->display & BASE_RANGE_STRING) {
+ g_strlcpy(result, rval_to_str(integer, hfinfo->strings, "%d"), size);
+ } else {
+ g_strlcpy(result, val_to_str(integer, cVALS(hfinfo->strings), "%d"), size);
+ }
+ } else if (IS_BASE_DUAL(hfinfo->display)) {
+ g_snprintf(result, size, hfinfo_int_value_format(hfinfo), integer, integer);
+ } else {
+ g_snprintf(result, size, hfinfo_int_value_format(hfinfo), integer);
+ }
+ break;
+
+ case FT_IPv4:
+ ipv4 = fvalue_get(&finfo->value);
+ n_addr = ipv4_get_net_order_addr(ipv4);
+ 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;
+
+ case FT_GUID:
+ g_strlcpy(result, guid_to_str((e_guid_t *)fvalue_get(&finfo->value)), size);
+ break;
+
+ case FT_OID:
+ bytes = fvalue_get(&finfo->value);
+ g_strlcpy(result, oid_resolved_from_encoded(bytes, fvalue_length(&finfo->value)), size);
+ break;
+
+ case FT_FLOAT:
+ g_snprintf(result, size, "%." STRINGIFY(FLT_DIG) "f", fvalue_get_floating(&finfo->value));
+ break;
+
+ case FT_DOUBLE:
+ g_snprintf(result, size, "%." STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
+ break;
+
+ case FT_EBCDIC:
+ case FT_STRING:
+ case FT_STRINGZ:
+ case FT_UINT_STRING:
+ bytes = fvalue_get(&finfo->value);
+ g_strlcpy(result, format_text(bytes, strlen(bytes)), size);
+ break;
+
+ case FT_IPXNET: /*XXX really No column custom ?*/
+ case FT_PCRE:
+ default:
+ g_error("hfinfo->type %d (%s) not handled\n",
+ hfinfo->type,
+ ftype_name(hfinfo->type));
+ DISSECTOR_ASSERT_NOT_REACHED();
+ break;
+ }
+
+ switch(hfinfo->type) {
+ case FT_EBCDIC:
+ case FT_STRING:
+ case FT_STRINGZ:
+ case FT_UINT_STRING:
+ g_snprintf(expr, size, "\"%s\"",result);
+ default:
+ g_strlcpy(expr, result, size);
+ break;
+ }
+ return hfinfo->abbrev;
+ }
+ return "";
+}
+
+
/* Set text of proto_item after having already been created. */
void
proto_item_set_text(proto_item *pi, const char *format, ...)
}
fi = PITEM_FINFO(pi);
+ if (fi==NULL)
+ return;
if(fi->rep){
ITEM_LABEL_FREE(fi->rep);
field_info *fi = NULL;
size_t curlen;
va_list ap;
- int ret; /*tmp return value */
if (pi==NULL) {
return;
curlen = strlen(fi->rep->representation);
if (ITEM_LABEL_LENGTH > curlen) {
- ret = g_vsnprintf(fi->rep->representation + curlen,
- ITEM_LABEL_LENGTH - curlen, format, ap);
- if ((ret == -1) || (ret >= (int)(ITEM_LABEL_LENGTH - curlen)))
- fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
+ g_vsnprintf(fi->rep->representation + curlen,
+ ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
}
va_end(ap);
}
}
void
-proto_item_set_len(proto_item *pi, gint length)
+proto_item_set_len(proto_item *pi, const gint length)
{
field_info *fi;
if (pi == NULL)
return;
+
fi = PITEM_FINFO(pi);
+ if (fi == NULL)
+ return;
+
DISSECTOR_ASSERT(length >= 0);
fi->length = length;
if (pi == NULL)
return;
+
fi = PITEM_FINFO(pi);
+ if (fi == NULL)
+ return;
+
end += TVB_RAW_OFFSET(tvb);
DISSECTOR_ASSERT(end >= fi->start);
fi->length = end - fi->start;
}
int
-proto_item_get_len(proto_item *pi)
+proto_item_get_len(const proto_item *pi)
{
field_info *fi = PITEM_FINFO(pi);
- return fi->length;
+ 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 || pi->finfo == NULL)
+ 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(pi->finfo, PI_SEVERITY_MASK)) {
- FI_REPLACE_FLAGS(pi->finfo, PI_GROUP_MASK, group);
- FI_REPLACE_FLAGS(pi->finfo, PI_SEVERITY_MASK, severity);
+ 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(void)
{
- proto_node *pnode;
+ proto_node *pnode;
/* Initialize the proto_node */
PROTO_NODE_NEW(pnode);
pnode->parent = NULL;
- pnode->finfo = NULL;
+ PNODE_FINFO(pnode) = NULL;
pnode->tree_data = g_new(tree_data_t, 1);
- /* Initialize the tree_data_t */
- pnode->tree_data->interesting_hfids =
- g_hash_table_new(g_direct_hash, g_direct_equal);
+ /* Don't initialize the tree_data_t. Wait until we know we need it */
+ pnode->tree_data->interesting_hfids = NULL;
/* Set the default to FALSE so it's easier to
* find errors; if we expect to see the protocol tree
* changed, then we'll find out very quickly. */
pnode->tree_data->visible = FALSE;
+ /* Make sure that we fake protocols (if possible) */
+ pnode->tree_data->fake_protocols = TRUE;
+
/* Keep track of the number of children */
pnode->tree_data->count = 0;
/* "prime" a proto_tree with a single hfid that a dfilter
* is interested in. */
void
-proto_tree_prime_hfid(proto_tree *tree, gint hfid)
+proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
{
header_field_info *hfinfo;
- g_hash_table_insert(PTREE_DATA(tree)->interesting_hfids,
- GINT_TO_POINTER(hfid), g_ptr_array_new());
-
PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
/* this field is referenced by a filter so increase the refcount.
also increase the refcount for the parent, i.e the protocol.
*/
- hfinfo->ref_count++;
+ hfinfo->ref_type = HF_REF_TYPE_DIRECT;
/* only increase the refcount if there is a parent.
if this is a protocol and not a field then parent will be -1
and there is no parent to add any refcounting for.
if (hfinfo->parent != -1) {
header_field_info *parent_hfinfo;
PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
- parent_hfinfo->ref_count++;
+
+ /* Mark parent as indirectly referenced unless it is already directly
+ * referenced, i.e. the user has specified the parent in a filter.
+ */
+ if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
+ parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
}
}
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)
return(NULL);
- fi = PITEM_FINFO(pi);
DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
+
+ fi = PITEM_FINFO(pi);
+ if (!fi)
+ return (proto_tree*) pi;
+
fi->tree_type = idx;
return (proto_tree*) 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_move_item(proto_tree *tree, proto_item *fixed_item, proto_item *item_to_move)
{
- DISSECTOR_ASSERT(item_to_move->parent == tree);
- DISSECTOR_ASSERT(fixed_item->parent == tree);
+ /* This function doesn't generate any values. It only reorganizes the prococol tree
+ * so we can bail out immediately if it isn't visible. */
+ if (!tree || !PTREE_DATA(tree)->visible)
+ return;
- /*** cut item_to_move out ***/
+ DISSECTOR_ASSERT(item_to_move->parent == tree);
+ DISSECTOR_ASSERT(fixed_item->parent == tree);
- /* is item_to_move the first? */
- if(tree->first_child == item_to_move) {
- /* simply change first child to next */
- tree->first_child = item_to_move->next;
+ /*** cut item_to_move out ***/
- DISSECTOR_ASSERT(tree->last_child != item_to_move);
- } else {
- proto_item *curr_item;
- /* find previous and change it's next */
- for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
- if(curr_item->next == item_to_move) {
- break;
- }
- }
+ /* is item_to_move the first? */
+ if(tree->first_child == item_to_move) {
+ /* simply change first child to next */
+ tree->first_child = item_to_move->next;
- DISSECTOR_ASSERT(curr_item);
+ DISSECTOR_ASSERT(tree->last_child != item_to_move);
+ } else {
+ proto_item *curr_item;
+ /* find previous and change it's next */
+ for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
+ if(curr_item->next == item_to_move) {
+ break;
+ }
+ }
- curr_item->next = item_to_move->next;
+ DISSECTOR_ASSERT(curr_item);
- /* fix last_child if required */
- if(tree->last_child == item_to_move) {
- tree->last_child = curr_item;
- }
- }
+ curr_item->next = item_to_move->next;
- /*** insert to_move after fixed ***/
- item_to_move->next = fixed_item->next;
- fixed_item->next = item_to_move;
- if(tree->last_child == fixed_item) {
- tree->last_child = item_to_move;
- }
+ /* fix last_child if required */
+ if(tree->last_child == item_to_move) {
+ tree->last_child = curr_item;
+ }
+ }
+
+ /*** insert to_move after fixed ***/
+ item_to_move->next = fixed_item->next;
+ fixed_item->next = item_to_move;
+ if(tree->last_child == fixed_item) {
+ tree->last_child = item_to_move;
+ }
}
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;
if (tree == NULL)
return;
- fi = tree->finfo;
+ fi = PTREE_FINFO(tree);
+ if (fi == NULL)
+ return;
+
start += TVB_RAW_OFFSET(tvb);
DISSECTOR_ASSERT(start >= 0);
DISSECTOR_ASSERT(length >= 0);
int
proto_register_protocol(const char *name, const char *short_name, const char *filter_name)
{
- protocol_t *protocol;
- header_field_info *hfinfo;
- int proto_id;
- char *existing_name;
- gint *key;
- guint i;
- guchar c;
- gboolean found_invalid;
-
- /*
- * Make sure there's not already a protocol with any of those
- * names. Crash if there is, as that's an error in the code
- * or an inappropriate plugin.
- * This situation has to be fixed to not register more than one
- * protocol with the same name.
- *
- * This is done by reducing the number of strcmp (and alike) calls as much as possible,
- * as this significally slows down startup time.
- *
- * Drawback: As a hash value is used to reduce insert time,
- * this might lead to a hash collision.
- * However, as we have around 500+ protocols and we're using a 32 bit int this is very,
- * very unlikely.
- */
-
- key = g_malloc (sizeof(gint));
- *key = wrs_str_hash(name);
- existing_name = g_hash_table_lookup(proto_names, key);
- if (existing_name != NULL) {
- /* g_error will terminate the program */
- g_error("Duplicate protocol name \"%s\"!"
- " This might be caused by an inappropriate plugin or a development error.", name);
- }
- g_hash_table_insert(proto_names, key, (gpointer)name);
-
- existing_name = g_hash_table_lookup(proto_short_names, (gpointer)short_name);
- if (existing_name != NULL) {
- g_error("Duplicate protocol short_name \"%s\"!"
- " This might be caused by an inappropriate plugin or a development error.", short_name);
- }
- g_hash_table_insert(proto_short_names, (gpointer)short_name, (gpointer)short_name);
-
- found_invalid = FALSE;
- for (i = 0; i < strlen(filter_name); i++) {
- c = filter_name[i];
- if (!(islower(c) || isdigit(c) || c == '-' || c == '_' || c == '.')) {
- found_invalid = TRUE;
- }
- }
- if (found_invalid) {
- g_error("Protocol filter name \"%s\" has one or more invalid characters."
- " Allowed are lower characters, digits, '-', '_' and '.'."
- " This might be caused by an inappropriate plugin or a development error.", filter_name);
- }
- existing_name = g_hash_table_lookup(proto_filter_names, (gpointer)filter_name);
- if (existing_name != NULL) {
- g_error("Duplicate protocol filter_name \"%s\"!"
- " This might be caused by an inappropriate plugin or a development error.", filter_name);
- }
- g_hash_table_insert(proto_filter_names, (gpointer)filter_name, (gpointer)filter_name);
-
- /* Add this protocol to the list of known protocols; the list
- is sorted by protocol short name. */
- protocol = g_malloc(sizeof (protocol_t));
- protocol->name = name;
- protocol->short_name = short_name;
- protocol->filter_name = filter_name;
- protocol->fields = NULL;
- protocol->is_enabled = TRUE; /* protocol is enabled by default */
- protocol->can_toggle = TRUE;
- protocol->is_private = FALSE;
- /* list will be sorted later by name, when all protocols completed registering */
- protocols = g_list_prepend(protocols, protocol);
-
- /* Here we do allocate a new header_field_info struct */
- hfinfo = g_mem_chunk_alloc(gmc_hfinfo);
- hfinfo->name = name;
- hfinfo->abbrev = filter_name;
- hfinfo->type = FT_PROTOCOL;
- hfinfo->strings = protocol;
- hfinfo->bitmask = 0;
- hfinfo->bitshift = 0;
- hfinfo->ref_count = 0;
- hfinfo->blurb = NULL;
- hfinfo->parent = -1; /* this field differentiates protos and fields */
-
- proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
- protocol->proto_id = proto_id;
- return proto_id;
+ protocol_t *protocol;
+ header_field_info *hfinfo;
+ int proto_id;
+ char *existing_name;
+ gint *key;
+ guint i;
+ guchar c;
+ gboolean found_invalid;
+
+ /*
+ * Make sure there's not already a protocol with any of those
+ * names. Crash if there is, as that's an error in the code
+ * or an inappropriate plugin.
+ * This situation has to be fixed to not register more than one
+ * protocol with the same name.
+ *
+ * This is done by reducing the number of strcmp (and alike) calls as much as possible,
+ * as this significally slows down startup time.
+ *
+ * Drawback: As a hash value is used to reduce insert time,
+ * this might lead to a hash collision.
+ * However, as we have around 500+ protocols and we're using a 32 bit int this is very,
+ * very unlikely.
+ */
+
+ key = g_malloc (sizeof(gint));
+ *key = wrs_str_hash(name);
+ existing_name = g_hash_table_lookup(proto_names, key);
+ if (existing_name != NULL) {
+ /* g_error will terminate the program */
+ g_error("Duplicate protocol name \"%s\"!"
+ " This might be caused by an inappropriate plugin or a development error.", name);
+ }
+ g_hash_table_insert(proto_names, key, (gpointer)name);
+
+ existing_name = g_hash_table_lookup(proto_short_names, (gpointer)short_name);
+ if (existing_name != NULL) {
+ g_error("Duplicate protocol short_name \"%s\"!"
+ " This might be caused by an inappropriate plugin or a development error.", short_name);
+ }
+ g_hash_table_insert(proto_short_names, (gpointer)short_name, (gpointer)short_name);
+
+ found_invalid = FALSE;
+ for (i = 0; i < strlen(filter_name); i++) {
+ c = filter_name[i];
+ if (!(islower(c) || isdigit(c) || c == '-' || c == '_' || c == '.')) {
+ found_invalid = TRUE;
+ }
+ }
+ if (found_invalid) {
+ g_error("Protocol filter name \"%s\" has one or more invalid characters."
+ " Allowed are lower characters, digits, '-', '_' and '.'."
+ " This might be caused by an inappropriate plugin or a development error.", filter_name);
+ }
+ existing_name = g_hash_table_lookup(proto_filter_names, (gpointer)filter_name);
+ if (existing_name != NULL) {
+ g_error("Duplicate protocol filter_name \"%s\"!"
+ " This might be caused by an inappropriate plugin or a development error.", filter_name);
+ }
+ g_hash_table_insert(proto_filter_names, (gpointer)filter_name, (gpointer)filter_name);
+
+ /* Add this protocol to the list of known protocols; the list
+ is sorted by protocol short name. */
+ protocol = g_new(protocol_t, 1);
+ protocol->name = name;
+ protocol->short_name = short_name;
+ protocol->filter_name = filter_name;
+ protocol->fields = NULL;
+ protocol->is_enabled = TRUE; /* protocol is enabled by default */
+ protocol->can_toggle = TRUE;
+ protocol->is_private = FALSE;
+ /* list will be sorted later by name, when all protocols completed registering */
+ 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;
+ 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_id = proto_register_field_init(hfinfo, hfinfo->parent);
+ protocol->proto_id = proto_id;
+ return proto_id;
}
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)
- protocol->is_private = TRUE;
+ protocol_t *protocol = find_protocol_by_id(proto_id);
+ if (protocol)
+ protocol->is_private = TRUE;
}
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)
- return protocol->is_private;
- else
- return FALSE;
+ protocol_t *protocol = find_protocol_by_id(proto_id);
+ if (protocol)
+ return protocol->is_private;
+ else
+ return FALSE;
}
/*
}
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;
}
protocol_t *protocol;
list_entry = g_list_find_custom(protocols, filter_name,
- compare_filter_name);
+ compare_filter_name);
if (list_entry == NULL)
return -1;
}
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;
*/
if (*ptr->p_id != -1 && *ptr->p_id != 0) {
fprintf(stderr,
- "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
- ptr->hfinfo.abbrev);
+ "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
+ ptr->hfinfo.abbrev);
return;
}
proto->last_field = proto->fields;
} else {
proto->last_field =
- g_list_append(proto->last_field, ptr)->next;
+ g_list_append(proto->last_field, ptr)->next;
}
}
field_id = proto_register_field_init(&ptr->hfinfo, parent);
const guchar fld_abbrev_chars[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
case FT_INT24:
case FT_INT32:
case FT_INT64:
- /* Hexadecimal and octal are, in printf() and everywhere else,
- * unsigned so don't allow dissectors to register a signed
- * field to be displayed unsigned. (Else how would we
- * display values negative values?)
+ /* Hexadecimal and octal are, in printf() and everywhere else,
+ * unsigned so don't allow dissectors to register a signed
+ * field to be displayed unsigned. (Else how would we
+ * display values 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 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*.
*/
DISSECTOR_ASSERT(hfinfo->display != BASE_HEX &&
hfinfo->display != BASE_HEX_DEC &&
DISSECTOR_ASSERT(hfinfo->display != BASE_NONE);
break;
+ case FT_PROTOCOL:
case FT_FRAMENUM:
- case FT_STRING:
- case FT_STRINGZ:
- case FT_EBCDIC:
- /* Don't allow bitfields or value strings for frame numbers and strings */
+ DISSECTOR_ASSERT(hfinfo->display == BASE_NONE);
+ DISSECTOR_ASSERT(hfinfo->bitmask == 0);
+ break;
+
+ 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);
+ DISSECTOR_ASSERT(hfinfo->strings == NULL);
break;
}
}
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);
g_tree_insert(gpa_name_tree, (gpointer) (hfinfo->abbrev), hfinfo);
/* GLIB 2.x - if it is already present
- * the previous hfinfo with the same name is saved
- * to same_name_hfinfo by value destroy callback */
+ * the previous hfinfo with the same name is saved
+ * to same_name_hfinfo by value destroy callback */
if (same_name_hfinfo) {
/* There's already a field with this name.
* Put it after that field in the list of
* we end up with a linked-list of same-named hfinfo's,
* with the root of the list being the hfinfo in the GTree */
same_name_next_hfinfo =
- same_name_hfinfo->same_name_next;
+ same_name_hfinfo->same_name_next;
hfinfo->same_name_next = same_name_next_hfinfo;
if (same_name_next_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;
*/
if (tree_is_expanded != NULL) {
tree_is_expanded =
- g_realloc(tree_is_expanded,
- (num_tree_types+num_indices)*sizeof (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));
+ num_indices*sizeof (gboolean));
}
/*
* first element is pointed to by "indices", and update
* "num_tree_types" appropriately.
*/
- for (i = 0; i < num_indices; i++, ptr++, num_tree_types++)
+ for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
+ if (**ptr != -1) {
+ /* g_error will terminate the program */
+ g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
+ " This is a development error:"
+ " Either the subtree item type has already been assigned or"
+ " was not initialized to -1.");
+ }
**ptr = num_tree_types;
+ }
}
void
proto_item_fill_label(field_info *fi, gchar *label_str)
{
- header_field_info *hfinfo = fi->hfinfo;
+ header_field_info *hfinfo;
guint8 *bytes;
guint32 integer;
const gchar *name;
int ret; /*tmp return value */
+ if (!fi) {
+ if (label_str)
+ label_str[0]= '\0';
+ /* XXX: Check validity of hfinfo->type */
+ return;
+ }
+
+ hfinfo = fi->hfinfo;
+
switch(hfinfo->type) {
case FT_NONE:
case FT_PROTOCOL:
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s", hfinfo->name);
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
+ g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
break;
case FT_BOOLEAN:
ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s", hfinfo->name,
bytes_to_str(bytes, fvalue_length(&fi->value)));
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH)) {
+ if (ret >= ITEM_LABEL_LENGTH) {
/* Uh oh, we don't have enough room. Tell the
- * user that the field is truncated.
+ * user that the field is truncated.
*/
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s [truncated]: %s",
hfinfo->name,
bytes_to_str(bytes, fvalue_length(&fi->value)));
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
}
}
else {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: <MISSING>", hfinfo->name);
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
+ g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s: <MISSING>", hfinfo->name);
}
break;
/* Four types of integers to take care of:
- * Bitfield, with val_string
- * Bitfield, w/o val_string
- * Non-bitfield, with val_string
- * Non-bitfield, w/o val_string
+ * Bitfield, with val_string
+ * Bitfield, w/o val_string
+ * Non-bitfield, with val_string
+ * Non-bitfield, w/o val_string
*/
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
- case FT_FRAMENUM:
if (hfinfo->bitmask) {
fill_label_bitfield(fi, label_str);
} else {
}
break;
+ case FT_FRAMENUM:
+ fill_label_uint(fi, label_str);
+ break;
+
case FT_UINT64:
fill_label_uint64(fi, label_str);
break;
break;
case FT_FLOAT:
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %." STRINGIFY(FLT_DIG) "f",
hfinfo->name, fvalue_get_floating(&fi->value));
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
case FT_DOUBLE:
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %." STRINGIFY(DBL_DIG) "g",
hfinfo->name, fvalue_get_floating(&fi->value));
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
case FT_ABSOLUTE_TIME:
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s", hfinfo->name,
- abs_time_to_str(fvalue_get(&fi->value)));
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
+ abs_time_to_str(fvalue_get(&fi->value), hfinfo->display));
break;
case FT_RELATIVE_TIME:
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s seconds", hfinfo->name,
rel_time_to_secs_str(fvalue_get(&fi->value)));
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
case FT_IPXNET:
integer = fvalue_get_uinteger(&fi->value);
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s (0x%08X)", hfinfo->name,
get_ipxnet_name(integer), integer);
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
case FT_ETHER:
bytes = fvalue_get(&fi->value);
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s (%s)", hfinfo->name,
get_ether_name(bytes),
ether_to_str(bytes));
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
case FT_IPv4:
ipv4 = fvalue_get(&fi->value);
n_addr = ipv4_get_net_order_addr(ipv4);
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s (%s)", hfinfo->name,
get_hostname(n_addr),
ip_to_str((guint8*)&n_addr));
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
case FT_IPv6:
bytes = fvalue_get(&fi->value);
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s (%s)", hfinfo->name,
get_hostname6((struct e_in6_addr *)bytes),
ip6_to_str((struct e_in6_addr*)bytes));
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
case FT_GUID:
guid = fvalue_get(&fi->value);
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s", hfinfo->name,
guid_to_str(guid));
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
case FT_OID:
bytes = fvalue_get(&fi->value);
name = oid_resolved_from_encoded(bytes, fvalue_length(&fi->value));
if (name) {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s (%s)", hfinfo->name,
oid_encoded2string(bytes, fvalue_length(&fi->value)), name);
} else {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s", hfinfo->name,
oid_encoded2string(bytes, fvalue_length(&fi->value)));
}
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
case FT_STRING:
case FT_STRINGZ:
- case FT_EBCDIC:
+ case FT_EBCDIC:
case FT_UINT_STRING:
bytes = fvalue_get(&fi->value);
- if(strlen(bytes) > ITEM_LABEL_LENGTH) {
+ ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ "%s: %s", hfinfo->name,
+ format_text(bytes, strlen(bytes)));
+ if (ret >= ITEM_LABEL_LENGTH) {
/* Uh oh, we don't have enough room. Tell the
- * user that the field is truncated.
+ * user that the field is truncated.
*/
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s [truncated]: %s",
hfinfo->name,
format_text(bytes, strlen(bytes)));
- } else {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
- "%s: %s", hfinfo->name,
- format_text(bytes, strlen(bytes)));
}
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
break;
default:
int bitfield_byte_length = 0, bitwidth;
guint32 unshifted_value;
guint32 value;
- int ret; /*tmp return value */
header_field_info *hfinfo = fi->hfinfo;
- const true_false_string *tfstring = &tfs_true_false;
+ const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
if (hfinfo->strings) {
tfstring = (const struct true_false_string*) hfinfo->strings;
/* Create the bitfield first */
p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
- bitfield_byte_length = p - label_str;
+ bitfield_byte_length = (int) (p - label_str);
}
/* Fill in the textual info */
- ret = g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
+ g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
"%s: %s", hfinfo->name,
value ? tfstring->true_string : tfstring->false_string);
- if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
}
-
/* Fills data for bitfield ints with val_strings */
static void
fill_label_bitfield(field_info *fi, gchar *label_str)
int bitfield_byte_length, bitwidth;
guint32 unshifted_value;
guint32 value;
- int ret; /*tmp return value */
header_field_info *hfinfo = fi->hfinfo;
/* Create the bitfield first */
p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
- bitfield_byte_length = p - label_str;
+ bitfield_byte_length = (int) (p - label_str);
/* Fill in the textual info using stored (shifted) value */
if (hfinfo->display == BASE_CUSTOM) {
DISSECTOR_ASSERT(fmtfunc);
fmtfunc(tmp, value);
- ret = g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
+ g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
"%s: %s", hfinfo->name, tmp);
}
else if (hfinfo->strings) {
format = hfinfo_uint_vals_format(hfinfo);
if (hfinfo->display & BASE_RANGE_STRING) {
- ret = g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
+ g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
format, hfinfo->name,
rval_to_str(value, hfinfo->strings, "Unknown"), value);
} else {
- ret = g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
+ g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
format, hfinfo->name,
val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
}
else {
format = hfinfo_uint_format(hfinfo);
if (IS_BASE_DUAL(hfinfo->display)) {
- ret = g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
+ g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
format, hfinfo->name, value, value);
} else {
- ret = g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
+ g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
format, hfinfo->name, value);
}
}
- if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
}
static void
const char *format = NULL;
header_field_info *hfinfo = fi->hfinfo;
guint32 value;
- int ret; /*tmp return value */
value = fvalue_get_uinteger(&fi->value);
DISSECTOR_ASSERT(fmtfunc);
fmtfunc(tmp, value);
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s: %s", hfinfo->name, tmp);
+ g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s: %s", hfinfo->name, tmp);
}
else if (hfinfo->strings) {
format = hfinfo_uint_vals_format(hfinfo);
if (hfinfo->display & BASE_RANGE_STRING) {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name,
rval_to_str(value, hfinfo->strings, "Unknown"), value);
} else {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name,
val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
}
else {
format = hfinfo_uint_format(hfinfo);
if (IS_BASE_DUAL(hfinfo->display)) {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name, value, value);
} else {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name, value);
}
}
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
}
static void
const char *format = NULL;
header_field_info *hfinfo = fi->hfinfo;
guint64 value;
- int ret; /*tmp return value */
/* Pick the proper format string */
format = hfinfo_uint64_format(hfinfo);
/* Fill in the textual info */
if (IS_BASE_DUAL(hfinfo->display)) {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name, value, value);
} else {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name, value);
}
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
}
static void
const char *format = NULL;
header_field_info *hfinfo = fi->hfinfo;
guint32 value;
- int ret; /*tmp return value */
value = fvalue_get_sinteger(&fi->value);
DISSECTOR_ASSERT(fmtfunc);
fmtfunc(tmp, value);
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s: %s", hfinfo->name, tmp);
+ g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s: %s", hfinfo->name, tmp);
}
else if (hfinfo->strings) {
format = hfinfo_int_vals_format(hfinfo);
if (hfinfo->display & BASE_RANGE_STRING) {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name,
rval_to_str(value, hfinfo->strings, "Unknown"), value);
} else {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name,
val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
}
else {
format = hfinfo_int_format(hfinfo);
if (IS_BASE_DUAL(hfinfo->display)) {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name, value, value);
} else {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name, value);
}
}
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
}
static void
const char *format = NULL;
header_field_info *hfinfo = fi->hfinfo;
guint64 value;
- int ret; /*tmp return value */
/* Pick the proper format string */
format = hfinfo_int64_format(hfinfo);
/* Fill in the textual info */
if (IS_BASE_DUAL(hfinfo->display)) {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name, value, value);
} else {
- ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
+ g_snprintf(label_str, ITEM_LABEL_LENGTH,
format, hfinfo->name, value);
}
- if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
- label_str[ITEM_LABEL_LENGTH - 1] = '\0';
}
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";
return format;
}
-
-
int
proto_registrar_n(void)
{
}
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;
return ftype_length(hfinfo->type);
}
-
-
/* 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)
{
- return g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
- GINT_TO_POINTER(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));
+ else
+ return NULL;
}
+gboolean
+proto_tracking_interesting_fields(const proto_tree *tree)
+{
+ if (!tree)
+ return FALSE;
+
+ return (PTREE_DATA(tree)->interesting_hfids != NULL);
+}
-/* Helper struct for proto_find_info() and proto_all_finfos() */
+/* Helper struct for proto_find_info() and proto_all_finfos() */
typedef struct {
GPtrArray *array;
int id;
static gboolean
find_finfo(proto_node *node, gpointer data)
{
- field_info *fi = PITEM_FINFO(node);
+ field_info *fi = PNODE_FINFO(node);
if (fi && fi->hfinfo) {
if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
g_ptr_array_add(((ffdata_t*)data)->array, fi);
* This works on any proto_tree, primed or unprimed, but actually searches
* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
* The caller does need to free the returned GPtrArray with
-* g_ptr_array_free(<array>, FALSE).
+* 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;
static gboolean
every_finfo(proto_node *node, gpointer data)
{
- field_info *fi = PITEM_FINFO(node);
+ field_info *fi = PNODE_FINFO(node);
if (fi && fi->hfinfo) {
g_ptr_array_add(((ffdata_t*)data)->array, fi);
}
} 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 = PITEM_FINFO(node);
+ field_info *fi = PNODE_FINFO(node);
offset_search_t *offsearch = data;
/* !fi == the top most container node which holds nothing */
return offsearch.finfo;
}
-/* Dumps the protocols in the registration database to stdout. An independent
+/* Dumps the protocols in the registration database to stdout. An independent
* program can take this output and format it into nice tables or HTML or
* whatever.
*
void *cookie = NULL;
for (i = proto_get_first_protocol(&cookie); i != -1;
- i = proto_get_next_protocol(&cookie)) {
+ i = proto_get_next_protocol(&cookie)) {
protocol = find_protocol_by_id(i);
printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
- protocol->filter_name);
+ protocol->filter_name);
}
}
-/* Dumps the value_string and true/false strings for fields that have
- * them. There is one record per line. Fields are tab-delimited.
- * There are two types of records, Value String records and True/False
- * String records. The first field, 'V' or 'T', indicates the type
- * of record.
+/* Dumps the value_strings, range_strings or true/false strings for fields
+ * that have them. There is one record per line. Fields are tab-delimited.
+ * There are three types of records: Value String, Range String
+ * and True/False String. The first field, 'V', 'R' or 'T', indicates
+ * the type of record.
*
* Value Strings
* -------------
* Field 3 = Integer value
* Field 4 = String
*
+ * Range Strings
+ * -------------
+ * Field 1 = 'R'
+ * Field 2 = field abbreviation to which this range string corresponds
+ * Field 3 = Integer value: lower bound
+ * Field 4 = Integer value: upper bound
+ * Field 5 = String
+ *
* True/False Strings
* ------------------
* Field 1 = 'T'
header_field_info *hfinfo, *parent_hfinfo;
int i, len, vi;
const value_string *vals;
+ const range_string *range;
const true_false_string *tfs;
len = gpa_hfinfo.len;
* fields with the same name are really just versions
* of the same field stored in different bits, and
* should have the same type/radix/value list, and
- * just differ in their bit masks. (If a field isn't
+ * just differ in their bit masks. (If a field isn't
* a bitfield, but can be, say, 1 or 2 bytes long,
* it can just be made FT_UINT16, meaning the
* *maximum* length is 2 bytes, and be used
PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
- vals = NULL;
- tfs = NULL;
+ vals = NULL;
+ range = NULL;
+ tfs = NULL;
- if (hfinfo->display != BASE_CUSTOM &&
+ if ((hfinfo->display & BASE_DISPLAY_E_MASK) != BASE_CUSTOM &&
(hfinfo->type == FT_UINT8 ||
hfinfo->type == FT_UINT16 ||
hfinfo->type == FT_UINT24 ||
hfinfo->type == FT_INT32 ||
hfinfo->type == FT_INT64)) {
- vals = hfinfo->strings;
+ if ((hfinfo->display & BASE_RANGE_STRING) == 0) {
+ vals = hfinfo->strings;
+ } else {
+ range = hfinfo->strings;
+ }
}
else if (hfinfo->type == FT_BOOLEAN) {
tfs = hfinfo->strings;
}
}
+ /* print range strings? */
+ else if (range) {
+ vi = 0;
+ while (range[vi].strptr) {
+ /* Print in the proper base */
+ 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,
+ range[vi].value_max,
+ range[vi].strptr);
+ }
+ else {
+ printf("R\t%s\t%u\t%u\t%s\n",
+ hfinfo->abbrev,
+ range[vi].value_min,
+ range[vi].value_max,
+ range[vi].strptr);
+ }
+ vi++;
+ }
+ }
+
/* Print true/false strings? */
else if (tfs) {
printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
* Field 4 = type ( textual representation of the the ftenum type )
* Field 5 = parent protocol abbreviation
* Field 6 = blurb describing field
- * Field 7 = base for display (for integer types)
+ * Field 7 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
* Field 8 = blurb describing field (yes, apparently we repeated this accidentally)
*
* (format 3)
* Field 4 = type ( textual representation of the the ftenum type )
* Field 5 = parent protocol abbreviation
* Field 6 = blurb describing field
- * Field 7 = base for display (for integer types)
- * Field 8 = bitmask
+ * Field 7 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
+ * 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;
- const char *enum_name;
+ const char *enum_name;
const char *base_name;
const char *blurb;
+ char width[5];
len = gpa_hfinfo.len;
for (i = 0; i < len ; i++) {
/*
* Skip the pseudo-field for "proto_tree_add_text()" since
* we don't want it in the list of filterable fields.
- */
- if (hfinfo->id == hf_text_only)
+ */
+ if (hfinfo->id == hf_text_only)
continue;
/* format for protocols */
* fields with the same name are really just versions
* of the same field stored in different bits, and
* should have the same type/radix/value list, and
- * just differ in their bit masks. (If a field isn't
+ * just differ in their bit masks. (If a field isn't
* a bitfield, but can be, say, 1 or 2 bytes long,
* it can just be made FT_UINT16, meaning the
* *maximum* length is 2 bytes, and be used
hfinfo->type == FT_INT64) {
- switch(hfinfo->display) {
+ switch(hfinfo->display & BASE_DISPLAY_E_MASK) {
case BASE_NONE:
base_name = "BASE_NONE";
break;
case BASE_CUSTOM:
base_name = "BASE_CUSTOM";
break;
+ default:
+ base_name = "????";
+ break;
}
+ } else if (hfinfo->type == FT_BOOLEAN) {
+ /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
+ g_snprintf(width, sizeof(width), "%d", hfinfo->display);
+ base_name = width;
}
}
base_name, blurb);
}
else if (format == 3) {
- printf("F\t%s\t%s\t%s\t%s\t%s\t%s\t%u\n",
+ printf("F\t%s\t%s\t%s\t%s\t%s\t%s\t0x%x\n",
hfinfo->name, hfinfo->abbrev, enum_name,
parent_hfinfo->abbrev, blurb,
base_name, hfinfo->bitmask);
}
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 */
*/
static gboolean
construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
- char **filter)
+ char **filter)
{
header_field_info *hfinfo;
int abbrev_len;
hfinfo = finfo->hfinfo;
DISSECTOR_ASSERT(hfinfo);
- abbrev_len = strlen(hfinfo->abbrev);
+ 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) {
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
- case FT_FRAMENUM:
if (filter != NULL) {
format = hfinfo_numeric_format(hfinfo);
if(is_signed_num) {
} else {
*filter = ep_strdup_printf(format,
hfinfo->abbrev,
- fvalue_get_uinteger(&finfo->value));
+ fvalue_get_uinteger(&finfo->value));
}
}
break;
+ case FT_FRAMENUM:
+ DISSECTOR_ASSERT(!is_signed_num);
+ if (filter != NULL) {
+ format = hfinfo_numeric_format(hfinfo);
+ *filter = ep_strdup_printf(format,
+ hfinfo->abbrev,
+ fvalue_get_uinteger(&finfo->value));
+ }
+ break;
+
case FT_INT64:
case FT_UINT64:
if (filter != NULL) {
format = hfinfo_numeric_format(hfinfo);
*filter = ep_strdup_printf(format,
- hfinfo->abbrev,
- fvalue_get_integer64(&finfo->value));
+ hfinfo->abbrev,
+ fvalue_get_integer64(&finfo->value));
}
break;
break;
case FT_NONE:
- case FT_PCRE:
/*
* If the length is 0, just match the name of the
* field.
*filter = ep_alloc0(buf_len);
ptr = *filter;
- ptr += g_snprintf(ptr, buf_len-(ptr-*filter),
- "frame[%d:%d] == ", finfo->start, length);
+ ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
+ "frame[%d:%d] == ", finfo->start, length);
for (i=0;i<length; i++) {
c = tvb_get_guint8(finfo->ds_tvb, start);
start++;
if (i == 0 ) {
- ptr += g_snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
+ ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
}
else {
- ptr += g_snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
+ ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
}
}
}
break;
+ case FT_PCRE:
+ /* FT_PCRE never appears as a type for a registered field. It is
+ * only used internally. */
+ DISSECTOR_ASSERT_NOT_REACHED();
+ break;
+
/* By default, use the fvalue's "to_string_repr" method. */
default:
/* Figure out the string length needed.
- * The ft_repr length.
- * 4 bytes for " == ".
- * 1 byte for trailing NUL.
+ * The ft_repr length.
+ * 4 bytes for " == ".
+ * 1 byte for trailing NUL.
*/
if (filter != NULL) {
dfilter_len = fvalue_string_repr_len(&finfo->value,
/* Create the string */
g_snprintf(*filter, dfilter_len, "%s == ",
- hfinfo->abbrev);
+ hfinfo->abbrev);
fvalue_to_string_repr(&finfo->value,
- FTREPR_DFILTER,
- &(*filter)[abbrev_len + 4]);
+ FTREPR_DFILTER,
+ &(*filter)[abbrev_len + 4]);
}
break;
}
return filter;
}
-
/* This function is common code for both proto_tree_add_bitmask() and
- * proto_tree_add_bitmask_text() functions.
+ * 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;
else if (hf->strings) {
if (hf->display & BASE_RANGE_STRING) {
proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
- hf->name, rval_to_str(tmpval, hf->strings, "Unknown"));
+ hf->name, rval_to_str(tmpval, hf->strings, "Unknown"));
} else {
proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
- hf->name, val_to_str(tmpval, cVALS(hf->strings), "Unknown"));
+ hf->name, val_to_str(tmpval, cVALS(hf->strings), "Unknown"));
}
first = FALSE;
}
* This array is terminated by a NULL entry.
*
* FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
- * FT_integer fields that have a value_string attached will have the
+ * FT_integer fields that have a value_string attached will have the
* 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)
{
- return proto_tree_add_bits_ret_val(tree, hf_index, tvb, bit_offset, no_of_bits, NULL, little_endian);
+ header_field_info *hfinfo;
+
+ TRY_TO_FAKE_THIS_ITEM(tree, hf_index, 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.
+ * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
+ * 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;
- hf_field = proto_registrar_get_nth(hf_index);
+ /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
+ PROTO_REGISTRAR_GET_NTH(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",
*/
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){
*return_value=value;
}
- 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;
- }
+ /* Coast clear. Try and fake it */
+ TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field);
- 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)
{