2 * Routines for protocol tree
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
36 #include "ptvcursor.h"
38 #include "addr_resolv.h"
39 #include "oid_resolv.h"
42 #include "epan_dissect.h"
47 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
48 #define SUBTREE_MAX_LEVELS 256
51 typedef struct __subtree_lvl {
58 subtree_lvl *pushed_tree;
59 guint8 pushed_tree_index;
60 guint8 pushed_tree_max;
66 #define cVALS(x) (const value_string*)(x)
69 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex) \
70 /* If this item is not referenced we dont have to do much work \
71 at all but we should still return a node so that \
72 field items below this node ( think proto_item_add_subtree() )\
73 will still have somewhere to attach to \
74 or else filtering will not work (they would be ignored since tree\
76 DONT try to fake a node where PITEM_FINFO(pi) is NULL \
77 since dissectors that want to do proto_item_set_len() ot \
78 other operations that dereference this would crash. \
79 We dont fake FT_PROTOCOL either since these are cheap and \
80 some stuff (proto hier stat) assumes they always exist. \
82 if(!(PTREE_DATA(tree)->visible)){ \
83 if(PITEM_FINFO(tree)){ \
84 register header_field_info *hfinfo; \
85 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
86 if((hfinfo->ref_count == 0) \
87 && (hfinfo->type!=FT_PROTOCOL)){ \
88 /* just return tree back to the caller */\
94 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex) ;
98 proto_tree_free_node(proto_node *node, gpointer data);
100 static void fill_label_boolean(field_info *fi, gchar *label_str);
101 static void fill_label_uint(field_info *fi, gchar *label_str);
102 static void fill_label_uint64(field_info *fi, gchar *label_str);
103 static void fill_label_enumerated_uint(field_info *fi, gchar *label_str);
104 static void fill_label_enumerated_bitfield(field_info *fi, gchar *label_str);
105 static void fill_label_numeric_bitfield(field_info *fi, gchar *label_str);
106 static void fill_label_int(field_info *fi, gchar *label_str);
107 static void fill_label_int64(field_info *fi, gchar *label_str);
108 static void fill_label_enumerated_int(field_info *fi, gchar *label_str);
110 int hfinfo_bitwidth(header_field_info *hfinfo);
111 static const char* hfinfo_uint_vals_format(header_field_info *hfinfo);
112 static const char* hfinfo_uint_format(header_field_info *hfinfo);
113 static const char* hfinfo_uint64_format(header_field_info *hfinfo);
114 static const char* hfinfo_int_vals_format(header_field_info *hfinfo);
115 static const char* hfinfo_int_format(header_field_info *hfinfo);
116 static const char* hfinfo_int64_format(header_field_info *hfinfo);
119 proto_tree_add_node(proto_tree *tree, field_info *fi);
121 static header_field_info *
122 get_hfi_and_length(int hfindex, tvbuff_t *tvb, gint start, gint *length,
126 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
127 gint start, gint item_length);
130 alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb,
131 gint start, gint *length);
134 proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb,
135 gint start, gint *length, field_info **pfi);
138 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
140 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
143 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb);
145 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
147 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
149 proto_tree_set_time(field_info *fi, nstime_t *value_ptr);
151 proto_tree_set_string(field_info *fi, const char* value);
153 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
155 proto_tree_set_ether(field_info *fi, const guint8* value);
157 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
159 proto_tree_set_ipxnet(field_info *fi, guint32 value);
161 proto_tree_set_ipv4(field_info *fi, guint32 value);
163 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
165 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start);
167 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
169 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian);
171 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
173 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
175 proto_tree_set_boolean(field_info *fi, guint32 value);
177 proto_tree_set_float(field_info *fi, float value);
179 proto_tree_set_double(field_info *fi, double value);
181 proto_tree_set_uint(field_info *fi, guint32 value);
183 proto_tree_set_int(field_info *fi, gint32 value);
185 proto_tree_set_uint64(field_info *fi, guint64 value);
187 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian);
189 static int proto_register_field_init(header_field_info *hfinfo, int parent);
191 /* Comparision function for tree insertion. A wrapper around strcmp() */
192 static int g_strcmp(gconstpointer a, gconstpointer b);
194 /* special-case header field used within proto.c */
195 int hf_text_only = -1;
197 /* Structure for information about a protocol */
199 const char *name; /* long description */
200 const char *short_name; /* short description */
201 const char *filter_name; /* name of this protocol in filters */
202 int proto_id; /* field ID for this protocol */
203 GList *fields; /* fields for this protocol */
204 GList *last_field; /* pointer to end of list of fields */
205 gboolean is_enabled; /* TRUE if protocol is enabled */
206 gboolean can_toggle; /* TRUE if is_enabled can be changed */
209 /* List of all protocols */
210 static GList *protocols = NULL;
212 #define INITIAL_NUM_PROTOCOL_HFINFO 200
215 /* Contains information about protocols and header fields. Used when
216 * dissectors register their data */
217 static GMemChunk *gmc_hfinfo = NULL;
219 /* Contains information about a field when a dissector calls
220 * proto_tree_add_item. */
221 SLAB_ITEM_TYPE_DEFINE(field_info)
222 static SLAB_FREE_LIST_DEFINE(field_info)
223 static field_info *field_info_tmp=NULL;
224 #define FIELD_INFO_NEW(fi) \
225 SLAB_ALLOC(fi, field_info)
226 #define FIELD_INFO_FREE(fi) \
227 SLAB_FREE(fi, field_info)
231 /* Contains the space for proto_nodes. */
232 SLAB_ITEM_TYPE_DEFINE(proto_node)
233 static SLAB_FREE_LIST_DEFINE(proto_node)
234 #define PROTO_NODE_NEW(node) \
235 SLAB_ALLOC(node, proto_node) \
236 node->first_child = NULL; \
237 node->last_child = NULL; \
240 #define PROTO_NODE_FREE(node) \
241 SLAB_FREE(node, proto_node)
245 /* String space for protocol and field items for the GUI */
246 SLAB_ITEM_TYPE_DEFINE(item_label_t)
247 static SLAB_FREE_LIST_DEFINE(item_label_t)
248 #define ITEM_LABEL_NEW(il) \
249 SLAB_ALLOC(il, item_label_t)
250 #define ITEM_LABEL_FREE(il) \
251 SLAB_FREE(il, item_label_t)
254 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
255 DISSECTOR_ASSERT((guint)hfindex < gpa_hfinfo.len); \
256 hfinfo=gpa_hfinfo.hfi[hfindex];
259 /* List which stores protocols and fields that have been registered */
260 typedef struct _gpa_hfinfo_t {
262 guint32 allocated_len;
263 header_field_info **hfi;
265 gpa_hfinfo_t gpa_hfinfo;
267 /* Balanced tree of abbreviations and IDs */
268 static GTree *gpa_name_tree = NULL;
270 /* Points to the first element of an array of Booleans, indexed by
271 a subtree item type; that array element is TRUE if subtrees of
272 an item of that type are to be expanded. */
273 gboolean *tree_is_expanded;
275 /* Number of elements in that array. */
278 /* Name hashtables for fast detection of duplicate names */
279 static GHashTable* proto_names = NULL;
280 static GHashTable* proto_short_names = NULL;
281 static GHashTable* proto_filter_names = NULL;
284 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
286 const protocol_t *p1 = p1_arg;
287 const protocol_t *p2 = p2_arg;
289 return g_strcasecmp(p1->short_name, p2->short_name);
293 /* initialize data structures and register protocols and fields */
295 proto_init(void (register_all_protocols)(register_cb cb, gpointer client_data),
296 void (register_all_protocol_handoffs)(register_cb cb, gpointer client_data),
298 gpointer client_data)
300 static hf_register_info hf[] = {
302 { "Proto Init", "", FT_NONE, BASE_NONE, NULL, 0x0,
307 proto_names = g_hash_table_new(g_int_hash, g_int_equal);
308 proto_short_names = g_hash_table_new(g_int_hash, g_int_equal);
309 proto_filter_names = g_hash_table_new(g_int_hash, g_int_equal);
313 gmc_hfinfo = g_mem_chunk_new("gmc_hfinfo",
314 sizeof(header_field_info),
315 INITIAL_NUM_PROTOCOL_HFINFO * sizeof(header_field_info),
319 gpa_hfinfo.allocated_len=0;
321 gpa_name_tree = g_tree_new(g_strcmp);
323 /* Initialize the ftype subsystem */
326 /* Register one special-case FT_TEXT_ONLY field for use when
327 converting wireshark to new-style proto_tree. These fields
328 are merely strings on the GUI tree; they are not filterable */
329 proto_register_field_array(-1, hf, array_length(hf));
331 /* Have each built-in dissector register its protocols, fields,
332 dissector tables, and dissectors to be called through a
333 handle, and do whatever one-time initialization it needs to
335 register_all_protocols(cb, client_data);
338 /* Now scan for plugins and load all the ones we find, calling
339 their register routines to do the stuff described above. */
341 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
345 /* Now call the "handoff registration" routines of all built-in
346 dissectors; those routines register the dissector in other
347 dissectors' handoff tables, and fetch any dissector handles
349 register_all_protocol_handoffs(cb, client_data);
352 /* Now do the same with plugins. */
354 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
355 register_all_plugin_handoffs();
358 /* sort the protocols by protocol name */
359 protocols = g_list_sort(protocols, proto_compare_name);
361 /* We've assigned all the subtree type values; allocate the array
362 for them, and zero it out. */
363 tree_is_expanded = g_malloc(num_tree_types*sizeof (gboolean));
364 memset(tree_is_expanded, 0, num_tree_types*sizeof (gboolean));
367 /* String comparison func for dfilter_token GTree */
369 g_strcmp(gconstpointer a, gconstpointer b)
371 return strcmp((const char*)a, (const char*)b);
377 /* Free the abbrev/ID GTree */
379 g_tree_destroy(gpa_name_tree);
380 gpa_name_tree = NULL;
384 g_mem_chunk_destroy(gmc_hfinfo);
386 if(gpa_hfinfo.allocated_len){
388 gpa_hfinfo.allocated_len=0;
389 g_free(gpa_hfinfo.hfi);
392 if (tree_is_expanded != NULL)
393 g_free(tree_is_expanded);
397 typedef gboolean (*proto_tree_traverse_func)(proto_node *, gpointer);
400 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
403 proto_node *pnode = tree;
407 if (func(pnode, data))
410 child = pnode->first_child;
411 while (child != NULL) {
413 * The routine we call might modify the child, e.g. by
414 * freeing it, so we get the child's successor before
415 * calling that routine.
418 child = current->next;
419 if (proto_tree_traverse_pre_order((proto_tree *)current, func,
428 proto_tree_traverse_in_order(proto_tree *tree, proto_tree_traverse_func func,
431 proto_node *pnode = tree;
435 child = pnode->first_child;
438 * The routine we call might modify the child, e.g. by
439 * freeing it, so we get the child's successor before
440 * calling that routine.
443 child = current->next;
445 if (proto_tree_traverse_in_order((proto_tree *)current, func,
449 if (func(pnode, data))
452 while (child != NULL) {
454 * The routine we call might modify the child, e.g. by
455 * freeing it, so we get the child's successor before
456 * calling that routine.
459 child = current->next;
460 if (proto_tree_traverse_in_order((proto_tree *)current,
465 if (func(pnode, data))
473 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
476 proto_node *node = tree;
479 node = node->first_child;
480 while (node != NULL) {
482 node = current->next;
483 func((proto_tree *)current, data);
487 /* frees the resources that the dissection a proto_tree uses */
489 proto_tree_free(proto_tree *tree)
491 proto_tree_traverse_in_order(tree, proto_tree_free_node, NULL);
495 free_GPtrArray_value(gpointer key _U_, gpointer value, gpointer user_data _U_)
497 GPtrArray *ptrs = value;
498 gint hfid = (gint)key;
499 header_field_info *hfinfo;
502 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
503 if(hfinfo->ref_count){
504 /* when a field is referenced by a filter this also
505 affects the refcount for the parent protocol so we need
506 to adjust the refcount for the parent as well
508 if( (hfinfo->parent != -1) && (hfinfo->ref_count) ){
509 header_field_info *parent_hfinfo;
510 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
511 parent_hfinfo->ref_count -= hfinfo->ref_count;
513 hfinfo->ref_count = 0;
516 g_ptr_array_free(ptrs, TRUE);
520 free_node_tree_data(tree_data_t *tree_data)
522 /* Free all the GPtrArray's in the interesting_hfids hash. */
523 g_hash_table_foreach(tree_data->interesting_hfids,
524 free_GPtrArray_value, NULL);
526 /* And then destroy the hash. */
527 g_hash_table_destroy(tree_data->interesting_hfids);
529 /* And finally the tree_data_t itself. */
533 #define FREE_NODE_FIELD_INFO(finfo) \
535 ITEM_LABEL_FREE(finfo->rep); \
537 FVALUE_CLEANUP(&finfo->value); \
538 FIELD_INFO_FREE(finfo);
541 proto_tree_free_node(proto_node *node, gpointer data _U_)
543 field_info *finfo = PITEM_FINFO(node);
546 /* This is the root node. Destroy the per-tree data.
547 * There is no field_info to destroy. */
548 free_node_tree_data(PTREE_DATA(node));
551 /* This is a child node. Don't free the per-tree data, but
552 * do free the field_info data. */
553 FREE_NODE_FIELD_INFO(finfo);
556 /* Free the proto_node. */
557 PROTO_NODE_FREE(node);
559 return FALSE; /* FALSE = do not end traversal of protocol tree */
562 /* Is the parsing being done for a visible proto_tree or an invisible one?
563 * By setting this correctly, the proto_tree creation is sped up by not
564 * having to call g_vsnprintf and copy strings around.
567 proto_tree_set_visible(proto_tree *tree, gboolean visible)
569 PTREE_DATA(tree)->visible = visible;
572 /* Assume dissector set only its protocol fields.
573 This function is called by dissectors and allowes to speed up filtering
574 in wireshark, if this function returns FALSE it is safe to reset tree to NULL
575 and thus skip calling most of the expensive proto_tree_add_...()
577 If the tree is visible we implicitely assume the field is referenced.
580 proto_field_is_referenced(proto_tree *tree, int proto_id)
582 register header_field_info *hfinfo;
588 if (PTREE_DATA(tree)->visible)
591 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
592 if (hfinfo->ref_count != 0)
599 /* Finds a record in the hf_info_records array by id. */
601 proto_registrar_get_nth(guint hfindex)
603 register header_field_info *hfinfo;
605 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
609 /* Finds a record in the hf_info_records array by name.
612 proto_registrar_get_byname(const char *field_name)
614 DISSECTOR_ASSERT(field_name != NULL);
615 return g_tree_lookup(gpa_name_tree, field_name);
619 void ptvcursor_new_subtree_levels(ptvcursor_t * ptvc)
621 subtree_lvl * pushed_tree;
623 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
624 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
626 pushed_tree = ep_alloc(sizeof(subtree_lvl) * ptvc->pushed_tree_max);
627 DISSECTOR_ASSERT(pushed_tree != NULL);
628 if (ptvc->pushed_tree)
629 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
630 ptvc->pushed_tree = pushed_tree;
633 void ptvcursor_free_subtree_levels(ptvcursor_t * ptvc)
635 ptvc->pushed_tree = NULL;
636 ptvc->pushed_tree_max = 0;
637 DISSECTOR_ASSERT(ptvc->pushed_tree_index ==0);
638 ptvc->pushed_tree_index = 0;
641 /* Allocates an initializes a ptvcursor_t with 3 variables:
642 * proto_tree, tvbuff, and offset. */
644 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
648 ptvc = ep_alloc(sizeof(ptvcursor_t));
651 ptvc->offset = offset;
652 ptvc->pushed_tree= NULL;
653 ptvc->pushed_tree_max= 0;
654 ptvc->pushed_tree_index= 0;
659 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
661 ptvcursor_free(ptvcursor_t *ptvc)
663 ptvcursor_free_subtree_levels(ptvc);
667 /* Returns tvbuff. */
669 ptvcursor_tvbuff(ptvcursor_t* ptvc)
674 /* Returns current offset. */
676 ptvcursor_current_offset(ptvcursor_t* ptvc)
682 ptvcursor_tree(ptvcursor_t* ptvc)
691 ptvcursor_set_tree(ptvcursor_t* ptvc, proto_tree *tree)
696 /* creates a subtree, sets it as the working tree and pushes the old working tree */
698 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
700 subtree_lvl * subtree;
701 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
702 ptvcursor_new_subtree_levels(ptvc);
704 subtree = ptvc->pushed_tree+ptvc->pushed_tree_index;
705 subtree->tree = ptvc->tree;
707 ptvc->pushed_tree_index++;
708 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
713 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
715 subtree_lvl * subtree;
716 if (ptvc->pushed_tree_index <= 0)
719 ptvc->pushed_tree_index--;
720 subtree = ptvc->pushed_tree+ptvc->pushed_tree_index;
721 if (subtree->it != NULL)
722 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
723 ptvc->tree = subtree->tree;
726 /* saves the current tvb offset and the item in the current subtree level */
727 void ptvcursor_subtree_set_item(ptvcursor_t * ptvc, proto_item * it)
729 subtree_lvl * subtree;
731 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
733 subtree = ptvc->pushed_tree+ptvc->pushed_tree_index-1;
735 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
738 /* Creates a subtree and adds it to the cursor as the working tree but does not
739 * save the old working tree */
741 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
743 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
747 proto_tree* ptvcursor_add_subtree_item(ptvcursor_t * ptvc, proto_item * it, gint ett_subtree, gint length)
749 ptvcursor_push_subtree(ptvc, it, ett_subtree);
750 if (length == SUBTREE_UNDEFINED_LENGTH)
751 ptvcursor_subtree_set_item(ptvc, it);
752 return ptvcursor_tree(ptvc);
755 /* Add an item to the tree and create a subtree
756 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
757 * In this case, when the subtree will be closed, the parent item length will
758 * be equal to the advancement of the cursor since the creation of the subtree.
760 proto_tree* ptvcursor_add_with_subtree(ptvcursor_t * ptvc, int hfindex, gint length,
761 gboolean little_endian, gint ett_subtree)
764 it = ptvcursor_add_no_advance(ptvc, hfindex, length, little_endian);
765 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
769 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
771 /* Add a text node to the tree and create a subtree
772 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
773 * In this case, when the subtree will be closed, the item length will be equal
774 * to the advancement of the cursor since the creation of the subtree.
776 proto_tree * ptvcursor_add_text_with_subtree(ptvcursor_t * ptvc, gint length,
777 gint ett_subtree, const char *format, ...)
782 it = proto_tree_add_text_node(ptvcursor_tree(ptvc), ptvcursor_tvbuff(ptvc),
783 ptvcursor_current_offset(ptvc), length);
785 va_start(ap, format);
786 proto_tree_set_representation(it, format, ap);
789 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
792 /* Add a text-only node, leaving it to our caller to fill the text in */
794 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
798 pi = proto_tree_add_pi(tree, hf_text_only, tvb, start, &length, NULL);
805 /* Add a text-only node to the proto_tree */
807 proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
808 const char *format, ...)
813 pi = proto_tree_add_text_node(tree, tvb, start, length);
817 va_start(ap, format);
818 proto_tree_set_representation(pi, format, ap);
824 /* Add a text-only node to the proto_tree (va_list version) */
826 proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start,
827 gint length, const char *format, va_list ap)
831 pi = proto_tree_add_text_node(tree, tvb, start, length);
835 proto_tree_set_representation(pi, format, ap);
840 /* Add a text-only node for debugging purposes. The caller doesn't need
841 * to worry about tvbuff, start, or length. Debug message gets sent to
844 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
849 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
853 va_start(ap, format);
854 proto_tree_set_representation(pi, format, ap);
864 get_uint_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian)
871 value = tvb_get_guint8(tvb, offset);
875 value = little_endian ? tvb_get_letohs(tvb, offset)
876 : tvb_get_ntohs(tvb, offset);
880 value = little_endian ? tvb_get_letoh24(tvb, offset)
881 : tvb_get_ntoh24(tvb, offset);
885 value = little_endian ? tvb_get_letohl(tvb, offset)
886 : tvb_get_ntohl(tvb, offset);
890 DISSECTOR_ASSERT_NOT_REACHED();
898 get_int_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian)
905 value = (gint8)tvb_get_guint8(tvb, offset);
909 value = (gint16) (little_endian ? tvb_get_letohs(tvb, offset)
910 : tvb_get_ntohs(tvb, offset));
914 value = little_endian ? tvb_get_letoh24(tvb, offset)
915 : tvb_get_ntoh24(tvb, offset);
916 if (value & 0x00800000) {
917 /* Sign bit is set; sign-extend it. */
923 value = little_endian ? tvb_get_letohl(tvb, offset)
924 : tvb_get_ntohl(tvb, offset);
928 DISSECTOR_ASSERT_NOT_REACHED();
935 /* Add an item to a proto_tree, using the text label registered to that item;
936 the item is extracted from the tvbuff handed to it. */
938 proto_tree_new_item(field_info *new_fi, proto_tree *tree, int hfindex,
939 tvbuff_t *tvb, gint start, gint length, gboolean little_endian)
949 /* there is a possibility here that we might raise an exception
950 * and thus would lose track of the field_info.
951 * store it in a temp so that if we come here again we can reclaim
952 * the field_info without leaking memory.
954 /* XXX this only keeps track of one field_info struct,
955 if we ever go multithreaded for calls to this function
956 we have to change this code to use per thread variable.
959 /* oops, last one we got must have been lost due
961 * good thing we saved it, now we can reverse the
962 * memory leak and reclaim it.
964 SLAB_FREE(field_info_tmp, field_info);
966 /* we might throw an exception, keep track of this one
967 * across the "dangerous" section below.
969 field_info_tmp=new_fi;
971 switch(new_fi->hfinfo->type) {
973 /* no value to set for FT_NONE */
977 proto_tree_set_protocol_tvb(new_fi, tvb);
981 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
985 n = get_uint_value(tvb, start, length, little_endian);
986 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
988 /* Instead of calling proto_item_set_len(), since we don't yet
989 * have a proto_item, we set the field_info's length ourselves. */
990 new_fi->length = n + length;
994 proto_tree_set_boolean(new_fi,
995 get_uint_value(tvb, start, length, little_endian));
998 /* XXX - make these just FT_UINT? */
1003 proto_tree_set_uint(new_fi,
1004 get_uint_value(tvb, start, length, little_endian));
1009 DISSECTOR_ASSERT(length == 8);
1010 proto_tree_set_uint64_tvb(new_fi, tvb, start, little_endian);
1013 /* XXX - make these just FT_INT? */
1018 proto_tree_set_int(new_fi,
1019 get_int_value(tvb, start, length, little_endian));
1023 DISSECTOR_ASSERT(length == 4);
1024 value = tvb_get_ipv4(tvb, start);
1025 proto_tree_set_ipv4(new_fi, little_endian ? GUINT32_SWAP_LE_BE(value) : value);
1029 DISSECTOR_ASSERT(length == 4);
1030 proto_tree_set_ipxnet(new_fi,
1031 get_uint_value(tvb, start, 4, FALSE));
1035 DISSECTOR_ASSERT(length == 16);
1036 proto_tree_set_ipv6_tvb(new_fi, tvb, start);
1040 DISSECTOR_ASSERT(length == 6);
1041 proto_tree_set_ether_tvb(new_fi, tvb, start);
1045 DISSECTOR_ASSERT(length == 16);
1046 proto_tree_set_guid_tvb(new_fi, tvb, start, little_endian);
1050 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
1054 DISSECTOR_ASSERT(length == 4);
1056 floatval = tvb_get_letohieee_float(tvb, start);
1058 floatval = tvb_get_ntohieee_float(tvb, start);
1059 proto_tree_set_float(new_fi, floatval);
1063 DISSECTOR_ASSERT(length == 8);
1065 doubleval = tvb_get_letohieee_double(tvb, start);
1067 doubleval = tvb_get_ntohieee_double(tvb, start);
1068 proto_tree_set_double(new_fi, doubleval);
1072 proto_tree_set_string_tvb(new_fi, tvb, start, length);
1076 DISSECTOR_ASSERT(length >= -1);
1077 /* Instead of calling proto_item_set_len(),
1078 * since we don't yet have a proto_item, we
1079 * set the field_info's length ourselves.
1081 * XXX - our caller can't use that length to
1082 * advance an offset unless they arrange that
1083 * there always be a protocol tree into which
1084 * we're putting this item.
1087 /* This can throw an exception */
1088 length = tvb_strsize(tvb, start);
1090 string = ep_alloc(length);
1092 tvb_memcpy(tvb, string, start, length);
1093 } else if (length == 0) {
1096 /* In this case, length signifies
1097 * the length of the string.
1099 * This could either be a null-padded
1100 * string, which doesn't necessarily
1101 * have a '\0' at the end, or a
1102 * null-terminated string, with a
1103 * trailing '\0'. (Yes, there are
1104 * cases where you have a string
1105 * that's both counted and null-
1108 * In the first case, we must
1109 * allocate a buffer of length
1110 * "length+1", to make room for
1113 * In the second case, we don't
1114 * assume that there is a trailing
1115 * '\0' there, as the packet might
1116 * be malformed. (XXX - should we
1117 * throw an exception if there's no
1118 * trailing '\0'?) Therefore, we
1119 * allocate a buffer of length
1120 * "length+1", and put in a trailing
1121 * '\0', just to be safe.
1123 * (XXX - this would change if
1124 * we made string values counted
1125 * rather than null-terminated.)
1127 string = tvb_get_ephemeral_string(tvb,
1131 new_fi->length = length;
1132 proto_tree_set_string(new_fi, string);
1135 case FT_UINT_STRING:
1136 n = get_uint_value(tvb, start, length, little_endian);
1137 proto_tree_set_string_tvb(new_fi, tvb, start + length, n);
1139 /* Instead of calling proto_item_set_len(), since we
1140 * don't yet have a proto_item, we set the
1141 * field_info's length ourselves.
1143 * XXX - our caller can't use that length to
1144 * advance an offset unless they arrange that
1145 * there always be a protocol tree into which
1146 * we're putting this item.
1148 new_fi->length = n + length;
1152 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
1153 new_fi->hfinfo->type,
1154 ftype_name(new_fi->hfinfo->type));
1155 DISSECTOR_ASSERT_NOT_REACHED();
1159 /* Don't add new node to proto_tree until now so that any exceptions
1160 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
1161 pi = proto_tree_add_node(tree, new_fi);
1163 /* we did not raise an exception so we dont have to remember this
1164 * field_info struct any more.
1166 field_info_tmp=NULL;
1168 /* If the proto_tree wants to keep a record of this finfo
1169 * for quick lookup, then record it. */
1170 if (new_fi->hfinfo->ref_count) {
1172 hash = PTREE_DATA(tree)->interesting_hfids;
1173 ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
1175 g_ptr_array_add(ptrs, new_fi);
1182 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
1183 and returns proto_item* */
1185 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
1186 gboolean little_endian)
1189 header_field_info *hfinfo;
1194 offset = ptvc->offset;
1195 hfinfo = get_hfi_and_length(hfindex, ptvc->tvb, offset, &length,
1197 ptvc->offset += length;
1198 if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
1200 * The length of the rest of the item is in the first N
1201 * bytes of the item.
1203 n = get_uint_value(ptvc->tvb, offset, length, little_endian);
1206 if (ptvc->tree == NULL)
1209 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex);
1211 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset,
1216 return proto_tree_new_item(new_fi, ptvc->tree, hfindex, ptvc->tvb,
1217 offset, length, little_endian);
1220 /* Add an item to a proto_tree, using the text label registered to that item;
1221 the item is extracted from the tvbuff handed to it. */
1223 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1224 gint start, gint length, gboolean little_endian)
1231 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
1233 new_fi = alloc_field_info(tree, hfindex, tvb, start, &length);
1238 return proto_tree_new_item(new_fi, tree, hfindex, tvb, start,
1239 length, little_endian);
1243 proto_tree_add_item_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1244 gint start, gint length, gboolean little_endian)
1248 pi = proto_tree_add_item(tree, hfindex, tvb, start, length, little_endian);
1252 PROTO_ITEM_SET_HIDDEN(pi);
1258 /* Add a FT_NONE to a proto_tree */
1260 proto_tree_add_none_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1261 gint length, const char *format, ...)
1265 header_field_info *hfinfo;
1270 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1271 DISSECTOR_ASSERT(hfinfo->type == FT_NONE);
1273 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, NULL);
1275 va_start(ap, format);
1276 proto_tree_set_representation(pi, format, ap);
1279 /* no value to set for FT_NONE */
1283 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
1284 * offset, and returns proto_item* */
1286 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
1287 gboolean endianness)
1291 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
1292 length, endianness);
1297 /* Advance the ptvcursor's offset within its tvbuff without
1298 * adding anything to the proto_tree. */
1300 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
1302 ptvc->offset += length;
1307 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
1309 fvalue_set(&fi->value, tvb, TRUE);
1312 /* Add a FT_PROTOCOL to a proto_tree */
1314 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1315 gint length, const char *format, ...)
1319 header_field_info *hfinfo;
1325 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1326 DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
1328 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1330 va_start(ap, format);
1331 proto_tree_set_representation(pi, format, ap);
1335 proto_tree_set_protocol_tvb(new_fi, tvb);
1338 proto_tree_set_protocol_tvb(new_fi, NULL);
1344 /* Add a FT_BYTES to a proto_tree */
1346 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1347 gint length, const guint8 *start_ptr)
1351 header_field_info *hfinfo;
1356 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
1358 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1359 DISSECTOR_ASSERT(hfinfo->type == FT_BYTES);
1361 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1362 proto_tree_set_bytes(new_fi, start_ptr, length);
1368 proto_tree_add_bytes_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1369 gint length, const guint8 *start_ptr)
1373 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
1377 PROTO_ITEM_SET_HIDDEN(pi);
1383 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1384 gint start, gint length, const guint8 *start_ptr,
1385 const char *format, ...)
1390 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
1394 va_start(ap, format);
1395 proto_tree_set_representation_value(pi, format, ap);
1402 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1403 gint length, const guint8 *start_ptr, const char *format, ...)
1408 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
1412 va_start(ap, format);
1413 proto_tree_set_representation(pi, format, ap);
1420 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
1424 bytes = g_byte_array_new();
1426 g_byte_array_append(bytes, start_ptr, length);
1428 fvalue_set(&fi->value, bytes, TRUE);
1433 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
1435 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
1438 /* Add a FT_*TIME to a proto_tree */
1440 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1441 nstime_t *value_ptr)
1445 header_field_info *hfinfo;
1450 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
1452 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1453 DISSECTOR_ASSERT(hfinfo->type == FT_ABSOLUTE_TIME ||
1454 hfinfo->type == FT_RELATIVE_TIME);
1456 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1457 proto_tree_set_time(new_fi, value_ptr);
1463 proto_tree_add_time_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1464 nstime_t *value_ptr)
1468 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
1472 PROTO_ITEM_SET_HIDDEN(pi);
1478 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1479 gint start, gint length, nstime_t *value_ptr,
1480 const char *format, ...)
1485 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
1489 va_start(ap, format);
1490 proto_tree_set_representation_value(pi, format, ap);
1497 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1498 nstime_t *value_ptr, const char *format, ...)
1503 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
1507 va_start(ap, format);
1508 proto_tree_set_representation(pi, format, ap);
1514 /* Set the FT_*TIME value */
1516 proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
1518 DISSECTOR_ASSERT(value_ptr != NULL);
1519 fvalue_set(&fi->value, value_ptr, FALSE);
1522 /* Add a FT_IPXNET to a proto_tree */
1524 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1529 header_field_info *hfinfo;
1534 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
1536 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1537 DISSECTOR_ASSERT(hfinfo->type == FT_IPXNET);
1539 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1540 proto_tree_set_ipxnet(new_fi, value);
1546 proto_tree_add_ipxnet_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1551 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
1555 PROTO_ITEM_SET_HIDDEN(pi);
1561 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1562 gint start, gint length, guint32 value, const char *format, ...)
1567 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
1571 va_start(ap, format);
1572 proto_tree_set_representation_value(pi, format, ap);
1579 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1580 guint32 value, const char *format, ...)
1585 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
1589 va_start(ap, format);
1590 proto_tree_set_representation(pi, format, ap);
1596 /* Set the FT_IPXNET value */
1598 proto_tree_set_ipxnet(field_info *fi, guint32 value)
1600 fvalue_set_uinteger(&fi->value, value);
1603 /* Add a FT_IPv4 to a proto_tree */
1605 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1610 header_field_info *hfinfo;
1615 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
1617 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1618 DISSECTOR_ASSERT(hfinfo->type == FT_IPv4);
1620 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1621 proto_tree_set_ipv4(new_fi, value);
1627 proto_tree_add_ipv4_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1632 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
1636 PROTO_ITEM_SET_HIDDEN(pi);
1642 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1643 gint start, gint length, guint32 value, const char *format, ...)
1648 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
1652 va_start(ap, format);
1653 proto_tree_set_representation_value(pi, format, ap);
1660 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1661 guint32 value, const char *format, ...)
1666 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
1670 va_start(ap, format);
1671 proto_tree_set_representation(pi, format, ap);
1677 /* Set the FT_IPv4 value */
1679 proto_tree_set_ipv4(field_info *fi, guint32 value)
1681 fvalue_set_uinteger(&fi->value, value);
1684 /* Add a FT_IPv6 to a proto_tree */
1686 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1687 const guint8* value_ptr)
1691 header_field_info *hfinfo;
1696 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
1698 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1699 DISSECTOR_ASSERT(hfinfo->type == FT_IPv6);
1701 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1702 proto_tree_set_ipv6(new_fi, value_ptr);
1708 proto_tree_add_ipv6_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1709 const guint8* value_ptr)
1713 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1717 PROTO_ITEM_SET_HIDDEN(pi);
1723 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1724 gint start, gint length, const guint8* value_ptr,
1725 const char *format, ...)
1730 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1734 va_start(ap, format);
1735 proto_tree_set_representation_value(pi, format, ap);
1742 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1743 const guint8* value_ptr, const char *format, ...)
1748 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1752 va_start(ap, format);
1753 proto_tree_set_representation(pi, format, ap);
1759 /* Set the FT_IPv6 value */
1761 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
1763 DISSECTOR_ASSERT(value_ptr != NULL);
1764 fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
1768 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start)
1770 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, 16));
1773 /* Add a FT_GUID to a proto_tree */
1775 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1776 const e_guid_t *value_ptr)
1780 header_field_info *hfinfo;
1785 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
1787 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1788 DISSECTOR_ASSERT(hfinfo->type == FT_GUID);
1790 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1791 proto_tree_set_guid(new_fi, value_ptr);
1797 proto_tree_add_guid_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1798 const e_guid_t *value_ptr)
1802 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
1806 PROTO_ITEM_SET_HIDDEN(pi);
1812 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1813 gint start, gint length, const e_guid_t *value_ptr,
1814 const char *format, ...)
1819 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
1823 va_start(ap, format);
1824 proto_tree_set_representation_value(pi, format, ap);
1831 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1832 const e_guid_t *value_ptr, const char *format, ...)
1837 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
1841 va_start(ap, format);
1842 proto_tree_set_representation(pi, format, ap);
1848 /* Set the FT_GUID value */
1850 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
1852 DISSECTOR_ASSERT(value_ptr != NULL);
1853 fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
1857 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian)
1861 tvb_get_guid(tvb, start, &guid, little_endian);
1862 proto_tree_set_guid(fi, &guid);
1865 /* Add a FT_OID to a proto_tree */
1867 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1868 const guint8* value_ptr)
1872 header_field_info *hfinfo;
1877 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
1879 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1880 DISSECTOR_ASSERT(hfinfo->type == FT_OID);
1882 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1883 proto_tree_set_oid(new_fi, value_ptr, length);
1889 proto_tree_add_oid_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1890 const guint8* value_ptr)
1894 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
1898 PROTO_ITEM_SET_HIDDEN(pi);
1904 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1905 gint start, gint length, const guint8* value_ptr,
1906 const char *format, ...)
1911 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
1915 va_start(ap, format);
1916 proto_tree_set_representation_value(pi, format, ap);
1923 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1924 const guint8* value_ptr, const char *format, ...)
1929 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
1933 va_start(ap, format);
1934 proto_tree_set_representation(pi, format, ap);
1940 /* Set the FT_OID value */
1942 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
1946 DISSECTOR_ASSERT(value_ptr != NULL);
1948 bytes = g_byte_array_new();
1950 g_byte_array_append(bytes, value_ptr, length);
1952 fvalue_set(&fi->value, bytes, TRUE);
1956 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
1958 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
1962 proto_tree_set_uint64(field_info *fi, guint64 value)
1964 fvalue_set_integer64(&fi->value, value);
1968 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian)
1972 value = little_endian ? tvb_get_letoh64(tvb, start)
1973 : tvb_get_ntoh64(tvb, start);
1975 proto_tree_set_uint64(fi, value);
1978 /* Add a FT_STRING or FT_STRINGZ to a proto_tree. Creates own copy of string,
1979 * and frees it when the proto_tree is destroyed. */
1981 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1982 gint length, const char* value)
1986 header_field_info *hfinfo;
1991 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
1993 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1994 DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
1996 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1997 DISSECTOR_ASSERT(length >= 0);
1998 proto_tree_set_string(new_fi, value);
2004 proto_tree_add_string_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2005 gint length, const char* value)
2009 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
2013 PROTO_ITEM_SET_HIDDEN(pi);
2019 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2020 gint start, gint length, const char* value, const char *format,
2026 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
2030 va_start(ap, format);
2031 proto_tree_set_representation_value(pi, format, ap);
2038 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2039 gint length, const char* value, const char *format, ...)
2044 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
2048 va_start(ap, format);
2049 proto_tree_set_representation(pi, format, ap);
2055 /* Appends string data to a FT_STRING or FT_STRINGZ, allowing progressive
2056 * field info update instead of only updating the representation as does
2057 * proto_item_append_text()
2059 /* NOTE: this function will break with the TRY_TO_FAKE_THIS_ITEM()
2060 * speed optimization.
2061 * Currently only WSP use this function so it is not that bad but try to
2062 * avoid using this one if possible.
2063 * IF you must use this function you MUST also disable the
2064 * TRY_TO_FAKE_THIS_ITEM() optimization for your dissector/function
2065 * using proto_item_append_string().
2066 * Do that by faking that the tree is visible by setting :
2067 * PTREE_DATA(tree)->visible=1; (see packet-wsp.c)
2068 * BEFORE you create the item you are later going to use
2069 * proto_item_append_string() on.
2072 proto_item_append_string(proto_item *pi, const char *str)
2075 header_field_info *hfinfo;
2076 gchar *old_str, *new_str;
2083 fi = PITEM_FINFO(pi);
2084 hfinfo = fi->hfinfo;
2085 if (hfinfo->type == FT_PROTOCOL) {
2086 /* TRY_TO_FAKE_THIS_ITEM() speed optimization: silently skip */
2089 DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
2090 old_str = fvalue_get(&fi->value);
2091 new_str = ep_strdup_printf("%s%s", old_str, str);
2092 fvalue_set(&fi->value, new_str, FALSE);
2095 /* Set the FT_STRING value */
2097 proto_tree_set_string(field_info *fi, const char* value)
2100 fvalue_set(&fi->value, (gpointer) value, FALSE);
2102 fvalue_set(&fi->value, (gpointer) "[ Null ]", FALSE);
2106 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
2111 length = tvb_ensure_length_remaining(tvb, start);
2114 string = tvb_get_ephemeral_string(tvb, start, length);
2115 proto_tree_set_string(fi, string);
2118 /* Add a FT_ETHER to a proto_tree */
2120 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2121 const guint8* value)
2125 header_field_info *hfinfo;
2130 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
2132 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2133 DISSECTOR_ASSERT(hfinfo->type == FT_ETHER);
2135 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
2136 proto_tree_set_ether(new_fi, value);
2142 proto_tree_add_ether_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2143 const guint8* value)
2147 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
2151 PROTO_ITEM_SET_HIDDEN(pi);
2157 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2158 gint start, gint length, const guint8* value,
2159 const char *format, ...)
2164 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
2168 va_start(ap, format);
2169 proto_tree_set_representation_value(pi, format, ap);
2176 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2177 const guint8* value, const char *format, ...)
2182 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
2186 va_start(ap, format);
2187 proto_tree_set_representation(pi, format, ap);
2193 /* Set the FT_ETHER value */
2195 proto_tree_set_ether(field_info *fi, const guint8* value)
2197 fvalue_set(&fi->value, (gpointer) value, FALSE);
2201 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
2203 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, 6));
2206 /* Add a FT_BOOLEAN to a proto_tree */
2208 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2213 header_field_info *hfinfo;
2218 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
2220 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2221 DISSECTOR_ASSERT(hfinfo->type == FT_BOOLEAN);
2223 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
2224 proto_tree_set_boolean(new_fi, value);
2230 proto_tree_add_boolean_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2235 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
2239 PROTO_ITEM_SET_HIDDEN(pi);
2245 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
2246 tvbuff_t *tvb, gint start, gint length, guint32 value,
2247 const char *format, ...)
2252 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
2256 va_start(ap, format);
2257 proto_tree_set_representation_value(pi, format, ap);
2264 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2265 guint32 value, const char *format, ...)
2270 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
2274 va_start(ap, format);
2275 proto_tree_set_representation(pi, format, ap);
2281 /* Set the FT_BOOLEAN value */
2283 proto_tree_set_boolean(field_info *fi, guint32 value)
2285 proto_tree_set_uint(fi, value);
2288 /* Add a FT_FLOAT to a proto_tree */
2290 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2295 header_field_info *hfinfo;
2300 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
2302 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2303 DISSECTOR_ASSERT(hfinfo->type == FT_FLOAT);
2305 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
2306 proto_tree_set_float(new_fi, value);
2312 proto_tree_add_float_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2317 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
2321 PROTO_ITEM_SET_HIDDEN(pi);
2327 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2328 gint start, gint length, float value, const char *format, ...)
2333 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
2337 va_start(ap, format);
2338 proto_tree_set_representation_value(pi, format, ap);
2345 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2346 float value, const char *format, ...)
2351 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
2355 va_start(ap, format);
2356 proto_tree_set_representation(pi, format, ap);
2362 /* Set the FT_FLOAT value */
2364 proto_tree_set_float(field_info *fi, float value)
2366 fvalue_set_floating(&fi->value, value);
2369 /* Add a FT_DOUBLE to a proto_tree */
2371 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2376 header_field_info *hfinfo;
2381 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
2383 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2384 DISSECTOR_ASSERT(hfinfo->type == FT_DOUBLE);
2386 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
2387 proto_tree_set_double(new_fi, value);
2393 proto_tree_add_double_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2398 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
2402 PROTO_ITEM_SET_HIDDEN(pi);
2408 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2409 gint start, gint length, double value, const char *format, ...)
2414 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
2418 va_start(ap, format);
2419 proto_tree_set_representation_value(pi, format, ap);
2426 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2427 double value, const char *format, ...)
2432 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
2436 va_start(ap, format);
2437 proto_tree_set_representation(pi, format, ap);
2443 /* Set the FT_DOUBLE value */
2445 proto_tree_set_double(field_info *fi, double value)
2447 fvalue_set_floating(&fi->value, value);
2450 /* Add FT_UINT{8,16,24,32} to a proto_tree */
2452 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2455 proto_item *pi = NULL;
2457 header_field_info *hfinfo;
2462 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
2464 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2465 switch(hfinfo->type) {
2471 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length,
2473 proto_tree_set_uint(new_fi, value);
2477 DISSECTOR_ASSERT_NOT_REACHED();
2484 proto_tree_add_uint_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2489 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
2493 PROTO_ITEM_SET_HIDDEN(pi);
2499 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2500 gint start, gint length, guint32 value, const char *format, ...)
2505 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
2509 va_start(ap, format);
2510 proto_tree_set_representation_value(pi, format, ap);
2517 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2518 guint32 value, const char *format, ...)
2523 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
2527 va_start(ap, format);
2528 proto_tree_set_representation(pi, format, ap);
2534 /* Set the FT_UINT{8,16,24,32} value */
2536 proto_tree_set_uint(field_info *fi, guint32 value)
2538 header_field_info *hfinfo;
2541 hfinfo = fi->hfinfo;
2544 if (hfinfo->bitmask) {
2545 /* Mask out irrelevant portions */
2546 integer &= hfinfo->bitmask;
2549 if (hfinfo->bitshift > 0) {
2550 integer >>= hfinfo->bitshift;
2553 fvalue_set_uinteger(&fi->value, integer);
2556 /* Add FT_UINT64 to a proto_tree */
2558 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2561 proto_item *pi = NULL;
2563 header_field_info *hfinfo;
2568 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
2570 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2571 DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
2573 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
2574 proto_tree_set_uint64(new_fi, value);
2580 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2581 gint start, gint length, guint64 value, const char *format, ...)
2586 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
2590 va_start(ap, format);
2591 proto_tree_set_representation_value(pi, format, ap);
2598 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2599 guint64 value, const char *format, ...)
2604 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
2608 va_start(ap, format);
2609 proto_tree_set_representation(pi, format, ap);
2615 /* Add FT_INT{8,16,24,32} to a proto_tree */
2617 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2620 proto_item *pi = NULL;
2622 header_field_info *hfinfo;
2627 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
2629 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2630 switch(hfinfo->type) {
2635 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length,
2637 proto_tree_set_int(new_fi, value);
2641 DISSECTOR_ASSERT_NOT_REACHED();
2648 proto_tree_add_int_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2653 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
2657 PROTO_ITEM_SET_HIDDEN(pi);
2663 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2664 gint start, gint length, gint32 value, const char *format, ...)
2666 proto_item *pi = NULL;
2669 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
2673 va_start(ap, format);
2674 proto_tree_set_representation_value(pi, format, ap);
2681 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2682 gint32 value, const char *format, ...)
2684 proto_item *pi = NULL;
2687 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
2691 va_start(ap, format);
2692 proto_tree_set_representation(pi, format, ap);
2698 /* Set the FT_INT{8,16,24,32} value */
2700 proto_tree_set_int(field_info *fi, gint32 value)
2702 header_field_info *hfinfo;
2705 hfinfo = fi->hfinfo;
2706 integer = (guint32) value;
2708 if (hfinfo->bitmask) {
2709 /* Mask out irrelevant portions */
2710 integer &= hfinfo->bitmask;
2713 if (hfinfo->bitshift > 0) {
2714 integer >>= hfinfo->bitshift;
2717 fvalue_set_sinteger(&fi->value, integer);
2720 /* Add FT_INT64 to a proto_tree */
2722 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2725 proto_item *pi = NULL;
2727 header_field_info *hfinfo;
2732 TRY_TO_FAKE_THIS_ITEM(tree, hfindex);
2734 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2735 DISSECTOR_ASSERT(hfinfo->type == FT_INT64);
2737 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
2738 proto_tree_set_uint64(new_fi, (guint64)value);
2744 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2745 gint start, gint length, gint64 value, const char *format, ...)
2750 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
2754 va_start(ap, format);
2755 proto_tree_set_representation_value(pi, format, ap);
2762 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2763 gint64 value, const char *format, ...)
2768 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
2772 va_start(ap, format);
2773 proto_tree_set_representation(pi, format, ap);
2779 /* Throw an exception if we exceed this many tree items. */
2780 /* XXX - This should probably be a preference */
2781 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
2782 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
2784 proto_tree_add_node(proto_tree *tree, field_info *fi)
2786 proto_node *pnode, *tnode, *sibling;
2790 * Make sure "tree" is ready to have subtrees under it, by
2791 * checking whether it's been given an ett_ value.
2793 * "tnode->finfo" may be null; that's the case for the root
2794 * node of the protocol tree. That node is not displayed,
2795 * so it doesn't need an ett_ value to remember whether it
2800 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
2801 REPORT_DISSECTOR_BUG(ep_strdup_printf("\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
2802 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
2803 /* XXX - is it safe to continue here? */
2806 DISSECTOR_ASSERT(tfi == NULL ||
2807 (tfi->tree_type >= 0 && tfi->tree_type < num_tree_types));
2809 PTREE_DATA(tree)->count++;
2810 if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) {
2811 /* Let the exception handler add items to the tree */
2812 PTREE_DATA(tree)->count = 0;
2813 THROW_MESSAGE(DissectorError,
2814 ep_strdup_printf("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS));
2817 PROTO_NODE_NEW(pnode);
2818 pnode->parent = tnode;
2820 pnode->tree_data = PTREE_DATA(tree);
2822 if (tnode->last_child != NULL) {
2823 sibling = tnode->last_child;
2824 DISSECTOR_ASSERT(sibling->next == NULL);
2825 sibling->next = pnode;
2827 tnode->first_child = pnode;
2828 tnode->last_child = pnode;
2830 return (proto_item*)pnode;
2834 /* Generic way to allocate field_info and add to proto_tree.
2835 * Sets *pfi to address of newly-allocated field_info struct, if pfi is
2838 proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2839 gint *length, field_info **pfi)
2849 fi = alloc_field_info(tree, hfindex, tvb, start, length);
2850 pi = proto_tree_add_node(tree, fi);
2852 /* If the proto_tree wants to keep a record of this finfo
2853 * for quick lookup, then record it. */
2854 if (fi->hfinfo->ref_count) {
2856 hash = PTREE_DATA(tree)->interesting_hfids;
2857 ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
2859 g_ptr_array_add(ptrs, fi);
2863 /* Does the caller want to know the fi pointer? */
2872 static header_field_info *
2873 get_hfi_and_length(int hfindex, tvbuff_t *tvb, gint start, gint *length,
2876 header_field_info *hfinfo;
2877 gint length_remaining;
2880 * We only allow a null tvbuff if the item has a zero length,
2881 * i.e. if there's no data backing it.
2883 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
2885 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2888 * XXX - in some protocols, there are 32-bit unsigned length
2889 * fields, so lengths in protocol tree and tvbuff routines
2890 * should really be unsigned. We should have, for those
2891 * field types for which "to the end of the tvbuff" makes sense,
2892 * additional routines that take no length argument and
2893 * add fields that run to the end of the tvbuff.
2895 if (*length == -1) {
2897 * For FT_NONE, FT_PROTOCOL, FT_BYTES, and FT_STRING fields,
2898 * a length of -1 means "set the length to what remains in
2901 * The assumption is either that
2903 * 1) the length of the item can only be determined
2904 * by dissection (typically true of items with
2905 * subitems, which are probably FT_NONE or
2910 * 2) if the tvbuff is "short" (either due to a short
2911 * snapshot length or due to lack of reassembly of
2912 * fragments/segments/whatever), we want to display
2913 * what's available in the field (probably FT_BYTES
2914 * or FT_STRING) and then throw an exception later
2918 * 3) the field is defined to be "what's left in the
2921 * so we set the length to what remains in the tvbuff so
2922 * that, if we throw an exception while dissecting, it
2923 * has what is probably the right value.
2925 * For FT_STRINGZ, it means "the string is null-terminated,
2926 * not null-padded; set the length to the actual length
2927 * of the string", and if the tvbuff if short, we just
2928 * throw an exception.
2930 * It's not valid for any other type of field.
2932 switch (hfinfo->type) {
2936 * We allow this to be zero-length - for
2937 * example, an ONC RPC NULL procedure has
2938 * neither arguments nor reply, so the
2939 * payload for that protocol is empty.
2941 * However, if the length is negative, the
2942 * start offset is *past* the byte past the
2943 * end of the tvbuff, so we throw an
2946 *length = tvb_length_remaining(tvb, start);
2949 * Use "tvb_ensure_bytes_exist()"
2950 * to force the appropriate exception
2953 tvb_ensure_bytes_exist(tvb, start, 0);
2955 DISSECTOR_ASSERT(*length >= 0);
2961 *length = tvb_ensure_length_remaining(tvb, start);
2962 DISSECTOR_ASSERT(*length >= 0);
2967 * Leave the length as -1, so our caller knows
2973 DISSECTOR_ASSERT_NOT_REACHED();
2975 *item_length = *length;
2977 *item_length = *length;
2978 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
2980 * These types are for interior nodes of the
2981 * tree, and don't have data associated with
2982 * them; if the length is negative (XXX - see
2983 * above) or goes past the end of the tvbuff,
2984 * cut it short at the end of the tvbuff.
2985 * That way, if this field is selected in
2986 * Wireshark, we don't highlight stuff past
2987 * the end of the data.
2989 /* XXX - what to do, if we don't have a tvb? */
2991 length_remaining = tvb_length_remaining(tvb, start);
2992 if (*item_length < 0 ||
2993 (*item_length > 0 &&
2994 (length_remaining < *item_length)))
2995 *item_length = length_remaining;
2998 if (*item_length < 0) {
2999 THROW(ReportedBoundsError);
3007 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
3008 gint start, gint item_length)
3014 fi->hfinfo = hfinfo;
3016 fi->start+=(tvb)?TVB_RAW_OFFSET(tvb):0;
3017 fi->length = item_length;
3020 if (!PTREE_DATA(tree)->visible)
3021 FI_SET_FLAG(fi, FI_HIDDEN);
3022 fvalue_init(&fi->value, fi->hfinfo->type);
3025 /* add the data source tvbuff */
3026 fi->ds_tvb=tvb?TVB_GET_DS_TVB(tvb):NULL;
3032 alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3035 header_field_info *hfinfo;
3038 hfinfo = get_hfi_and_length(hfindex, tvb, start, length, &item_length);
3039 return new_field_info(tree, hfinfo, tvb, start, item_length);
3042 /* If the protocol tree is to be visible, set the representation of a
3043 proto_tree entry with the name of the field for the item and with
3044 the value formatted with the supplied printf-style format and
3047 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
3049 int ret; /*tmp return value */
3051 field_info *fi = PITEM_FINFO(pi);
3053 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
3054 ITEM_LABEL_NEW(fi->rep);
3056 ret = g_snprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
3057 "%s: ", fi->hfinfo->name);
3058 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH)) {
3059 /* That's all we can put in the representation. */
3060 fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
3064 ret = g_vsnprintf(fi->rep->representation + replen,
3065 ITEM_LABEL_LENGTH - replen, format, ap);
3066 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH - replen))
3067 fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
3071 /* If the protocol tree is to be visible, set the representation of a
3072 proto_tree entry with the representation formatted with the supplied
3073 printf-style format and argument list. */
3075 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
3077 int ret; /*tmp return value */
3078 field_info *fi = PITEM_FINFO(pi);
3080 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
3081 ITEM_LABEL_NEW(fi->rep);
3082 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH, format, ap);
3083 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3084 fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
3088 /* Set text of proto_item after having already been created. */
3090 proto_item_set_text(proto_item *pi, const char *format, ...)
3092 field_info *fi = NULL;
3099 fi = PITEM_FINFO(pi);
3102 ITEM_LABEL_FREE(fi->rep);
3105 va_start(ap, format);
3106 proto_tree_set_representation(pi, format, ap);
3110 /* Append to text of proto_item after having already been created. */
3112 proto_item_append_text(proto_item *pi, const char *format, ...)
3114 field_info *fi = NULL;
3117 int ret; /*tmp return value */
3123 fi = PITEM_FINFO(pi);
3128 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
3129 va_start(ap, format);
3132 * If we don't already have a representation,
3133 * generate the default representation.
3135 if (fi->rep == NULL) {
3136 ITEM_LABEL_NEW(fi->rep);
3137 proto_item_fill_label(fi, fi->rep->representation);
3140 curlen = strlen(fi->rep->representation);
3141 if (ITEM_LABEL_LENGTH > curlen) {
3142 ret = g_vsnprintf(fi->rep->representation + curlen,
3143 ITEM_LABEL_LENGTH - curlen, format, ap);
3144 if ((ret == -1) || (ret >= (int)(ITEM_LABEL_LENGTH - curlen)))
3145 fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
3152 proto_item_set_len(proto_item *pi, gint length)
3158 fi = PITEM_FINFO(pi);
3159 DISSECTOR_ASSERT(length >= 0);
3160 fi->length = length;
3164 * Sets the length of the item based on its start and on the specified
3165 * offset, which is the offset past the end of the item; as the start
3166 * in the item is relative to the beginning of the data source tvbuff,
3167 * we need to pass in a tvbuff - the end offset is relative to the beginning
3171 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
3177 fi = PITEM_FINFO(pi);
3178 end += TVB_RAW_OFFSET(tvb);
3179 DISSECTOR_ASSERT(end >= fi->start);
3180 fi->length = end - fi->start;
3184 proto_item_get_len(proto_item *pi)
3186 field_info *fi = PITEM_FINFO(pi);
3191 /** clear flags according to the mask and set new flag values */
3192 #define FI_REPLACE_FLAGS(fi, mask, flags_in) { \
3193 (fi->flags = (fi)->flags & ~(mask)); \
3194 (fi->flags = (fi)->flags | (flags_in)); \
3198 proto_item_set_expert_flags(proto_item *pi, int group, int severity)
3200 if(pi == NULL || pi->finfo == NULL)
3203 /* only change things if severity is worse or at least equal than before */
3204 if(severity >= FI_GET_FLAG(pi->finfo, PI_SEVERITY_MASK)) {
3205 FI_REPLACE_FLAGS(pi->finfo, PI_GROUP_MASK, group);
3206 FI_REPLACE_FLAGS(pi->finfo, PI_SEVERITY_MASK, severity);
3217 proto_tree_create_root(void)
3221 /* Initialize the proto_node */
3222 PROTO_NODE_NEW(pnode);
3223 pnode->parent = NULL;
3224 pnode->finfo = NULL;
3225 pnode->tree_data = g_new(tree_data_t, 1);
3227 /* Initialize the tree_data_t */
3228 pnode->tree_data->interesting_hfids =
3229 g_hash_table_new(g_direct_hash, g_direct_equal);
3231 /* Set the default to FALSE so it's easier to
3232 * find errors; if we expect to see the protocol tree
3233 * but for some reason the default 'visible' is not
3234 * changed, then we'll find out very quickly. */
3235 pnode->tree_data->visible = FALSE;
3237 /* Keep track of the number of children */
3238 pnode->tree_data->count = 0;
3240 return (proto_tree*) pnode;
3244 /* "prime" a proto_tree with a single hfid that a dfilter
3245 * is interested in. */
3247 proto_tree_prime_hfid(proto_tree *tree, gint hfid)
3249 header_field_info *hfinfo;
3251 g_hash_table_insert(PTREE_DATA(tree)->interesting_hfids,
3252 GINT_TO_POINTER(hfid), g_ptr_array_new());
3254 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
3255 /* this field is referenced by a filter so increase the refcount.
3256 also increase the refcount for the parent, i.e the protocol.
3258 hfinfo->ref_count++;
3259 /* only increase the refcount if there is a parent.
3260 if this is a protocol and not a field then parent will be -1
3261 and there is no parent to add any refcounting for.
3263 if (hfinfo->parent != -1) {
3264 header_field_info *parent_hfinfo;
3265 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
3266 parent_hfinfo->ref_count++;
3271 proto_item_add_subtree(proto_item *pi, gint idx) {
3277 fi = PITEM_FINFO(pi);
3278 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
3279 fi->tree_type = idx;
3281 return (proto_tree*) pi;
3285 proto_item_get_subtree(proto_item *pi) {
3290 fi = PITEM_FINFO(pi);
3291 if ( (!fi) || (fi->tree_type == -1) )
3293 return (proto_tree*) pi;
3297 proto_item_get_parent(proto_item *ti) {
3304 proto_item_get_parent_nth(proto_item *ti, int gen) {
3317 proto_tree_get_parent(proto_tree *tree) {
3320 return (proto_item*) tree;
3324 proto_tree_get_root(proto_tree *tree) {
3327 while (tree->parent) {
3328 tree = tree->parent;
3334 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item, proto_item *item_to_move)
3336 proto_item *curr_item;
3339 /*** cut item_to_move out ***/
3341 /* is item_to_move the first? */
3342 if(tree->first_child == item_to_move) {
3343 /* simply change first child to next */
3344 tree->first_child = item_to_move->next;
3346 /* find previous and change it's next */
3347 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
3348 if(curr_item->next == item_to_move) {
3353 DISSECTOR_ASSERT(curr_item);
3355 curr_item->next = item_to_move->next;
3357 /* fix last_child if required */
3358 if(tree->last_child == item_to_move) {
3359 tree->last_child = curr_item;
3363 /*** insert to_move after fixed ***/
3364 item_to_move->next = fixed_item->next;
3365 fixed_item->next = item_to_move;
3366 if(tree->last_child == fixed_item) {
3367 tree->last_child = item_to_move;
3373 proto_register_protocol(const char *name, const char *short_name, const char *filter_name)
3375 protocol_t *protocol;
3376 header_field_info *hfinfo;
3378 char *existing_name;
3382 gboolean found_invalid;
3385 * Make sure there's not already a protocol with any of those
3386 * names. Crash if there is, as that's an error in the code
3387 * or an inappropriate plugin.
3388 * This situation has to be fixed to not register more than one
3389 * protocol with the same name.
3391 * This is done by reducing the number of strcmp (and alike) calls as much as possible,
3392 * as this significally slows down startup time.
3394 * Drawback: As a hash value is used to reduce insert time,
3395 * this might lead to a hash collision.
3396 * However, as we have around 500+ protocols and we're using a 32 bit int this is very,
3400 key = g_malloc (sizeof(gint));
3401 *key = g_str_hash(name);
3402 existing_name = g_hash_table_lookup(proto_names, key);
3403 if (existing_name != NULL) {
3404 /* g_error will terminate the program */
3405 g_error("Duplicate protocol name \"%s\"!"
3406 " This might be caused by an inappropriate plugin or a development error.", name);
3408 g_hash_table_insert(proto_names, key, (gpointer)name);
3410 key = g_malloc (sizeof(gint));
3411 *key = g_str_hash(short_name);
3412 existing_name = g_hash_table_lookup(proto_short_names, key);
3413 if (existing_name != NULL) {
3414 g_error("Duplicate protocol short_name \"%s\"!"
3415 " This might be caused by an inappropriate plugin or a development error.", short_name);
3417 g_hash_table_insert(proto_short_names, key, (gpointer)short_name);
3419 found_invalid = FALSE;
3420 for (i = 0; i < strlen(filter_name); i++) {
3422 if (!(islower(c) || isdigit(c) || c == '-' || c == '_' || c == '.')) {
3423 found_invalid = TRUE;
3426 if (found_invalid) {
3427 g_error("Protocol filter name \"%s\" has one or more invalid characters."
3428 " Allowed are lower characters, digits, '-', '_' and '.'."
3429 " This might be caused by an inappropriate plugin or a development error.", filter_name);
3431 key = g_malloc (sizeof(gint));
3432 *key = g_str_hash(filter_name);
3433 existing_name = g_hash_table_lookup(proto_filter_names, key);
3434 if (existing_name != NULL) {
3435 g_error("Duplicate protocol filter_name \"%s\"!"
3436 " This might be caused by an inappropriate plugin or a development error.", filter_name);
3438 g_hash_table_insert(proto_filter_names, key, (gpointer)filter_name);
3440 /* Add this protocol to the list of known protocols; the list
3441 is sorted by protocol short name. */
3442 protocol = g_malloc(sizeof (protocol_t));
3443 protocol->name = name;
3444 protocol->short_name = short_name;
3445 protocol->filter_name = filter_name;
3446 protocol->fields = NULL;
3447 protocol->is_enabled = TRUE; /* protocol is enabled by default */
3448 protocol->can_toggle = TRUE;
3449 /* list will be sorted later by name, when all protocols completed registering */
3450 protocols = g_list_append(protocols, protocol);
3452 /* Here we do allocate a new header_field_info struct */
3453 hfinfo = g_mem_chunk_alloc(gmc_hfinfo);
3454 hfinfo->name = name;
3455 hfinfo->abbrev = filter_name;
3456 hfinfo->type = FT_PROTOCOL;
3457 hfinfo->strings = protocol;
3458 hfinfo->bitmask = 0;
3459 hfinfo->bitshift = 0;
3460 hfinfo->ref_count = 0;
3461 hfinfo->blurb = NULL;
3462 hfinfo->parent = -1; /* this field differentiates protos and fields */
3464 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
3465 protocol->proto_id = proto_id;
3470 * Routines to use to iterate over the protocols.
3471 * The argument passed to the iterator routines is an opaque cookie to
3472 * their callers; it's the GList pointer for the current element in
3474 * The ID of the protocol is returned, or -1 if there is no protocol.
3477 proto_get_first_protocol(void **cookie)
3479 protocol_t *protocol;
3481 if (protocols == NULL)
3483 *cookie = protocols;
3484 protocol = protocols->data;
3485 return protocol->proto_id;
3489 proto_get_next_protocol(void **cookie)
3491 GList *list_item = *cookie;
3492 protocol_t *protocol;
3494 list_item = g_list_next(list_item);
3495 if (list_item == NULL)
3497 *cookie = list_item;
3498 protocol = list_item->data;
3499 return protocol->proto_id;
3503 proto_get_first_protocol_field(int proto_id, void **cookie)
3505 protocol_t *protocol = find_protocol_by_id(proto_id);
3506 hf_register_info *ptr;
3508 if ((protocol == NULL) || (protocol->fields == NULL))
3511 *cookie = protocol->fields;
3512 ptr = protocol->fields->data;
3513 return &ptr->hfinfo;
3517 proto_get_next_protocol_field(void **cookie)
3519 GList *list_item = *cookie;
3520 hf_register_info *ptr;
3522 list_item = g_list_next(list_item);
3523 if (list_item == NULL)
3526 *cookie = list_item;
3527 ptr = list_item->data;
3528 return &ptr->hfinfo;
3532 find_protocol_by_id(int proto_id)
3534 header_field_info *hfinfo;
3539 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
3540 DISSECTOR_ASSERT(hfinfo->type==FT_PROTOCOL);
3541 return (protocol_t *)hfinfo->strings;
3544 static gint compare_filter_name(gconstpointer proto_arg,
3545 gconstpointer filter_name)
3547 const protocol_t *protocol = proto_arg;
3548 const gchar* f_name = filter_name;
3550 return (strcmp(protocol->filter_name, f_name));
3554 proto_get_id(protocol_t *protocol)
3556 return protocol->proto_id;
3559 int proto_get_id_by_filter_name(const gchar* filter_name)
3562 protocol_t *protocol;
3564 list_entry = g_list_find_custom(protocols, filter_name,
3565 compare_filter_name);
3566 if (list_entry == NULL)
3568 protocol = list_entry->data;
3569 return protocol->proto_id;
3573 proto_get_protocol_name(int proto_id)
3575 protocol_t *protocol;
3577 protocol = find_protocol_by_id(proto_id);
3578 return protocol->name;
3582 proto_get_protocol_short_name(protocol_t *protocol)
3584 if (protocol == NULL)
3586 return protocol->short_name;
3590 proto_get_protocol_filter_name(int proto_id)
3592 protocol_t *protocol;
3594 protocol = find_protocol_by_id(proto_id);
3595 return protocol->filter_name;
3599 proto_is_protocol_enabled(protocol_t *protocol)
3601 return protocol->is_enabled;
3605 proto_can_toggle_protocol(int proto_id)
3607 protocol_t *protocol;
3609 protocol = find_protocol_by_id(proto_id);
3610 return protocol->can_toggle;
3614 proto_set_decoding(int proto_id, gboolean enabled)
3616 protocol_t *protocol;
3618 protocol = find_protocol_by_id(proto_id);
3619 DISSECTOR_ASSERT(protocol->can_toggle);
3620 protocol->is_enabled = enabled;
3624 proto_set_cant_toggle(int proto_id)
3626 protocol_t *protocol;
3628 protocol = find_protocol_by_id(proto_id);
3629 protocol->can_toggle = FALSE;
3632 /* for use with static arrays only, since we don't allocate our own copies
3633 of the header_field_info struct contained within the hf_register_info struct */
3635 proto_register_field_array(int parent, hf_register_info *hf, int num_records)
3638 hf_register_info *ptr = hf;
3641 proto = find_protocol_by_id(parent);
3642 for (i = 0; i < num_records; i++, ptr++) {
3644 * Make sure we haven't registered this yet.
3645 * Most fields have variables associated with them
3646 * that are initialized to -1; some have array elements,
3647 * or possibly uninitialized variables, so we also allow
3648 * 0 (which is unlikely to be the field ID we get back
3649 * from "proto_register_field_init()").
3651 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
3653 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
3654 ptr->hfinfo.abbrev);
3658 if (proto != NULL) {
3659 if (proto->fields == NULL) {
3660 proto->fields = g_list_append(NULL, ptr);
3661 proto->last_field = proto->fields;
3664 g_list_append(proto->last_field, ptr)->next;
3667 field_id = proto_register_field_init(&ptr->hfinfo, parent);
3668 *ptr->p_id = field_id;
3673 proto_register_field_init(header_field_info *hfinfo, int parent)
3675 /* The field must have a name (with length > 0) */
3676 DISSECTOR_ASSERT(hfinfo->name && hfinfo->name[0]);
3678 /* fields with an empty string for an abbreviation aren't filterable */
3679 DISSECTOR_ASSERT(hfinfo->abbrev);
3681 /* These types of fields are allowed to have value_strings, true_false_strings or a protocol_t struct*/
3682 DISSECTOR_ASSERT((hfinfo->strings == NULL) || (
3683 (hfinfo->type == FT_UINT8) ||
3684 (hfinfo->type == FT_UINT16) ||
3685 (hfinfo->type == FT_UINT24) ||
3686 (hfinfo->type == FT_UINT32) ||
3687 (hfinfo->type == FT_INT8) ||
3688 (hfinfo->type == FT_INT16) ||
3689 (hfinfo->type == FT_INT24) ||
3690 (hfinfo->type == FT_INT32) ||
3691 (hfinfo->type == FT_BOOLEAN) ||
3692 (hfinfo->type == FT_PROTOCOL) ||
3693 (hfinfo->type == FT_FRAMENUM) ));
3695 switch (hfinfo->type) {
3705 /* Require integral types (other than frame number, which is
3706 always displayed in decimal) to have a number base */
3707 DISSECTOR_ASSERT(hfinfo->display != BASE_NONE);
3711 /* Don't allow bitfields or value strings for frame numbers */
3712 DISSECTOR_ASSERT(hfinfo->bitmask == 0);
3713 DISSECTOR_ASSERT(hfinfo->strings == NULL);
3719 /* if this is a bitfield, compute bitshift */
3720 if (hfinfo->bitmask) {
3721 while ((hfinfo->bitmask & (1 << hfinfo->bitshift)) == 0)
3725 hfinfo->parent = parent;
3726 hfinfo->same_name_next = NULL;
3727 hfinfo->same_name_prev = NULL;
3729 /* if we always add and never delete, then id == len - 1 is correct */
3730 if(gpa_hfinfo.len>=gpa_hfinfo.allocated_len){
3731 if(!gpa_hfinfo.hfi){
3732 gpa_hfinfo.allocated_len=1000;
3733 gpa_hfinfo.hfi=g_malloc(sizeof(header_field_info *)*1000);
3735 gpa_hfinfo.allocated_len+=1000;
3736 gpa_hfinfo.hfi=g_realloc(gpa_hfinfo.hfi, sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
3739 gpa_hfinfo.hfi[gpa_hfinfo.len]=hfinfo;
3741 hfinfo->id = gpa_hfinfo.len - 1;
3743 /* if we have real names, enter this field in the name tree */
3744 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
3746 header_field_info *same_name_hfinfo, *same_name_next_hfinfo;
3750 /* Check that the filter name (abbreviation) is legal;
3751 * it must contain only alphanumerics, '-', "_", and ".". */
3752 for (p = hfinfo->abbrev; (c = *p) != '\0'; p++) {
3753 if (!(isalnum(c) || c == '-' || c == '_' || c == '.')) {
3754 fprintf(stderr, "OOPS: '%c' in '%s'\n", c, hfinfo->abbrev);
3755 DISSECTOR_ASSERT(isalnum(c) || c == '-' || c == '_' ||
3759 /* We allow multiple hfinfo's to be registered under the same
3760 * abbreviation. This was done for X.25, as, depending
3761 * on whether it's modulo-8 or modulo-128 operation,
3762 * some bitfield fields may be in different bits of
3763 * a byte, and we want to be able to refer to that field
3764 * with one name regardless of whether the packets
3765 * are modulo-8 or modulo-128 packets. */
3766 same_name_hfinfo = g_tree_lookup(gpa_name_tree, hfinfo->abbrev);
3767 if (same_name_hfinfo) {
3768 /* There's already a field with this name.
3769 * Put it after that field in the list of
3770 * fields with this name, then allow the code
3771 * after this if{} block to replace the old
3772 * hfinfo with the new hfinfo in the GTree. Thus,
3773 * we end up with a linked-list of same-named hfinfo's,
3774 * with the root of the list being the hfinfo in the GTree */
3775 same_name_next_hfinfo =
3776 same_name_hfinfo->same_name_next;
3778 hfinfo->same_name_next = same_name_next_hfinfo;
3779 if (same_name_next_hfinfo)
3780 same_name_next_hfinfo->same_name_prev = hfinfo;
3782 same_name_hfinfo->same_name_next = hfinfo;
3783 hfinfo->same_name_prev = same_name_hfinfo;
3785 g_tree_insert(gpa_name_tree, (gpointer) (hfinfo->abbrev), hfinfo);
3792 proto_register_subtree_array(gint *const *indices, int num_indices)
3795 gint *const *ptr = indices;
3798 * If we've already allocated the array of tree types, expand
3799 * it; this lets plugins such as mate add tree types after
3800 * the initial startup. (If we haven't already allocated it,
3801 * we don't allocate it; on the first pass, we just assign
3802 * ett values and keep track of how many we've assigned, and
3803 * when we're finished registering all dissectors we allocate
3804 * the array, so that we do only one allocation rather than
3805 * wasting CPU time and memory by growing the array for each
3806 * dissector that registers ett values.)
3808 if (tree_is_expanded != NULL) {
3810 g_realloc(tree_is_expanded,
3811 (num_tree_types+num_indices)*sizeof (gboolean));
3812 memset(tree_is_expanded + num_tree_types, 0,
3813 num_indices*sizeof (gboolean));
3817 * Assign "num_indices" subtree numbers starting at "num_tree_types",
3818 * returning the indices through the pointers in the array whose
3819 * first element is pointed to by "indices", and update
3820 * "num_tree_types" appropriately.
3822 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++)
3823 **ptr = num_tree_types;
3827 proto_item_fill_label(field_info *fi, gchar *label_str)
3829 header_field_info *hfinfo = fi->hfinfo;
3835 guint32 n_addr; /* network-order IPv4 address */
3837 int ret; /*tmp return value */
3839 switch(hfinfo->type) {
3842 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3843 "%s", hfinfo->name);
3844 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3845 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3849 fill_label_boolean(fi, label_str);
3854 bytes = fvalue_get(&fi->value);
3856 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3857 "%s: %s", hfinfo->name,
3858 bytes_to_str(bytes, fvalue_length(&fi->value)));
3859 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3860 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3863 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3864 "%s: <MISSING>", hfinfo->name);
3865 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3866 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3870 /* Four types of integers to take care of:
3871 * Bitfield, with val_string
3872 * Bitfield, w/o val_string
3873 * Non-bitfield, with val_string
3874 * Non-bitfield, w/o val_string
3881 if (hfinfo->bitmask) {
3882 if (hfinfo->strings) {
3883 fill_label_enumerated_bitfield(fi, label_str);
3886 fill_label_numeric_bitfield(fi, label_str);
3890 if (hfinfo->strings) {
3891 fill_label_enumerated_uint(fi, label_str);
3894 fill_label_uint(fi, label_str);
3900 fill_label_uint64(fi, label_str);
3907 DISSECTOR_ASSERT(!hfinfo->bitmask);
3908 if (hfinfo->strings) {
3909 fill_label_enumerated_int(fi, label_str);
3912 fill_label_int(fi, label_str);
3917 fill_label_int64(fi, label_str);
3921 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3922 "%s: %." STRINGIFY(FLT_DIG) "f",
3923 hfinfo->name, fvalue_get_floating(&fi->value));
3924 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3925 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3929 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3930 "%s: %." STRINGIFY(DBL_DIG) "g",
3931 hfinfo->name, fvalue_get_floating(&fi->value));
3932 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3933 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3936 case FT_ABSOLUTE_TIME:
3937 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3938 "%s: %s", hfinfo->name,
3939 abs_time_to_str(fvalue_get(&fi->value)));
3940 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3941 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3944 case FT_RELATIVE_TIME:
3945 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3946 "%s: %s seconds", hfinfo->name,
3947 rel_time_to_secs_str(fvalue_get(&fi->value)));
3948 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3949 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3953 integer = fvalue_get_uinteger(&fi->value);
3954 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3955 "%s: %s (0x%08X)", hfinfo->name,
3956 get_ipxnet_name(integer), integer);
3957 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3958 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3962 bytes = fvalue_get(&fi->value);
3963 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3964 "%s: %s (%s)", hfinfo->name,
3965 get_ether_name(bytes),
3966 ether_to_str(bytes));
3967 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3968 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3972 ipv4 = fvalue_get(&fi->value);
3973 n_addr = ipv4_get_net_order_addr(ipv4);
3974 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3975 "%s: %s (%s)", hfinfo->name,
3976 get_hostname(n_addr),
3977 ip_to_str((guint8*)&n_addr));
3978 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3979 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3983 bytes = fvalue_get(&fi->value);
3984 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3985 "%s: %s (%s)", hfinfo->name,
3986 get_hostname6((struct e_in6_addr *)bytes),
3987 ip6_to_str((struct e_in6_addr*)bytes));
3988 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3989 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3993 guid = fvalue_get(&fi->value);
3994 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
3995 "%s: %s", hfinfo->name,
3997 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3998 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4002 bytes = fvalue_get(&fi->value);
4003 name = (oid_resolv_enabled()) ? get_oid_name(bytes, fvalue_length(&fi->value)) : NULL;
4005 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4006 "%s: %s (%s)", hfinfo->name,
4007 oid_to_str(bytes, fvalue_length(&fi->value)), name);
4009 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4010 "%s: %s", hfinfo->name,
4011 oid_to_str(bytes, fvalue_length(&fi->value)));
4013 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
4014 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4019 case FT_UINT_STRING:
4020 bytes = fvalue_get(&fi->value);
4021 if(strlen(bytes) > ITEM_LABEL_LENGTH) {
4022 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4023 "%s [truncated]: %s", hfinfo->name,
4024 format_text(bytes, strlen(bytes)));
4026 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4027 "%s: %s", hfinfo->name,
4028 format_text(bytes, strlen(bytes)));
4030 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
4031 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4035 g_error("hfinfo->type %d (%s) not handled\n",
4037 ftype_name(hfinfo->type));
4038 DISSECTOR_ASSERT_NOT_REACHED();
4044 fill_label_boolean(field_info *fi, gchar *label_str)
4046 char *p = label_str;
4047 int bitfield_byte_length = 0, bitwidth;
4048 guint32 unshifted_value;
4050 int ret; /*tmp return value */
4052 header_field_info *hfinfo = fi->hfinfo;
4053 const true_false_string *tfstring = &tfs_true_false;
4055 if (hfinfo->strings) {
4056 tfstring = (const struct true_false_string*) hfinfo->strings;
4059 value = fvalue_get_uinteger(&fi->value);
4060 if (hfinfo->bitmask) {
4061 /* Figure out the bit width */
4062 bitwidth = hfinfo_bitwidth(hfinfo);
4065 unshifted_value = value;
4066 if (hfinfo->bitshift > 0) {
4067 unshifted_value <<= hfinfo->bitshift;
4070 /* Create the bitfield first */
4071 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
4072 bitfield_byte_length = p - label_str;
4075 /* Fill in the textual info */
4076 ret = g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
4077 "%s: %s", hfinfo->name,
4078 value ? tfstring->true_string : tfstring->false_string);
4079 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
4080 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4084 /* Fills data for bitfield ints with val_strings */
4086 fill_label_enumerated_bitfield(field_info *fi, gchar *label_str)
4088 const char *format = NULL;
4090 int bitfield_byte_length, bitwidth;
4091 guint32 unshifted_value;
4093 int ret; /*tmp return value */
4095 header_field_info *hfinfo = fi->hfinfo;
4097 /* Figure out the bit width */
4098 bitwidth = hfinfo_bitwidth(hfinfo);
4100 /* Pick the proper format string */
4101 format = hfinfo_uint_vals_format(hfinfo);
4104 unshifted_value = fvalue_get_uinteger(&fi->value);
4105 value = unshifted_value;
4106 if (hfinfo->bitshift > 0) {
4107 unshifted_value <<= hfinfo->bitshift;
4110 /* Create the bitfield first */
4111 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
4112 bitfield_byte_length = p - label_str;
4114 /* Fill in the textual info using stored (shifted) value */
4115 ret = g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
4116 format, hfinfo->name,
4117 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
4118 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
4119 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4123 fill_label_numeric_bitfield(field_info *fi, gchar *label_str)
4125 const char *format = NULL;
4127 int bitfield_byte_length, bitwidth;
4128 guint32 unshifted_value;
4130 int ret; /*tmp return value */
4132 header_field_info *hfinfo = fi->hfinfo;
4134 /* Figure out the bit width */
4135 bitwidth = hfinfo_bitwidth(hfinfo);
4137 /* Pick the proper format string */
4138 format = hfinfo_uint_format(hfinfo);
4141 unshifted_value = fvalue_get_uinteger(&fi->value);
4142 value = unshifted_value;
4143 if (hfinfo->bitshift > 0) {
4144 unshifted_value <<= hfinfo->bitshift;
4147 /* Create the bitfield using */
4148 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
4149 bitfield_byte_length = p - label_str;
4151 /* Fill in the textual info using stored (shifted) value */
4152 if (IS_BASE_DUAL(hfinfo->display)) {
4153 ret = g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
4154 format, hfinfo->name, value, value);
4156 ret = g_snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
4157 format, hfinfo->name, value);
4159 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
4160 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4165 fill_label_enumerated_uint(field_info *fi, gchar *label_str)
4167 const char *format = NULL;
4168 header_field_info *hfinfo = fi->hfinfo;
4170 int ret; /*tmp return value */
4172 /* Pick the proper format string */
4173 format = hfinfo_uint_vals_format(hfinfo);
4175 value = fvalue_get_uinteger(&fi->value);
4177 /* Fill in the textual info */
4178 if (hfinfo->display & BASE_RANGE_STRING) {
4179 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4180 format, hfinfo->name,
4181 rval_to_str(value, hfinfo->strings, "Unknown"), value);
4183 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4184 format, hfinfo->name,
4185 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
4187 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
4188 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4192 fill_label_uint(field_info *fi, gchar *label_str)
4194 const char *format = NULL;
4195 header_field_info *hfinfo = fi->hfinfo;
4197 int ret; /*tmp return value */
4199 /* Pick the proper format string */
4200 format = hfinfo_uint_format(hfinfo);
4201 value = fvalue_get_uinteger(&fi->value);
4203 /* Fill in the textual info */
4204 if (IS_BASE_DUAL(hfinfo->display)) {
4205 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4206 format, hfinfo->name, value, value);
4208 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4209 format, hfinfo->name, value);
4211 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
4212 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4216 fill_label_uint64(field_info *fi, gchar *label_str)
4218 const char *format = NULL;
4219 header_field_info *hfinfo = fi->hfinfo;
4221 int ret; /*tmp return value */
4223 /* Pick the proper format string */
4224 format = hfinfo_uint64_format(hfinfo);
4225 value = fvalue_get_integer64(&fi->value);
4227 /* Fill in the textual info */
4228 if (IS_BASE_DUAL(hfinfo->display)) {
4229 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4230 format, hfinfo->name, value, value);
4232 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4233 format, hfinfo->name, value);
4235 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
4236 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4240 fill_label_enumerated_int(field_info *fi, gchar *label_str)
4242 const char *format = NULL;
4243 header_field_info *hfinfo = fi->hfinfo;
4245 int ret; /*tmp return value */
4247 /* Pick the proper format string */
4248 format = hfinfo_int_vals_format(hfinfo);
4249 value = fvalue_get_sinteger(&fi->value);
4251 /* Fill in the textual info */
4252 if (hfinfo->display & BASE_RANGE_STRING) {
4253 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4254 format, hfinfo->name,
4255 rval_to_str(value, hfinfo->strings, "Unknown"), value);
4257 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4258 format, hfinfo->name,
4259 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
4261 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
4262 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4266 fill_label_int(field_info *fi, gchar *label_str)
4268 const char *format = NULL;
4269 header_field_info *hfinfo = fi->hfinfo;
4271 int ret; /*tmp return value */
4273 /* Pick the proper format string */
4274 format = hfinfo_int_format(hfinfo);
4275 value = fvalue_get_sinteger(&fi->value);
4277 /* Fill in the textual info */
4278 if (IS_BASE_DUAL(hfinfo->display)) {
4279 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4280 format, hfinfo->name, value, value);
4282 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4283 format, hfinfo->name, value);
4285 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
4286 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4290 fill_label_int64(field_info *fi, gchar *label_str)
4292 const char *format = NULL;
4293 header_field_info *hfinfo = fi->hfinfo;
4295 int ret; /*tmp return value */
4297 /* Pick the proper format string */
4298 format = hfinfo_int64_format(hfinfo);
4299 value = fvalue_get_integer64(&fi->value);
4301 /* Fill in the textual info */
4302 if (IS_BASE_DUAL(hfinfo->display)) {
4303 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4304 format, hfinfo->name, value, value);
4306 ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
4307 format, hfinfo->name, value);
4309 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
4310 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
4314 hfinfo_bitwidth(header_field_info *hfinfo)
4318 if (!hfinfo->bitmask) {
4322 switch(hfinfo->type) {
4340 bitwidth = hfinfo->display; /* hacky? :) */
4343 DISSECTOR_ASSERT_NOT_REACHED();
4350 hfinfo_uint_vals_format(header_field_info *hfinfo)
4352 const char *format = NULL;
4354 /* bit operation to reset the potential BASE_RANGE_STRING (or others in
4356 switch(hfinfo->display & BASE_STRUCTURE_RESET) {
4359 format = "%s: %s (%u)";
4361 case BASE_OCT: /* I'm lazy */
4362 format = "%s: %s (%o)";
4366 switch(hfinfo->type) {
4368 format = "%s: %s (0x%02x)";
4371 format = "%s: %s (0x%04x)";
4374 format = "%s: %s (0x%06x)";
4377 format = "%s: %s (0x%08x)";
4380 DISSECTOR_ASSERT_NOT_REACHED();
4385 DISSECTOR_ASSERT_NOT_REACHED();
4392 hfinfo_uint_format(header_field_info *hfinfo)
4394 const char *format = NULL;
4396 /* Pick the proper format string */
4397 if (hfinfo->type == FT_FRAMENUM) {
4399 * Frame numbers are always displayed in decimal.
4403 switch(hfinfo->display) {
4408 switch(hfinfo->type) {
4410 format = "%s: %u (0x%02x)";
4413 format = "%s: %u (0x%04x)";
4416 format = "%s: %u (0x%06x)";
4419 format = "%s: %u (0x%08x)";
4422 DISSECTOR_ASSERT_NOT_REACHED();
4426 case BASE_OCT: /* I'm lazy */
4430 switch(hfinfo->type) {
4432 format = "%s: 0x%02x";
4435 format = "%s: 0x%04x";
4438 format = "%s: 0x%06x";
4441 format = "%s: 0x%08x";
4444 DISSECTOR_ASSERT_NOT_REACHED();
4449 switch(hfinfo->type) {
4451 format = "%s: 0x%02x (%u)";
4454 format = "%s: 0x%04x (%u)";
4457 format = "%s: 0x%06x (%u)";
4460 format = "%s: 0x%08x (%u)";
4463 DISSECTOR_ASSERT_NOT_REACHED();
4468 DISSECTOR_ASSERT_NOT_REACHED();
4476 hfinfo_int_vals_format(header_field_info *hfinfo)
4478 const char *format = NULL;
4480 /* bit operation to reset the potential BASE_RANGE_STRING (or others in
4482 switch(hfinfo->display & BASE_STRUCTURE_RESET) {
4485 format = "%s: %s (%d)";
4487 case BASE_OCT: /* I'm lazy */
4488 format = "%s: %s (%o)";
4492 switch(hfinfo->type) {
4494 format = "%s: %s (0x%02x)";
4497 format = "%s: %s (0x%04x)";
4500 format = "%s: %s (0x%06x)";
4503 format = "%s: %s (0x%08x)";
4506 DISSECTOR_ASSERT_NOT_REACHED();
4511 DISSECTOR_ASSERT_NOT_REACHED();
4518 hfinfo_uint64_format(header_field_info *hfinfo)
4520 const char *format = NULL;
4522 /* Pick the proper format string */
4523 switch(hfinfo->display) {
4525 format = "%s: %" PRIu64;
4528 format = "%s: %" PRIu64 " (%" PRIx64 ")";
4530 case BASE_OCT: /* I'm lazy */
4531 format = "%s: %" PRIo64;
4534 format = "%s: 0x%016" PRIx64;
4537 format = "%s: 0x%016" PRIx64 " (%" PRIu64 ")";
4540 DISSECTOR_ASSERT_NOT_REACHED();
4547 hfinfo_int_format(header_field_info *hfinfo)
4549 const char *format = NULL;
4551 /* Pick the proper format string */
4552 switch(hfinfo->display) {
4557 switch(hfinfo->type) {
4559 format = "%s: %d (0x%02x)";
4562 format = "%s: %d (0x%04x)";
4565 format = "%s: %d (0x%06x)";
4568 format = "%s: %d (0x%08x)";
4571 DISSECTOR_ASSERT_NOT_REACHED();
4574 case BASE_OCT: /* I'm lazy */
4578 switch(hfinfo->type) {
4580 format = "%s: 0x%02x";
4583 format = "%s: 0x%04x";
4586 format = "%s: 0x%06x";
4589 format = "%s: 0x%08x";
4592 DISSECTOR_ASSERT_NOT_REACHED();
4597 switch(hfinfo->type) {
4599 format = "%s: 0x%02x (%d)";
4602 format = "%s: 0x%04x (%d)";
4605 format = "%s: 0x%06x (%d)";
4608 format = "%s: 0x%08x (%d)";
4611 DISSECTOR_ASSERT_NOT_REACHED();
4616 DISSECTOR_ASSERT_NOT_REACHED();
4623 hfinfo_int64_format(header_field_info *hfinfo)
4625 const char *format = NULL;
4627 /* Pick the proper format string */
4628 switch(hfinfo->display) {
4630 format = "%s: %" PRId64;
4633 format = "%s: %" PRId64 " (%" PRIx64 ")";
4635 case BASE_OCT: /* I'm lazy */
4636 format = "%s: %" PRIo64;
4639 format = "%s: 0x%016" PRIx64;
4642 format = "%s: 0x%016" PRIx64 " (%" PRId64 ")";
4645 DISSECTOR_ASSERT_NOT_REACHED();
4654 proto_registrar_n(void)
4656 return gpa_hfinfo.len;
4660 proto_registrar_get_name(int n)
4662 header_field_info *hfinfo;
4664 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
4665 return hfinfo->name;
4669 proto_registrar_get_abbrev(int n)
4671 header_field_info *hfinfo;
4673 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
4674 return hfinfo->abbrev;
4678 proto_registrar_get_ftype(int n)
4680 header_field_info *hfinfo;
4682 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
4683 return hfinfo->type;
4687 proto_registrar_get_parent(int n)
4689 header_field_info *hfinfo;
4691 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
4692 return hfinfo->parent;
4696 proto_registrar_is_protocol(int n)
4698 header_field_info *hfinfo;
4700 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
4701 return (hfinfo->parent == -1 ? TRUE : FALSE);
4704 /* Returns length of field in packet (not necessarily the length
4705 * in our internal representation, as in the case of IPv4).
4706 * 0 means undeterminable at time of registration
4707 * -1 means the field is not registered. */
4709 proto_registrar_get_length(int n)
4711 header_field_info *hfinfo;
4713 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
4714 return ftype_length(hfinfo->type);
4719 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
4720 * it exists anywhere, or FALSE if it exists nowhere. */
4722 proto_check_for_protocol_or_field(proto_tree* tree, int id)
4724 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
4729 else if (g_ptr_array_len(ptrs) > 0) {
4737 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
4738 * This only works if the hfindex was "primed" before the dissection
4739 * took place, as we just pass back the already-created GPtrArray*.
4740 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
4743 proto_get_finfo_ptr_array(proto_tree *tree, int id)
4745 return g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
4746 GINT_TO_POINTER(id));
4750 /* Helper struct for proto_find_info() and proto_all_finfos() */
4756 /* Helper function for proto_find_info() */
4758 find_finfo(proto_node *node, gpointer data)
4760 field_info *fi = PITEM_FINFO(node);
4761 if (fi && fi->hfinfo) {
4762 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
4763 g_ptr_array_add(((ffdata_t*)data)->array, fi);
4767 /* Don't stop traversing. */
4771 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
4772 * This works on any proto_tree, primed or unprimed, but actually searches
4773 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
4774 * The caller does need to free the returned GPtrArray with
4775 * g_ptr_array_free(<array>, FALSE).
4778 proto_find_finfo(proto_tree *tree, int id)
4782 ffdata.array = g_ptr_array_new();
4785 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
4787 return ffdata.array;
4790 /* Helper function for proto_all_finfos() */
4792 every_finfo(proto_node *node, gpointer data)
4794 field_info *fi = PITEM_FINFO(node);
4795 if (fi && fi->hfinfo) {
4796 g_ptr_array_add(((ffdata_t*)data)->array, fi);
4799 /* Don't stop traversing. */
4803 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
4805 proto_all_finfos(proto_tree *tree)
4809 ffdata.array = g_ptr_array_new();
4812 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
4814 return ffdata.array;
4825 check_for_offset(proto_node *node, gpointer data)
4827 field_info *fi = PITEM_FINFO(node);
4828 offset_search_t *offsearch = data;
4830 /* !fi == the top most container node which holds nothing */
4831 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
4832 if (offsearch->offset >= (guint) fi->start &&
4833 offsearch->offset < (guint) (fi->start + fi->length)) {
4835 offsearch->finfo = fi;
4836 return FALSE; /* keep traversing */
4839 return FALSE; /* keep traversing */
4842 /* Search a proto_tree backwards (from leaves to root) looking for the field
4843 * whose start/length occupies 'offset' */
4844 /* XXX - I couldn't find an easy way to search backwards, so I search
4845 * forwards, w/o stopping. Therefore, the last finfo I find will the be
4846 * the one I want to return to the user. This algorithm is inefficient
4847 * and could be re-done, but I'd have to handle all the children and
4848 * siblings of each node myself. When I have more time I'll do that.
4851 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
4853 offset_search_t offsearch;
4855 offsearch.offset = offset;
4856 offsearch.finfo = NULL;
4857 offsearch.tvb = tvb;
4859 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
4861 return offsearch.finfo;
4864 /* Dumps the protocols in the registration database to stdout. An independent
4865 * program can take this output and format it into nice tables or HTML or
4868 * There is one record per line. The fields are tab-delimited.
4870 * Field 1 = protocol name
4871 * Field 2 = protocol short name
4872 * Field 3 = protocol filter name
4875 proto_registrar_dump_protocols(void)
4877 protocol_t *protocol;
4879 void *cookie = NULL;
4881 for (i = proto_get_first_protocol(&cookie); i != -1;
4882 i = proto_get_next_protocol(&cookie)) {
4883 protocol = find_protocol_by_id(i);
4884 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
4885 protocol->filter_name);
4889 /* Dumps the value_string and true/false strings for fields that have
4890 * them. There is one record per line. Fields are tab-delimited.
4891 * There are two types of records, Value String records and True/False
4892 * String records. The first field, 'V' or 'T', indicates the type
4898 * Field 2 = field abbreviation to which this value string corresponds
4899 * Field 3 = Integer value
4902 * True/False Strings
4903 * ------------------
4905 * Field 2 = field abbreviation to which this true/false string corresponds
4906 * Field 3 = True String
4907 * Field 4 = False String
4910 proto_registrar_dump_values(void)
4912 header_field_info *hfinfo, *parent_hfinfo;
4914 const value_string *vals;
4915 const true_false_string *tfs;
4917 len = gpa_hfinfo.len;
4918 for (i = 0; i < len ; i++) {
4919 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
4921 if (hfinfo->id == hf_text_only) {
4925 /* ignore protocols */
4926 if (proto_registrar_is_protocol(i)) {
4929 /* process header fields */
4932 * If this field isn't at the head of the list of
4933 * fields with this name, skip this field - all
4934 * fields with the same name are really just versions
4935 * of the same field stored in different bits, and
4936 * should have the same type/radix/value list, and
4937 * just differ in their bit masks. (If a field isn't
4938 * a bitfield, but can be, say, 1 or 2 bytes long,
4939 * it can just be made FT_UINT16, meaning the
4940 * *maximum* length is 2 bytes, and be used
4943 if (hfinfo->same_name_prev != NULL)
4946 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
4951 if (hfinfo->type == FT_UINT8 ||
4952 hfinfo->type == FT_UINT16 ||
4953 hfinfo->type == FT_UINT24 ||
4954 hfinfo->type == FT_UINT32 ||
4955 hfinfo->type == FT_UINT64 ||
4956 hfinfo->type == FT_INT8 ||
4957 hfinfo->type == FT_INT16 ||
4958 hfinfo->type == FT_INT24 ||
4959 hfinfo->type == FT_INT32 ||
4960 hfinfo->type == FT_INT64) {
4962 vals = hfinfo->strings;
4964 else if (hfinfo->type == FT_BOOLEAN) {
4965 tfs = hfinfo->strings;
4968 /* Print value strings? */
4971 while (vals[vi].strptr) {
4972 /* Print in the proper base */
4973 if (hfinfo->display == BASE_HEX) {
4974 printf("V\t%s\t0x%x\t%s\n",
4980 printf("V\t%s\t%u\t%s\n",
4989 /* Print true/false strings? */
4991 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
4992 tfs->true_string, tfs->false_string);
4998 /* Dumps the contents of the registration database to stdout. An indepedent
4999 * program can take this output and format it into nice tables or HTML or
5002 * There is one record per line. Each record is either a protocol or a header
5003 * field, differentiated by the first field. The fields are tab-delimited.
5008 * Field 2 = descriptive protocol name
5009 * Field 3 = protocol abbreviation
5015 * Field 2 = descriptive field name
5016 * Field 3 = field abbreviation
5017 * Field 4 = type ( textual representation of the the ftenum type )
5018 * Field 5 = parent protocol abbreviation
5019 * Field 6 = blurb describing field
5023 * Field 2 = descriptive field name
5024 * Field 3 = field abbreviation
5025 * Field 4 = type ( textual representation of the the ftenum type )
5026 * Field 5 = parent protocol abbreviation
5027 * Field 6 = blurb describing field
5028 * Field 7 = base for display (for integer types)
5029 * Field 8 = blurb describing field (yes, apparently we repeated this accidentally)
5033 * Field 2 = descriptive field name
5034 * Field 3 = field abbreviation
5035 * Field 4 = type ( textual representation of the the ftenum type )
5036 * Field 5 = parent protocol abbreviation
5037 * Field 6 = blurb describing field
5038 * Field 7 = base for display (for integer types)
5042 proto_registrar_dump_fields(int format)
5044 header_field_info *hfinfo, *parent_hfinfo;
5046 const char *enum_name;
5047 const char *base_name;
5050 len = gpa_hfinfo.len;
5051 for (i = 0; i < len ; i++) {
5052 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
5055 * Skip the pseudo-field for "proto_tree_add_text()" since
5056 * we don't want it in the list of filterable fields.
5058 if (hfinfo->id == hf_text_only)
5061 /* format for protocols */
5062 if (proto_registrar_is_protocol(i)) {
5063 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
5065 /* format for header fields */
5068 * If this field isn't at the head of the list of
5069 * fields with this name, skip this field - all
5070 * fields with the same name are really just versions
5071 * of the same field stored in different bits, and
5072 * should have the same type/radix/value list, and
5073 * just differ in their bit masks. (If a field isn't
5074 * a bitfield, but can be, say, 1 or 2 bytes long,
5075 * it can just be made FT_UINT16, meaning the
5076 * *maximum* length is 2 bytes, and be used
5079 if (hfinfo->same_name_prev != NULL)
5082 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
5084 enum_name = ftype_name(hfinfo->type);
5088 if (hfinfo->type == FT_UINT8 ||
5089 hfinfo->type == FT_UINT16 ||
5090 hfinfo->type == FT_UINT24 ||
5091 hfinfo->type == FT_UINT32 ||
5092 hfinfo->type == FT_UINT64 ||
5093 hfinfo->type == FT_INT8 ||
5094 hfinfo->type == FT_INT16 ||
5095 hfinfo->type == FT_INT24 ||
5096 hfinfo->type == FT_INT32 ||
5097 hfinfo->type == FT_INT64) {
5100 switch(hfinfo->display) {
5102 base_name = "BASE_NONE";
5105 base_name = "BASE_DEC";
5108 base_name = "BASE_HEX";
5111 base_name = "BASE_OCT";
5114 base_name = "BASE_DEC_HEX";
5117 base_name = "BASE_HEX_DEC";
5123 blurb = hfinfo->blurb;
5127 printf("F\t%s\t%s\t%s\t%s\t%s\n",
5128 hfinfo->name, hfinfo->abbrev, enum_name,
5129 parent_hfinfo->abbrev, blurb);
5131 else if (format == 2) {
5132 printf("F\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
5133 hfinfo->name, hfinfo->abbrev, enum_name,
5134 parent_hfinfo->abbrev, blurb,
5137 else if (format == 3) {
5138 printf("F\t%s\t%s\t%s\t%s\t%s\t%s\t%u\n",
5139 hfinfo->name, hfinfo->abbrev, enum_name,
5140 parent_hfinfo->abbrev, blurb,
5141 base_name, hfinfo->bitmask);
5144 g_assert_not_reached();
5151 hfinfo_numeric_format(header_field_info *hfinfo)
5153 const char *format = NULL;
5155 /* Pick the proper format string */
5156 if (hfinfo->type == FT_FRAMENUM) {
5158 * Frame numbers are always displayed in decimal.
5160 format = "%s == %u";
5162 /* Pick the proper format string */
5163 switch(hfinfo->display) {
5166 case BASE_OCT: /* I'm lazy */
5167 switch(hfinfo->type) {
5172 format = "%s == %u";
5175 format = "%s == %" PRIu64;
5181 format = "%s == %d";
5184 format = "%s == %" PRId64;
5187 DISSECTOR_ASSERT_NOT_REACHED();
5193 switch(hfinfo->type) {
5195 format = "%s == 0x%02x";
5198 format = "%s == 0x%04x";
5201 format = "%s == 0x%06x";
5204 format = "%s == 0x%08x";
5207 format = "%s == 0x%016" PRIx64;
5210 DISSECTOR_ASSERT_NOT_REACHED();
5215 DISSECTOR_ASSERT_NOT_REACHED();
5222 /* This function indicates whether it's possible to construct a
5223 * "match selected" display filter string for the specified field,
5224 * returns an indication of whether it's possible, and, if it's
5225 * possible and "filter" is non-null, constructs the filter and
5226 * sets "*filter" to point to it.
5227 * You do not need to [g_]free() this string since it will be automatically
5228 * freed once the next packet is dissected.
5231 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
5234 header_field_info *hfinfo;
5240 gint start, length, length_remaining;
5242 gchar is_signed_num = FALSE;
5244 hfinfo = finfo->hfinfo;
5245 DISSECTOR_ASSERT(hfinfo);
5246 abbrev_len = strlen(hfinfo->abbrev);
5249 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
5250 * functions for FT_UINT and FT_INT types, as we choose the base in
5251 * the string expression based on the display base of the field.
5253 * Note that the base does matter, as this is also used for
5254 * the protocolinfo tap.
5256 * It might be nice to use them in "proto_item_fill_label()"
5257 * as well, although, there, you'd have to deal with the base
5258 * *and* with resolved values for addresses.
5260 * Perhaps we need two different val_to_string routines, one
5261 * to generate items for display filters and one to generate
5262 * strings for display, and pass to both of them the
5263 * "display" and "strings" values in the header_field_info
5264 * structure for the field, so they can get the base and,
5265 * if the field is Boolean or an enumerated integer type,
5266 * the tables used to generate human-readable values.
5268 switch(hfinfo->type) {
5274 is_signed_num = TRUE;
5281 * 4 bytes for " == ".
5284 * a sign + up to 10 digits of 32-bit integer,
5287 * "0x" + 8 digits of 32-bit integer, in hex;
5289 * 11 digits of 32-bit integer, in octal.
5290 * (No, we don't do octal, but this way,
5291 * we know that if we do, this will still
5294 * 1 byte for the trailing '\0'.
5296 if (filter != NULL) {
5297 dfilter_len = abbrev_len + 4 + 11 + 1;
5298 *filter = ep_alloc0(dfilter_len);
5299 format = hfinfo_numeric_format(hfinfo);
5301 g_snprintf(*filter, dfilter_len, format,
5303 fvalue_get_sinteger(&finfo->value));
5305 g_snprintf(*filter, dfilter_len, format,
5307 fvalue_get_uinteger(&finfo->value));
5315 * 4 bytes for " == ".
5318 * a sign + up to 20 digits of 32-bit integer,
5321 * "0x" + 16 digits of 32-bit integer, in hex;
5323 * 22 digits of 32-bit integer, in octal.
5324 * (No, we don't do octal, but this way,
5325 * we know that if we do, this will still
5328 * 1 byte for the trailing '\0'.
5330 if (filter != NULL) {
5331 dfilter_len = abbrev_len + 4 + 22 + 1;
5332 *filter = ep_alloc0(dfilter_len);
5333 format = hfinfo_numeric_format(hfinfo);
5334 g_snprintf(*filter, dfilter_len, format,
5336 fvalue_get_integer64(&finfo->value));
5342 *filter = ep_strdup(finfo->hfinfo->abbrev);
5348 * If the length is 0, just match the name of the
5351 * (Also check for negative values, just in case,
5352 * as we'll cast it to an unsigned value later.)
5354 length = finfo->length;
5357 *filter = ep_strdup(finfo->hfinfo->abbrev);
5364 * This doesn't have a value, so we'd match
5365 * on the raw bytes at this address.
5367 * Should we be allowed to access to the raw bytes?
5368 * If "edt" is NULL, the answer is "no".
5374 * Is this field part of the raw frame tvbuff?
5375 * If not, we can't use "frame[N:M]" to match
5378 * XXX - should this be frame-relative, or
5379 * protocol-relative?
5381 * XXX - does this fallback for non-registered
5382 * fields even make sense?
5384 if (finfo->ds_tvb != edt->tvb)
5385 return FALSE; /* you lose */
5388 * Don't go past the end of that tvbuff.
5390 length_remaining = tvb_length_remaining(finfo->ds_tvb, finfo->start);
5391 if (length > length_remaining)
5392 length = length_remaining;
5396 if (filter != NULL) {
5397 start = finfo->start;
5398 buf_len = 32 + length * 3;
5399 *filter = ep_alloc0(buf_len);
5402 ptr += g_snprintf(ptr, buf_len-(ptr-*filter),
5403 "frame[%d:%d] == ", finfo->start, length);
5404 for (i=0;i<length; i++) {
5405 c = tvb_get_guint8(finfo->ds_tvb, start);
5408 ptr += g_snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
5411 ptr += g_snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
5417 /* By default, use the fvalue's "to_string_repr" method. */
5419 /* Figure out the string length needed.
5420 * The ft_repr length.
5421 * 4 bytes for " == ".
5422 * 1 byte for trailing NUL.
5424 if (filter != NULL) {
5425 dfilter_len = fvalue_string_repr_len(&finfo->value,
5427 dfilter_len += abbrev_len + 4 + 1;
5428 *filter = ep_alloc0(dfilter_len);
5430 /* Create the string */
5431 g_snprintf(*filter, dfilter_len, "%s == ",
5433 fvalue_to_string_repr(&finfo->value,
5435 &(*filter)[abbrev_len + 4]);
5444 * Returns TRUE if we can do a "match selected" on the field, FALSE
5448 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
5450 return construct_match_selected_string(finfo, edt, NULL);
5453 /* This function attempts to construct a "match selected" display filter
5454 * string for the specified field; if it can do so, it returns a pointer
5455 * to the string, otherwise it returns NULL.
5457 * The string is allocated with packet lifetime scope.
5458 * You do not need to [g_]free() this string since it will be automatically
5459 * freed once the next packet is dissected.
5462 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
5466 if (!construct_match_selected_string(finfo, edt, &filter))
5472 /* This function will dissect a sequence of bytes that describe a
5474 * hf_hdr is a 8/16/24/32 bit integer that describes the bitmask to be dissected.
5475 * This field will form an expansion under which the individual fields of the
5476 * bitmask is dissected and displayed.
5477 * This field must be of the type FT_[U]INT{8|16|24|32}.
5479 * fields is an array of pointers to int that lists all the fields of the
5480 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
5481 * or another integer of the same type/size as hf_hdr with a mask specified.
5482 * This array is terminated by a NULL entry.
5484 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
5485 * FT_integer fields that have a value_string attached will have the
5486 * matched string displayed on the expansion line.
5489 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb, int offset, int hf_hdr, gint ett, const int **fields, gboolean little_endian)
5491 proto_tree *tree=NULL;
5492 proto_item *item=NULL;
5493 header_field_info *hf_info;
5497 hf_info=proto_registrar_get_nth(hf_hdr);
5498 switch(hf_info->type){
5502 value=tvb_get_guint8(tvb, offset);
5508 value=tvb_get_letohs(tvb, offset);
5510 value=tvb_get_ntohs(tvb, offset);
5517 value=tvb_get_letoh24(tvb, offset);
5519 value=tvb_get_ntoh24(tvb, offset);
5526 value=tvb_get_letohl(tvb, offset);
5528 value=tvb_get_ntohl(tvb, offset);
5532 g_assert_not_reached();
5536 item=proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, little_endian);
5537 tree=proto_item_add_subtree(item, ett);
5541 header_field_info *hf_field;
5542 guint32 tmpval, tmpmask;
5544 hf_field=proto_registrar_get_nth(**fields);
5545 switch(hf_field->type){
5554 proto_tree_add_item(tree, **fields, tvb, offset, len, little_endian);
5556 /* Mask and shift out the value */
5557 tmpmask=hf_field->bitmask;
5561 while(!(tmpmask&0x00000001)){
5566 /* Show the value_string content (if there is one) */
5567 if(hf_field->strings){
5568 proto_item_append_text(item, ", %s", val_to_str(tmpval, hf_field->strings, "Unknown"));
5573 proto_tree_add_item(tree, **fields, tvb, offset, len, little_endian);
5574 /* if the flag is set, show the name */
5575 if(hf_field->bitmask&value){
5576 proto_item_append_text(item, ", %s", hf_field->name);
5580 g_assert_not_reached();
5590 proto_tree_add_bits_item(proto_tree *tree, int hf_index, tvbuff_t *tvb, gint bit_offset, gint no_of_bits, gboolean little_endian)
5592 return proto_tree_add_bits_ret_val(tree, hf_index, tvb, bit_offset, no_of_bits, NULL, little_endian);
5596 * This function will dissect a sequence of bits that does not need to be byte aligned the bits
5597 * set vill be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
5598 * Offset should be given in bits from the start of the tvb.
5602 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)
5607 guint8 remaining_bits;
5608 guint64 mask = 0,tmp;
5610 header_field_info *hf_field;
5615 hf_field = proto_registrar_get_nth(hf_index);
5617 /* Byte align offset */
5618 offset = bit_offset>>3;
5622 * Calculate the number of octets used to hold the bits
5624 tot_no_bits = ((bit_offset&0x7)+no_of_bits);
5625 length = tot_no_bits>>3;
5626 remaining_bits = tot_no_bits % 8;
5627 if ((remaining_bits)!=0)
5630 if (no_of_bits < 9){
5631 value = tvb_get_bits8(tvb, bit_offset, no_of_bits);
5632 }else if(no_of_bits < 17){
5633 value = tvb_get_bits16(tvb, bit_offset, no_of_bits, little_endian);
5634 }else if(no_of_bits < 33){
5635 value = tvb_get_bits32(tvb, bit_offset, no_of_bits, little_endian);
5636 }else if(no_of_bits < 65){
5637 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, little_endian);
5638 }else if(no_of_bits>64){
5639 DISSECTOR_ASSERT_NOT_REACHED();
5645 mask = mask << (no_of_bits-1);
5647 /* prepare the string */
5650 for(bit=0;bit<((int)(bit_offset&0x07));bit++){
5651 if(bit&&(!(bit%4))){
5656 /* read the bits for the int */
5657 for(i=0;i<no_of_bits;i++){
5658 if(bit&&(!(bit%4))){
5661 if(bit&&(!(bit%8))){
5674 if(bit&&(!(bit%4))){
5681 *return_value=value;
5687 strcat(str,hf_field->name);
5689 switch(hf_field->type){
5692 if (hf_field->strings) {
5693 const true_false_string *tfstring = &tfs_true_false;
5694 tfstring = (const struct true_false_string*) hf_field->strings;
5696 return proto_tree_add_boolean_format(tree, hf_index, tvb, offset, length, (guint32)value,
5699 (guint32)value ? tfstring->true_string : tfstring->false_string);
5701 return proto_tree_add_boolean_format(tree, hf_index, tvb, offset, length, (guint32)value,
5711 /* 1 - 32 bits field */
5712 if (hf_field->strings) {
5713 return proto_tree_add_uint_format(tree, hf_index, tvb, offset, length, (guint32)value,
5716 val_to_str((guint32)value, cVALS(hf_field->strings), "Unknown "),
5720 switch(hf_field->display){
5722 return proto_tree_add_uint_format(tree, hf_index, tvb, offset, length, (guint32)value,
5728 return proto_tree_add_uint_format(tree, hf_index, tvb, offset, length, (guint32)value,
5734 DISSECTOR_ASSERT_NOT_REACHED();
5740 switch(hf_field->display){
5742 return proto_tree_add_uint64_format(tree, hf_index, tvb, offset, length, value,
5748 return proto_tree_add_uint64_format(tree, hf_index, tvb, offset, length, value,
5754 DISSECTOR_ASSERT_NOT_REACHED();
5760 DISSECTOR_ASSERT_NOT_REACHED();