X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=epan%2Fproto.c;h=287bf7383511cfd1863cfe313098b1522c8e8a98;hb=4e4e8476e74357a4af574d0fbadc10d3619365e1;hp=c2ac555d9d19527b4e7c4d049655e680457136e8;hpb=0ae0d9e86415642a2a88d3654f4ae2d8bf31ac48;p=obnox%2Fwireshark%2Fwip.git diff --git a/epan/proto.c b/epan/proto.c index c2ac555d9d..287bf73835 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -46,11 +46,15 @@ #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 { @@ -69,8 +73,8 @@ struct ptvcursor { }; /* Candidates for assembler */ -int -wrs_count_bitshift(guint32 bitmask) +static int +wrs_count_bitshift(const guint32 bitmask) { int bitshift = 0; @@ -93,21 +97,43 @@ wrs_count_bitshift(guint32 bitmask) will still have somewhere to attach to \ or else filtering will not work (they would be ignored since tree\ would be NULL). \ - We fake FT_PROTOCOL unless some clients have requested us \ + We fake FT_PROTOCOL unless some clients have requested us \ not to do so. \ */ \ - if (!tree) \ - return(NULL); \ - PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \ + 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((hfinfo->ref_count == HF_REF_TYPE_NONE) \ - && (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_REPR(tree, pi) +#endif + static gboolean proto_tree_free_node(proto_node *node, gpointer data); @@ -118,34 +144,33 @@ static void fill_label_bitfield(field_info *fi, gchar *label_str); 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); @@ -177,7 +202,7 @@ proto_tree_set_ipv4(field_info *fi, guint32 value); 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 @@ -201,10 +226,10 @@ proto_tree_set_uint64(field_info *fi, guint64 value); 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; @@ -225,12 +250,14 @@ struct _protocol { /* 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. */ @@ -242,8 +269,6 @@ static field_info *field_info_tmp=NULL; #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) @@ -256,8 +281,6 @@ 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) @@ -266,12 +289,10 @@ 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; @@ -325,17 +346,19 @@ proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_da 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; @@ -356,8 +379,8 @@ proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_da do. */ register_all_protocols_func(cb, client_data); #ifdef HAVE_PYTHON - /* Now scan for python protocols */ - register_all_py_protocols_func(cb, client_data); + /* Now scan for python protocols */ + register_all_py_protocols_func(cb, client_data); #endif #ifdef HAVE_PLUGINS @@ -376,8 +399,8 @@ proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_da 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); + /* Now do the same with python dissectors */ + register_all_py_handoffs_func(cb, client_data); #endif #ifdef HAVE_PLUGINS @@ -392,8 +415,7 @@ proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_da /* 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 @@ -405,8 +427,45 @@ proto_cleanup(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; @@ -415,12 +474,12 @@ proto_cleanup(void) gpa_hfinfo.hfi=NULL; } 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; @@ -439,7 +498,7 @@ proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func, current = child; child = current->next; if (proto_tree_traverse_pre_order((proto_tree *)current, func, - data)) + data)) return TRUE; } @@ -448,7 +507,7 @@ proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func, 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; @@ -464,7 +523,7 @@ proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func, current = child; child = current->next; if (proto_tree_traverse_post_order((proto_tree *)current, func, - data)) + data)) return TRUE; } if (func(pnode, data)) @@ -475,7 +534,7 @@ proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func, void proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func, - gpointer data) + gpointer data) { proto_node *node = tree; proto_node *current; @@ -498,12 +557,12 @@ proto_tree_free(proto_tree *tree) 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 != HF_REF_TYPE_NONE) { + 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 @@ -511,9 +570,9 @@ free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_) if( hfinfo->parent != -1 ) { header_field_info *parent_hfinfo; PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo); - parent_hfinfo->ref_count = HF_REF_TYPE_NONE; + parent_hfinfo->ref_type = HF_REF_TYPE_NONE; } - hfinfo->ref_count = HF_REF_TYPE_NONE; + hfinfo->ref_type = HF_REF_TYPE_NONE; } g_ptr_array_free(ptrs, TRUE); @@ -598,10 +657,14 @@ proto_tree_free_node(proto_node *node, gpointer data _U_) * 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 @@ -611,11 +674,11 @@ proto_tree_set_fake_protocols(proto_tree *tree, gboolean 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) @@ -630,7 +693,7 @@ proto_field_is_referenced(proto_tree *tree, int proto_id) return TRUE; PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo); - if (hfinfo->ref_count != HF_REF_TYPE_NONE) + if (hfinfo->ref_type != HF_REF_TYPE_NONE) return TRUE; if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols) @@ -651,10 +714,10 @@ proto_registrar_get_nth(guint hfindex) } -/* 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 */ @@ -670,7 +733,7 @@ prefix_hash (gconstpointer key) { break; } } - + return g_str_hash(copy); } @@ -679,19 +742,19 @@ 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; } @@ -706,7 +769,7 @@ proto_register_prefix(const char *prefix, prefix_initializer_t pi ) { if (! prefixes ) { prefixes = g_hash_table_new(prefix_hash,prefix_equal); } - + g_hash_table_insert(prefixes,(gpointer)prefix,pi); } @@ -733,23 +796,23 @@ proto_registrar_get_byname(const char *field_name) { header_field_info* hfinfo; prefix_initializer_t pi; - + 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); } @@ -779,7 +842,7 @@ ptvcursor_free_subtree_levels(ptvcursor_t * ptvc) } /* 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) { @@ -929,7 +992,7 @@ ptvcursor_add_text_with_subtree(ptvcursor_t * ptvc, gint length, 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); + ptvcursor_current_offset(ptvc), length); if (it == NULL) return(NULL); @@ -957,7 +1020,7 @@ proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint lengt /* 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; @@ -969,6 +1032,8 @@ proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint 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); @@ -990,6 +1055,8 @@ proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start, if (pi == NULL) return(NULL); + TRY_TO_FAKE_THIS_REPR(tree, pi); + proto_tree_set_representation(pi, format, ap); return pi; @@ -1030,17 +1097,17 @@ get_uint_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian) 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: @@ -1069,7 +1136,7 @@ get_int_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian) 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; @@ -1078,7 +1145,7 @@ get_int_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian) case 4: value = little_endian ? tvb_get_letohl(tvb, offset) - : tvb_get_ntohl(tvb, offset); + : tvb_get_ntohl(tvb, offset); break; default: @@ -1090,14 +1157,14 @@ get_int_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian) } static GPtrArray *proto_lookup_or_create_interesting_hfids(proto_tree *tree, - header_field_info *hfinfo) + header_field_info *hfinfo) { GPtrArray *ptrs = NULL; DISSECTOR_ASSERT(tree); DISSECTOR_ASSERT(hfinfo); - if (hfinfo->ref_count == HF_REF_TYPE_DIRECT) { + 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 = @@ -1109,7 +1176,7 @@ static GPtrArray *proto_lookup_or_create_interesting_hfids(proto_tree *tree, if (!ptrs) { /* First element triggers the creation of pointer array */ ptrs = g_ptr_array_new(); - g_hash_table_insert(PTREE_DATA(tree)->interesting_hfids, + g_hash_table_insert(PTREE_DATA(tree)->interesting_hfids, GINT_TO_POINTER(hfinfo->id), ptrs); } } @@ -1121,7 +1188,7 @@ static GPtrArray *proto_lookup_or_create_interesting_hfids(proto_tree *tree, the item is extracted from the tvbuff handed to it. */ static proto_item * proto_tree_new_item(field_info *new_fi, proto_tree *tree, - tvbuff_t *tvb, gint start, gint length, gboolean little_endian) + tvbuff_t *tvb, gint start, gint length, gboolean little_endian) { proto_item *pi; guint32 value, n; @@ -1176,7 +1243,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, 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? */ @@ -1185,7 +1252,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, 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: @@ -1200,33 +1267,33 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, 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; @@ -1299,7 +1366,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, * '\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. @@ -1316,7 +1383,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, 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; @@ -1366,7 +1433,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, 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; @@ -1379,7 +1446,7 @@ ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length, 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) { /* @@ -1393,20 +1460,19 @@ ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length, /* 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, ptvc->tvb, - offset, length, little_endian); + 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; @@ -1419,12 +1485,12 @@ proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb, return(NULL); return proto_tree_new_item(new_fi, tree, tvb, start, - length, little_endian); + 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; @@ -1437,6 +1503,8 @@ proto_tree_add_none_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st 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); @@ -1490,16 +1558,14 @@ proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gin 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; } @@ -1538,6 +1604,8 @@ proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -1559,6 +1627,8 @@ proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint s 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); @@ -1575,8 +1645,6 @@ proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length) 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); } @@ -1622,6 +1690,8 @@ proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -1643,6 +1713,8 @@ proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st 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); @@ -1654,16 +1726,8 @@ proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st 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); } @@ -1700,6 +1764,8 @@ proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -1721,6 +1787,8 @@ proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint 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); @@ -1768,6 +1836,8 @@ proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -1789,6 +1859,8 @@ proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st 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); @@ -1800,8 +1872,6 @@ proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st 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); } @@ -1839,6 +1909,8 @@ proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -1860,6 +1932,8 @@ proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st 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); @@ -1876,9 +1950,9 @@ 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) { - 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 */ @@ -1915,6 +1989,8 @@ proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -1936,6 +2012,8 @@ proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st 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); @@ -1948,8 +2026,6 @@ static void 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); } @@ -1996,6 +2072,8 @@ proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -2017,6 +2095,8 @@ proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint sta 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); @@ -2036,8 +2116,6 @@ proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length) 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); } @@ -2050,8 +2128,6 @@ proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length) 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); } @@ -2129,6 +2205,8 @@ proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -2150,6 +2228,8 @@ proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint 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); @@ -2204,11 +2284,8 @@ static void 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); } } @@ -2274,6 +2351,8 @@ proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -2295,6 +2374,8 @@ proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint s 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); @@ -2306,14 +2387,13 @@ proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint s 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 */ @@ -2350,6 +2430,8 @@ proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex, 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); @@ -2371,6 +2453,8 @@ proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint 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); @@ -2418,6 +2502,8 @@ proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -2439,6 +2525,8 @@ proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint s 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); @@ -2450,8 +2538,6 @@ proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint s 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); } @@ -2488,6 +2574,8 @@ proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -2509,6 +2597,8 @@ proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint 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); @@ -2520,8 +2610,6 @@ proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint 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); } @@ -2568,6 +2656,8 @@ proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -2589,6 +2679,8 @@ proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint st 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); @@ -2616,23 +2708,6 @@ proto_tree_set_uint(field_info *fi, guint32 value) } } - if (hfinfo->type == FT_BOOLEAN) { - const true_false_string *tfstring = (const true_false_string *)&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); } @@ -2669,6 +2744,8 @@ proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -2690,6 +2767,8 @@ proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint 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); @@ -2739,6 +2818,8 @@ proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -2760,6 +2841,8 @@ proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint sta 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); @@ -2787,17 +2870,6 @@ proto_tree_set_int(field_info *fi, gint32 value) } } - 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); } @@ -2834,6 +2906,8 @@ proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb, 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); @@ -2855,6 +2929,8 @@ proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint s 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); @@ -2862,9 +2938,6 @@ proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint s 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) @@ -2890,15 +2963,7 @@ proto_tree_add_node(proto_tree *tree, field_info *fi) } 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; @@ -2922,7 +2987,7 @@ proto_tree_add_node(proto_tree *tree, field_info *fi) * 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; @@ -2950,8 +3015,8 @@ proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, 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; @@ -3070,8 +3135,8 @@ get_hfi_and_length(int hfindex, tvbuff_t *tvb, gint start, gint *length, 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; } } @@ -3085,7 +3150,7 @@ get_hfi_and_length(int hfindex, tvbuff_t *tvb, gint start, gint *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) { field_info *fi; @@ -3112,8 +3177,8 @@ new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, } 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; @@ -3168,8 +3233,8 @@ proto_tree_set_representation_value(proto_item *pi, const char *format, va_list */ char *oldrep; - /* 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); @@ -3203,8 +3268,8 @@ proto_tree_set_representation(proto_item *pi, const char *format, va_list ap) */ char *oldrep; - /* 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); @@ -3215,6 +3280,189 @@ proto_tree_set_representation(proto_item *pi, const char *format, va_list ap) } } +/* -------------------------- */ +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, ...) @@ -3271,14 +3519,14 @@ proto_item_append_text(proto_item *pi, const char *format, ...) curlen = strlen(fi->rep->representation); if (ITEM_LABEL_LENGTH > curlen) { g_vsnprintf(fi->rep->representation + curlen, - ITEM_LABEL_LENGTH - (gulong) curlen, format, ap); + 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; @@ -3321,7 +3569,7 @@ proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end) } int -proto_item_get_len(proto_item *pi) +proto_item_get_len(const proto_item *pi) { field_info *fi = PITEM_FINFO(pi); return fi ? fi->length : -1; @@ -3335,7 +3583,7 @@ proto_item_get_len(proto_item *pi) } gboolean -proto_item_set_expert_flags(proto_item *pi, int group, guint severity) +proto_item_set_expert_flags(proto_item *pi, const int group, const guint severity) { if(pi == NULL || PITEM_FINFO(pi) == NULL) return FALSE; @@ -3354,7 +3602,7 @@ proto_item_set_expert_flags(proto_item *pi, int group, guint severity) proto_tree* proto_tree_create_root(void) { - proto_node *pnode; + proto_node *pnode; /* Initialize the proto_node */ PROTO_NODE_NEW(pnode); @@ -3384,7 +3632,7 @@ proto_tree_create_root(void) /* "prime" a proto_tree with a single hfid that a dfilter * is interested in. */ void -proto_tree_prime_hfid(proto_tree *tree _U_, gint hfid) +proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid) { header_field_info *hfinfo; @@ -3392,7 +3640,7 @@ proto_tree_prime_hfid(proto_tree *tree _U_, gint hfid) /* 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 = HF_REF_TYPE_DIRECT; + 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. @@ -3404,13 +3652,13 @@ proto_tree_prime_hfid(proto_tree *tree _U_, gint hfid) /* 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_count != HF_REF_TYPE_DIRECT) - parent_hfinfo->ref_count = HF_REF_TYPE_INDIRECT; + 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) @@ -3428,7 +3676,7 @@ proto_item_add_subtree(proto_item *pi, gint idx) { } proto_tree* -proto_item_get_subtree(proto_item *pi) { +proto_item_get_subtree(const proto_item *pi) { field_info *fi; if (!pi) @@ -3440,7 +3688,7 @@ proto_item_get_subtree(proto_item *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; @@ -3460,7 +3708,7 @@ proto_item_get_parent_nth(proto_item *ti, int gen) { 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; @@ -3484,46 +3732,46 @@ proto_tree_move_item(proto_tree *tree, proto_item *fixed_item, proto_item *item_ if (!tree || !PTREE_DATA(tree)->visible) return; - DISSECTOR_ASSERT(item_to_move->parent == tree); - DISSECTOR_ASSERT(fixed_item->parent == tree); + DISSECTOR_ASSERT(item_to_move->parent == tree); + DISSECTOR_ASSERT(fixed_item->parent == tree); - /*** cut item_to_move out ***/ + /*** cut item_to_move out ***/ - /* 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; + /* 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(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; - } - } + 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; + } + } - DISSECTOR_ASSERT(curr_item); + DISSECTOR_ASSERT(curr_item); - curr_item->next = item_to_move->next; + curr_item->next = item_to_move->next; - /* fix last_child if required */ - if(tree->last_child == item_to_move) { - tree->last_child = curr_item; - } - } + /* 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; - } + /*** 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; @@ -3545,114 +3793,118 @@ proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start, gint length 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->display = BASE_NONE; - hfinfo->strings = protocol; - hfinfo->bitmask = 0; - hfinfo->bitshift = 0; - hfinfo->ref_count = 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; + 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; } /* @@ -3689,7 +3941,7 @@ proto_get_next_protocol(void **cookie) } 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; @@ -3718,7 +3970,7 @@ proto_get_next_protocol_field(void **cookie) } protocol_t * -find_protocol_by_id(int proto_id) +find_protocol_by_id(const int proto_id) { header_field_info *hfinfo; @@ -3740,7 +3992,7 @@ static gint compare_filter_name(gconstpointer proto_arg, } int -proto_get_id(protocol_t *protocol) +proto_get_id(const protocol_t *protocol) { return protocol->proto_id; } @@ -3751,7 +4003,7 @@ int proto_get_id_by_filter_name(const gchar* filter_name) protocol_t *protocol; list_entry = g_list_find_custom(protocols, filter_name, - compare_filter_name); + compare_filter_name); if (list_entry == NULL) return -1; @@ -3760,7 +4012,7 @@ int proto_get_id_by_filter_name(const gchar* filter_name) } const char * -proto_get_protocol_name(int proto_id) +proto_get_protocol_name(const int proto_id) { protocol_t *protocol; @@ -3769,7 +4021,7 @@ proto_get_protocol_name(int proto_id) } const char * -proto_get_protocol_short_name(protocol_t *protocol) +proto_get_protocol_short_name(const protocol_t *protocol) { if (protocol == NULL) return "(none)"; @@ -3777,7 +4029,7 @@ proto_get_protocol_short_name(protocol_t *protocol) } const char * -proto_get_protocol_long_name(protocol_t *protocol) +proto_get_protocol_long_name(const protocol_t *protocol) { if (protocol == NULL) return "(none)"; @@ -3785,7 +4037,7 @@ proto_get_protocol_long_name(protocol_t *protocol) } const char * -proto_get_protocol_filter_name(int proto_id) +proto_get_protocol_filter_name(const int proto_id) { protocol_t *protocol; @@ -3796,13 +4048,13 @@ proto_get_protocol_filter_name(int proto_id) } 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; @@ -3811,7 +4063,7 @@ proto_can_toggle_protocol(int proto_id) } void -proto_set_decoding(int proto_id, gboolean enabled) +proto_set_decoding(const int proto_id, const gboolean enabled) { protocol_t *protocol; @@ -3838,7 +4090,7 @@ proto_enable_all(void) } void -proto_set_cant_toggle(int proto_id) +proto_set_cant_toggle(const int proto_id) { protocol_t *protocol; @@ -3849,7 +4101,7 @@ proto_set_cant_toggle(int proto_id) /* 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; @@ -3867,8 +4119,8 @@ proto_register_field_array(int parent, hf_register_info *hf, int num_records) */ 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; } @@ -3878,7 +4130,7 @@ proto_register_field_array(int parent, hf_register_info *hf, int num_records) 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); @@ -3891,12 +4143,12 @@ static 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 */ @@ -3936,15 +4188,15 @@ static void tmp_fld_check_assert(header_field_info *hfinfo) { 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 && @@ -3966,22 +4218,33 @@ static void tmp_fld_check_assert(header_field_info *hfinfo) { 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); @@ -4046,7 +4309,7 @@ proto_register_field_init(header_field_info *hfinfo, int parent) * 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) @@ -4061,7 +4324,7 @@ proto_register_field_init(header_field_info *hfinfo, int parent) } 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; @@ -4079,10 +4342,10 @@ proto_register_subtree_array(gint *const *indices, int num_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)); } /* @@ -4106,7 +4369,7 @@ proto_register_subtree_array(gint *const *indices, int num_indices) 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; @@ -4123,6 +4386,8 @@ proto_item_fill_label(field_info *fi, gchar *label_str) return; } + hfinfo = fi->hfinfo; + switch(hfinfo->type) { case FT_NONE: case FT_PROTOCOL: @@ -4142,7 +4407,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str) bytes_to_str(bytes, fvalue_length(&fi->value))); 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. */ g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s [truncated]: %s", @@ -4156,10 +4421,10 @@ proto_item_fill_label(field_info *fi, gchar *label_str) 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: @@ -4207,7 +4472,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str) case FT_ABSOLUTE_TIME: g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s: %s", hfinfo->name, - abs_time_to_str(fvalue_get(&fi->value))); + abs_time_to_str(fvalue_get(&fi->value), hfinfo->display)); break; case FT_RELATIVE_TIME: @@ -4271,7 +4536,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str) case FT_STRING: case FT_STRINGZ: - case FT_EBCDIC: + case FT_EBCDIC: case FT_UINT_STRING: bytes = fvalue_get(&fi->value); ret = g_snprintf(label_str, ITEM_LABEL_LENGTH, @@ -4279,7 +4544,7 @@ proto_item_fill_label(field_info *fi, gchar *label_str) 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. */ g_snprintf(label_str, ITEM_LABEL_LENGTH, "%s [truncated]: %s", @@ -4521,7 +4786,7 @@ fill_label_int64(field_info *fi, gchar *label_str) } int -hfinfo_bitwidth(header_field_info *hfinfo) +hfinfo_bitwidth(const header_field_info *hfinfo) { int bitwidth = 0; @@ -4557,13 +4822,12 @@ hfinfo_bitwidth(header_field_info *hfinfo) } 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; @@ -4572,7 +4836,7 @@ hfinfo_uint_vals_format(header_field_info *hfinfo) 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: @@ -4602,7 +4866,7 @@ hfinfo_uint_vals_format(header_field_info *hfinfo) } static const char* -hfinfo_uint_format(header_field_info *hfinfo) +hfinfo_uint_format(const header_field_info *hfinfo) { const char *format = NULL; @@ -4637,7 +4901,7 @@ hfinfo_uint_format(header_field_info *hfinfo) } break; case BASE_OCT: /* I'm lazy */ - format = "%s: %o"; + format = "%s: %#o"; break; case BASE_HEX: switch(hfinfo->type) { @@ -4686,7 +4950,7 @@ hfinfo_uint_format(header_field_info *hfinfo) } static const char* -hfinfo_uint_value_format(header_field_info *hfinfo) +hfinfo_uint_value_format(const header_field_info *hfinfo) { const char *format = NULL; @@ -4721,7 +4985,7 @@ hfinfo_uint_value_format(header_field_info *hfinfo) } break; case BASE_OCT: - format = "%o"; + format = "%#o"; break; case BASE_HEX: switch(hfinfo->type) { @@ -4770,13 +5034,12 @@ hfinfo_uint_value_format(header_field_info *hfinfo) } 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; @@ -4785,7 +5048,7 @@ hfinfo_int_vals_format(header_field_info *hfinfo) 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: @@ -4815,7 +5078,7 @@ hfinfo_int_vals_format(header_field_info *hfinfo) } static const char* -hfinfo_uint64_format(header_field_info *hfinfo) +hfinfo_uint64_format(const header_field_info *hfinfo) { const char *format = NULL; @@ -4828,7 +5091,7 @@ hfinfo_uint64_format(header_field_info *hfinfo) 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"; @@ -4844,7 +5107,7 @@ hfinfo_uint64_format(header_field_info *hfinfo) } static const char* -hfinfo_int_format(header_field_info *hfinfo) +hfinfo_int_format(const header_field_info *hfinfo) { const char *format = NULL; @@ -4873,7 +5136,7 @@ hfinfo_int_format(header_field_info *hfinfo) } break; case BASE_OCT: /* I'm lazy */ - format = "%s: %o"; + format = "%s: %#o"; break; case BASE_HEX: switch(hfinfo->type) { @@ -4921,7 +5184,7 @@ hfinfo_int_format(header_field_info *hfinfo) } static const char* -hfinfo_int_value_format(header_field_info *hfinfo) +hfinfo_int_value_format(const header_field_info *hfinfo) { const char *format = NULL; @@ -4950,7 +5213,7 @@ hfinfo_int_value_format(header_field_info *hfinfo) } break; case BASE_OCT: - format = "%o"; + format = "%#o"; break; case BASE_HEX: switch(hfinfo->type) { @@ -4998,7 +5261,7 @@ hfinfo_int_value_format(header_field_info *hfinfo) } static const char* -hfinfo_int64_format(header_field_info *hfinfo) +hfinfo_int64_format(const header_field_info *hfinfo) { const char *format = NULL; @@ -5011,7 +5274,7 @@ hfinfo_int64_format(header_field_info *hfinfo) 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"; @@ -5026,8 +5289,6 @@ hfinfo_int64_format(header_field_info *hfinfo) return format; } - - int proto_registrar_n(void) { @@ -5035,7 +5296,7 @@ proto_registrar_n(void) } const char* -proto_registrar_get_name(int n) +proto_registrar_get_name(const int n) { header_field_info *hfinfo; @@ -5044,7 +5305,7 @@ proto_registrar_get_name(int n) } const char* -proto_registrar_get_abbrev(int n) +proto_registrar_get_abbrev(const int n) { header_field_info *hfinfo; @@ -5053,7 +5314,7 @@ proto_registrar_get_abbrev(int n) } int -proto_registrar_get_ftype(int n) +proto_registrar_get_ftype(const int n) { header_field_info *hfinfo; @@ -5062,7 +5323,7 @@ proto_registrar_get_ftype(int n) } int -proto_registrar_get_parent(int n) +proto_registrar_get_parent(const int n) { header_field_info *hfinfo; @@ -5071,7 +5332,7 @@ proto_registrar_get_parent(int n) } gboolean -proto_registrar_is_protocol(int n) +proto_registrar_is_protocol(const int n) { header_field_info *hfinfo; @@ -5084,7 +5345,7 @@ proto_registrar_is_protocol(int n) * 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; @@ -5092,12 +5353,10 @@ proto_registrar_get_length(int n) 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); @@ -5118,8 +5377,11 @@ proto_check_for_protocol_or_field(proto_tree* tree, int id) * The caller should *not* free the GPtrArray*; proto_tree_free_node() * handles that. */ GPtrArray* -proto_get_finfo_ptr_array(proto_tree *tree, int id) +proto_get_finfo_ptr_array(const proto_tree *tree, const int id) { + if (!tree) + return NULL; + if (PTREE_DATA(tree)->interesting_hfids != NULL) return g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids, GINT_TO_POINTER(id)); @@ -5128,12 +5390,15 @@ proto_get_finfo_ptr_array(proto_tree *tree, int id) } gboolean -proto_tracking_interesting_fields(proto_tree *tree) +proto_tracking_interesting_fields(const proto_tree *tree) { + if (!tree) + return FALSE; + return (PTREE_DATA(tree)->interesting_hfids != NULL); } -/* 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; @@ -5158,10 +5423,10 @@ find_finfo(proto_node *node, gpointer data) * 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(, FALSE). +* g_ptr_array_free(, TRUE). */ GPtrArray* -proto_find_finfo(proto_tree *tree, int id) +proto_find_finfo(proto_tree *tree, const int id) { ffdata_t ffdata; @@ -5208,9 +5473,9 @@ typedef struct { } offset_search_t; static gboolean -check_for_offset(proto_node *node, gpointer data) +check_for_offset(proto_node *node, const gpointer data) { - field_info *fi = PNODE_FINFO(node); + field_info *fi = PNODE_FINFO(node); offset_search_t *offsearch = data; /* !fi == the top most container node which holds nothing */ @@ -5247,7 +5512,7 @@ proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb) 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. * @@ -5265,14 +5530,14 @@ proto_registrar_dump_protocols(void) 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_strings, range_strings or true/false strings for fields +/* 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 @@ -5329,7 +5594,7 @@ proto_registrar_dump_values(void) * 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 @@ -5344,7 +5609,7 @@ proto_registrar_dump_values(void) range = NULL; tfs = NULL; - if ((hfinfo->display & BASE_STRUCTURE_RESET) != BASE_CUSTOM && + if ((hfinfo->display & BASE_DISPLAY_E_MASK) != BASE_CUSTOM && (hfinfo->type == FT_UINT8 || hfinfo->type == FT_UINT16 || hfinfo->type == FT_UINT24 || @@ -5392,7 +5657,7 @@ proto_registrar_dump_values(void) vi = 0; while (range[vi].strptr) { /* Print in the proper base */ - if ((hfinfo->display & BASE_STRUCTURE_RESET) == BASE_HEX) { + if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_HEX) { printf("R\t%s\t0x%x\t0x%x\t%s\n", hfinfo->abbrev, range[vi].value_min, @@ -5463,12 +5728,11 @@ proto_registrar_dump_values(void) * 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]; @@ -5480,8 +5744,8 @@ proto_registrar_dump_fields(int format) /* * 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 */ @@ -5496,7 +5760,7 @@ proto_registrar_dump_fields(int format) * 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 @@ -5523,7 +5787,7 @@ proto_registrar_dump_fields(int format) hfinfo->type == FT_INT64) { - switch(hfinfo->display & BASE_STRUCTURE_RESET) { + switch(hfinfo->display & BASE_DISPLAY_E_MASK) { case BASE_NONE: base_name = "BASE_NONE"; break; @@ -5584,7 +5848,7 @@ proto_registrar_dump_fields(int format) } static const char* -hfinfo_numeric_format(header_field_info *hfinfo) +hfinfo_numeric_format(const header_field_info *hfinfo) { const char *format = NULL; @@ -5595,8 +5859,8 @@ hfinfo_numeric_format(header_field_info *hfinfo) */ 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 */ @@ -5666,7 +5930,7 @@ hfinfo_numeric_format(header_field_info *hfinfo) */ static gboolean construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, - char **filter) + char **filter) { header_field_info *hfinfo; int abbrev_len; @@ -5682,7 +5946,7 @@ construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, DISSECTOR_ASSERT(hfinfo); abbrev_len = (int) strlen(hfinfo->abbrev); - if (hfinfo->strings && (hfinfo->display & BASE_STRUCTURE_RESET) == BASE_NONE) { + if (hfinfo->strings && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) { const gchar *str = NULL; switch(hfinfo->type) { @@ -5759,7 +6023,7 @@ construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, } else { *filter = ep_strdup_printf(format, hfinfo->abbrev, - fvalue_get_uinteger(&finfo->value)); + fvalue_get_uinteger(&finfo->value)); } } break; @@ -5770,7 +6034,7 @@ construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, format = hfinfo_numeric_format(hfinfo); *filter = ep_strdup_printf(format, hfinfo->abbrev, - fvalue_get_uinteger(&finfo->value)); + fvalue_get_uinteger(&finfo->value)); } break; @@ -5779,8 +6043,8 @@ construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, 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; @@ -5846,7 +6110,7 @@ construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, ptr = *filter; ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), - "frame[%d:%d] == ", finfo->start, length); + "frame[%d:%d] == ", finfo->start, length); for (i=0;ids_tvb, start); start++; @@ -5861,7 +6125,7 @@ construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, break; case FT_PCRE: - /* FT_PCRE never appears as a type for a registered field. It is + /* FT_PCRE never appears as a type for a registered field. It is * only used internally. */ DISSECTOR_ASSERT_NOT_REACHED(); break; @@ -5869,9 +6133,9 @@ construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, /* 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, @@ -5881,10 +6145,10 @@ construct_match_selected_string(field_info *finfo, epan_dissect_t *edt, /* 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; } @@ -5920,13 +6184,12 @@ proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt) 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; @@ -5988,10 +6251,10 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, int offset, int len 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; } @@ -6057,12 +6320,12 @@ proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, int offset, int len * 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; @@ -6083,9 +6346,9 @@ proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb, guint offset, int /* 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; @@ -6102,7 +6365,7 @@ proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb, guint offset } proto_item * -proto_tree_add_bits_item(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian) +proto_tree_add_bits_item(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, const gboolean little_endian) { header_field_info *hfinfo; @@ -6110,26 +6373,24 @@ proto_tree_add_bits_item(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint bit return proto_tree_add_bits_ret_val(tree, hf_index, tvb, bit_offset, no_of_bits, NULL, little_endian); } + /* * This function will dissect a sequence of bits that does not need to be byte aligned; the bits - * set vill be shown in the tree as ..10 10.. and the integer value returned if return_value is set. + * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set. * Offset should be given in bits from the start of the tvb. */ proto_item * -proto_tree_add_bits_ret_val(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint bit_offset, gint no_of_bits, guint64 *return_value, gboolean little_endian) +proto_tree_add_bits_ret_val(proto_tree *tree, const int hf_index, tvbuff_t *tvb, const gint bit_offset, const gint no_of_bits, guint64 *return_value, const gboolean little_endian) { const char *format = NULL; gint offset; guint length; guint8 tot_no_bits; - guint8 remaining_bits; - guint64 mask = 0,tmp; char *str; header_field_info *hf_field; guint64 value = 0; - int bit; - int i; + const true_false_string *tfstring; /* We can't fake it just yet. We have to fill in the 'return_value' parameter */ PROTO_REGISTRAR_GET_NTH(hf_index, hf_field); @@ -6150,8 +6411,8 @@ proto_tree_add_bits_ret_val(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint */ 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){ @@ -6174,43 +6435,7 @@ proto_tree_add_bits_ret_val(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint /* Coast clear. Try and fake it */ TRY_TO_FAKE_THIS_ITEM(tree, hf_index, hf_field); - mask = 1; - mask = mask << (no_of_bits-1); - - /* prepare the string */ - str=ep_alloc(256); - str[0]='\0'; - for(bit=0;bit<((int)(bit_offset&0x07));bit++){ - if(bit&&(!(bit%4))){ - strcat(str, " "); - } - strcat(str,"."); - } - - /* read the bits for the int */ - for(i=0;i>1; - } - - for(;bit%8;bit++){ - if(bit&&(!(bit%4))){ - strcat(str, " "); - } - strcat(str,"."); - } + str = decode_bits_in_field(bit_offset, no_of_bits, value); strcat(str," = "); strcat(str,hf_field->name); @@ -6218,19 +6443,13 @@ proto_tree_add_bits_ret_val(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint 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: @@ -6277,6 +6496,198 @@ proto_tree_add_bits_ret_val(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint } } +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) {