2 * Routines for protocol tree
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include <wsutil/bits_ctz.h>
32 #include <wsutil/bits_count_ones.h>
33 #include <wsutil/sign_ext.h>
35 #include <ftypes/ftypes-int.h>
38 #include "exceptions.h"
39 #include "ptvcursor.h"
41 #include "addr_resolv.h"
42 #include "address_types.h"
45 #include "epan_dissect.h"
47 #include "wmem/wmem.h"
49 #include "asm_utils.h"
50 #include "column-utils.h"
51 #include "to_str-int.h"
53 #include "osi-utils.h"
55 #include "show_exception.h"
57 #include <wsutil/plugins.h>
59 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
60 #define SUBTREE_MAX_LEVELS 256
61 /* Throw an exception if we exceed this many tree items. */
62 /* XXX - This should probably be a preference */
63 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
66 typedef struct __subtree_lvl {
73 subtree_lvl *pushed_tree;
74 guint8 pushed_tree_index;
75 guint8 pushed_tree_max;
81 #define cVALS(x) (const value_string*)(x)
83 /** See inlined comments.
84 @param tree the tree to append this item to
85 @param hfindex field index
86 @param hfinfo header_field
87 @param free_block a code block to call to free resources if this returns
88 @return the header field matching 'hfinfo' */
89 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
90 /* If this item is not referenced we don't have to do much work \
91 at all but we should still return a node so that field items \
92 below this node (think proto_item_add_subtree()) will still \
93 have somewhere to attach to or else filtering will not work \
94 (they would be ignored since tree would be NULL). \
95 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
96 since dissectors that want to do proto_item_set_len() or \
97 other operations that dereference this would crash. \
98 We fake FT_PROTOCOL unless some clients have requested us \
105 PTREE_DATA(tree)->count++; \
106 if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
108 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
109 g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
110 /* Let the exception handler add items to the tree */ \
111 PTREE_DATA(tree)->count = 0; \
112 THROW_MESSAGE(DissectorError, \
113 wmem_strdup_printf(wmem_packet_scope(), "More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
115 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
116 if (!(PTREE_DATA(tree)->visible)) { \
117 if (PTREE_FINFO(tree)) { \
118 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
119 && (hfinfo->type != FT_PROTOCOL || \
120 PTREE_DATA(tree)->fake_protocols)) { \
122 /* just return tree back to the caller */\
128 /** See inlined comments.
129 @param tree the tree to append this item to
130 @param hfindex field index
131 @param hfinfo header_field
132 @return the header field matching 'hfinfo' */
133 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
134 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
137 /** See inlined comments.
138 @param pi the created protocol item we're about to return */
139 #define TRY_TO_FAKE_THIS_REPR(pi) \
141 if (!(PTREE_DATA(pi)->visible)) { \
142 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
143 * items string representation */ \
146 /* Same as above but returning void */
147 #define TRY_TO_FAKE_THIS_REPR_VOID(pi) \
150 if (!(PTREE_DATA(pi)->visible)) { \
151 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
152 * items string representation */ \
156 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
157 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
159 static void label_mark_truncated(char *label_str, gsize name_pos);
160 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
162 static void fill_label_boolean(field_info *fi, gchar *label_str);
163 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
164 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
165 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
166 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
168 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
169 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
170 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
171 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
172 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
173 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
174 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
175 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
178 proto_tree_add_node(proto_tree *tree, field_info *fi);
181 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
185 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
186 const gint start, const gint item_length);
189 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
190 gint start, gint *length);
193 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
195 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
198 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb);
200 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
202 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
204 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
206 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
208 proto_tree_set_string(field_info *fi, const char* value);
210 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding);
212 proto_tree_set_ax25(field_info *fi, const guint8* value);
214 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
216 proto_tree_set_vines(field_info *fi, const guint8* value);
218 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
220 proto_tree_set_ether(field_info *fi, const guint8* value);
222 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
224 proto_tree_set_ipxnet(field_info *fi, guint32 value);
226 proto_tree_set_ipv4(field_info *fi, guint32 value);
228 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
230 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
232 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
234 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
236 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
238 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
240 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
242 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
244 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
246 proto_tree_set_boolean(field_info *fi, guint64 value);
248 proto_tree_set_float(field_info *fi, float value);
250 proto_tree_set_double(field_info *fi, double value);
252 proto_tree_set_uint(field_info *fi, guint32 value);
254 proto_tree_set_int(field_info *fi, gint32 value);
256 proto_tree_set_uint64(field_info *fi, guint64 value);
258 proto_tree_set_int64(field_info *fi, gint64 value);
260 proto_tree_set_eui64(field_info *fi, const guint64 value);
262 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
264 /* Handle type length mismatch (now filterable) expert info */
265 static int proto_type_length_mismatch = -1;
266 static expert_field ei_type_length_mismatch_error = EI_INIT;
267 static expert_field ei_type_length_mismatch_warn = EI_INIT;
268 static void register_type_length_mismatch(void);
270 /* Handle number string decoding errors with expert info */
271 static int proto_number_string_decoding_error = -1;
272 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
273 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
274 static void register_number_string_decoding_error(void);
276 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
278 /* special-case header field used within proto.c */
279 static header_field_info hfi_text_only =
280 { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
281 int hf_text_only = -1;
283 /* Structure for information about a protocol */
285 const char *name; /* long description */
286 const char *short_name; /* short description */
287 const char *filter_name; /* name of this protocol in filters */
288 GPtrArray *fields; /* fields for this protocol */
289 int proto_id; /* field ID for this protocol */
290 gboolean is_enabled; /* TRUE if protocol is enabled */
291 gboolean can_toggle; /* TRUE if is_enabled can be changed */
292 GList *heur_list; /* Heuristic dissectors associated with this protocol */
295 /* List of all protocols */
296 static GList *protocols = NULL;
298 /* Deregistered fields */
299 static GPtrArray *deregistered_fields = NULL;
300 static GPtrArray *deregistered_data = NULL;
302 /* Contains information about a field when a dissector calls
303 * proto_tree_add_item. */
304 #define FIELD_INFO_NEW(pool, fi) fi = wmem_new(pool, field_info)
305 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
307 /* Contains the space for proto_nodes. */
308 #define PROTO_NODE_INIT(node) \
309 node->first_child = NULL; \
310 node->last_child = NULL; \
313 #define PROTO_NODE_FREE(pool, node) \
314 wmem_free(pool, node)
316 /* String space for protocol and field items for the GUI */
317 #define ITEM_LABEL_NEW(pool, il) \
318 il = wmem_new(pool, item_label_t);
319 #define ITEM_LABEL_FREE(pool, il) \
322 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
323 if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
324 g_error("Unregistered hf! index=%d", hfindex); \
325 DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
326 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
327 hfinfo = gpa_hfinfo.hfi[hfindex];
329 /* List which stores protocols and fields that have been registered */
330 typedef struct _gpa_hfinfo_t {
332 guint32 allocated_len;
333 header_field_info **hfi;
336 static gpa_hfinfo_t gpa_hfinfo;
338 /* Hash table of abbreviations and IDs */
339 static GHashTable *gpa_name_map = NULL;
340 static header_field_info *same_name_hfinfo;
342 * We're called repeatedly with the same field name when sorting a column.
343 * Cache our last gpa_name_map hit for faster lookups.
345 static char *last_field_name = NULL;
346 static header_field_info *last_hfinfo;
348 static void save_same_name_hfinfo(gpointer data)
350 same_name_hfinfo = (header_field_info*)data;
353 /* Points to the first element of an array of bits, indexed by
354 a subtree item type; that array element is TRUE if subtrees of
355 an item of that type are to be expanded. */
356 static guint32 *tree_is_expanded;
358 /* Number of elements in that array. */
361 /* Name hashtables for fast detection of duplicate names */
362 static GHashTable* proto_names = NULL;
363 static GHashTable* proto_short_names = NULL;
364 static GHashTable* proto_filter_names = NULL;
367 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
369 const protocol_t *p1 = (const protocol_t *)p1_arg;
370 const protocol_t *p2 = (const protocol_t *)p2_arg;
372 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
377 * List of dissector plugins.
380 void (*register_protoinfo)(void); /* routine to call to register protocol information */
381 void (*reg_handoff)(void); /* routine to call to register dissector handoff */
384 static GSList *dissector_plugins = NULL;
387 * Callback for each plugin found.
390 check_for_dissector_plugin(GModule *handle)
393 void (*register_protoinfo)(void);
394 void (*reg_handoff)(void);
395 dissector_plugin *plugin;
398 * Do we have a register routine?
400 if (g_module_symbol(handle, "plugin_register", &gp))
401 register_protoinfo = (void (*)(void))gp;
403 register_protoinfo = NULL;
406 * Do we have a reg_handoff routine?
408 if (g_module_symbol(handle, "plugin_reg_handoff", &gp))
409 reg_handoff = (void (*)(void))gp;
414 * If we have neither, we're not a dissector plugin.
416 if (register_protoinfo == NULL && reg_handoff == NULL)
420 * Add this one to the list of dissector plugins.
422 plugin = (dissector_plugin *)g_malloc(sizeof (dissector_plugin));
423 plugin->register_protoinfo = register_protoinfo;
424 plugin->reg_handoff = reg_handoff;
425 dissector_plugins = g_slist_append(dissector_plugins, plugin);
430 register_dissector_plugin(gpointer data, gpointer user_data _U_)
432 dissector_plugin *plugin = (dissector_plugin *)data;
434 if (plugin->register_protoinfo)
435 (plugin->register_protoinfo)();
439 reg_handoff_dissector_plugin(gpointer data, gpointer user_data _U_)
441 dissector_plugin *plugin = (dissector_plugin *)data;
443 if (plugin->reg_handoff)
444 (plugin->reg_handoff)();
448 * Register dissector plugin type.
451 register_dissector_plugin_type(void)
453 add_plugin_type("dissector", check_for_dissector_plugin);
455 #endif /* HAVE_PLUGINS */
457 /* initialize data structures and register protocols and fields */
459 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
460 void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
462 gpointer client_data)
466 proto_names = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
467 proto_short_names = g_hash_table_new(wrs_str_hash, g_str_equal);
468 proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
471 gpa_hfinfo.allocated_len = 0;
472 gpa_hfinfo.hfi = NULL;
473 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
474 deregistered_fields = g_ptr_array_new();
475 deregistered_data = g_ptr_array_new();
477 /* Initialize the ftype subsystem */
480 /* Initialize the addres type subsystem */
481 address_types_initialize();
483 /* Register one special-case FT_TEXT_ONLY field for use when
484 converting wireshark to new-style proto_tree. These fields
485 are merely strings on the GUI tree; they are not filterable */
486 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
488 /* Register the pseudo-protocols used for exceptions. */
489 register_show_exception();
490 register_type_length_mismatch();
491 register_number_string_decoding_error();
493 /* Have each built-in dissector register its protocols, fields,
494 dissector tables, and dissectors to be called through a
495 handle, and do whatever one-time initialization it needs to
497 register_all_protocols_func(cb, client_data);
500 /* Now call the registration routines for all disssector
503 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
504 g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL);
507 /* Now call the "handoff registration" routines of all built-in
508 dissectors; those routines register the dissector in other
509 dissectors' handoff tables, and fetch any dissector handles
511 register_all_handoffs_func(cb, client_data);
514 /* Now do the same with plugins. */
516 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
517 g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL);
520 /* sort the protocols by protocol name */
521 protocols = g_list_sort(protocols, proto_compare_name);
523 /* We've assigned all the subtree type values; allocate the array
524 for them, and zero it out. */
525 tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
531 /* Free the abbrev/ID hash table */
533 g_hash_table_destroy(gpa_name_map);
536 g_free(last_field_name);
537 last_field_name = NULL;
540 protocol_t *protocol = (protocol_t *)protocols->data;
541 header_field_info *hfinfo;
542 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
543 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
545 g_slice_free(header_field_info, hfinfo);
546 g_ptr_array_free(protocol->fields, TRUE);
547 g_list_free(protocol->heur_list);
548 protocols = g_list_remove(protocols, protocol);
553 g_hash_table_destroy(proto_names);
557 if (proto_short_names) {
558 g_hash_table_destroy(proto_short_names);
559 proto_short_names = NULL;
562 if (proto_filter_names) {
563 g_hash_table_destroy(proto_filter_names);
564 proto_filter_names = NULL;
567 if (gpa_hfinfo.allocated_len) {
569 gpa_hfinfo.allocated_len = 0;
570 g_free(gpa_hfinfo.hfi);
571 gpa_hfinfo.hfi = NULL;
574 if (deregistered_fields) {
575 g_ptr_array_free(deregistered_fields, FALSE);
576 deregistered_fields = NULL;
579 if (deregistered_data) {
580 g_ptr_array_free(deregistered_data, FALSE);
581 deregistered_data = NULL;
584 g_free(tree_is_expanded);
585 tree_is_expanded = NULL;
589 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
592 proto_node *pnode = tree;
596 if (func(pnode, data))
599 child = pnode->first_child;
600 while (child != NULL) {
602 * The routine we call might modify the child, e.g. by
603 * freeing it, so we get the child's successor before
604 * calling that routine.
607 child = current->next;
608 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
616 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
619 proto_node *pnode = tree;
623 child = pnode->first_child;
624 while (child != NULL) {
626 * The routine we call might modify the child, e.g. by
627 * freeing it, so we get the child's successor before
628 * calling that routine.
631 child = current->next;
632 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
635 if (func(pnode, data))
642 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
645 proto_node *node = tree;
651 node = node->first_child;
652 while (node != NULL) {
654 node = current->next;
655 func((proto_tree *)current, data);
660 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
662 GPtrArray *ptrs = (GPtrArray *)value;
663 gint hfid = GPOINTER_TO_UINT(key);
664 header_field_info *hfinfo;
666 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
667 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
668 /* when a field is referenced by a filter this also
669 affects the refcount for the parent protocol so we need
670 to adjust the refcount for the parent as well
672 if (hfinfo->parent != -1) {
673 header_field_info *parent_hfinfo;
674 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
675 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
677 hfinfo->ref_type = HF_REF_TYPE_NONE;
680 g_ptr_array_free(ptrs, TRUE);
684 proto_tree_free_node(proto_node *node, gpointer data _U_)
686 field_info *finfo = PNODE_FINFO(node);
688 proto_tree_children_foreach(node, proto_tree_free_node, NULL);
690 FVALUE_CLEANUP(&finfo->value);
694 proto_tree_reset(proto_tree *tree)
696 tree_data_t *tree_data = PTREE_DATA(tree);
698 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
701 if (tree_data->interesting_hfids) {
702 /* Free all the GPtrArray's in the interesting_hfids hash. */
703 g_hash_table_foreach(tree_data->interesting_hfids,
704 free_GPtrArray_value, NULL);
706 /* And then remove all values. */
707 g_hash_table_remove_all(tree_data->interesting_hfids);
710 /* Reset track of the number of children */
711 tree_data->count = 0;
713 PROTO_NODE_INIT(tree);
716 /* frees the resources that the dissection a proto_tree uses */
718 proto_tree_free(proto_tree *tree)
720 tree_data_t *tree_data = PTREE_DATA(tree);
722 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
725 if (tree_data->interesting_hfids) {
726 /* Free all the GPtrArray's in the interesting_hfids hash. */
727 g_hash_table_foreach(tree_data->interesting_hfids,
728 free_GPtrArray_value, NULL);
730 /* And then destroy the hash. */
731 g_hash_table_destroy(tree_data->interesting_hfids);
734 g_slice_free(tree_data_t, tree_data);
736 g_slice_free(proto_tree, tree);
739 /* Is the parsing being done for a visible proto_tree or an invisible one?
740 * By setting this correctly, the proto_tree creation is sped up by not
741 * having to call g_vsnprintf and copy strings around.
744 proto_tree_set_visible(proto_tree *tree, gboolean visible)
746 gboolean old_visible = PTREE_DATA(tree)->visible;
748 PTREE_DATA(tree)->visible = visible;
754 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
756 PTREE_DATA(tree)->fake_protocols = fake_protocols;
759 /* Assume dissector set only its protocol fields.
760 This function is called by dissectors and allows the speeding up of filtering
761 in wireshark; if this function returns FALSE it is safe to reset tree to NULL
762 and thus skip calling most of the expensive proto_tree_add_...()
764 If the tree is visible we implicitly assume the field is referenced.
767 proto_field_is_referenced(proto_tree *tree, int proto_id)
769 register header_field_info *hfinfo;
775 if (PTREE_DATA(tree)->visible)
778 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
779 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
782 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
789 /* Finds a record in the hfinfo array by id. */
791 proto_registrar_get_nth(guint hfindex)
793 register header_field_info *hfinfo;
795 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
800 /* Prefix initialization
801 * this allows for a dissector to register a display filter name prefix
802 * so that it can delay the initialization of the hf array as long as
806 /* compute a hash for the part before the dot of a display filter */
808 prefix_hash (gconstpointer key) {
809 /* end the string at the dot and compute its hash */
810 gchar* copy = g_strdup((const gchar *)key);
821 tmp = g_str_hash(copy);
826 /* are both strings equal up to the end or the dot? */
828 prefix_equal (gconstpointer ap, gconstpointer bp) {
829 const gchar* a = (const gchar *)ap;
830 const gchar* b = (const gchar *)bp;
836 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
838 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
839 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
841 if (ac != bc) return FALSE;
848 /* indexed by prefix, contains initializers */
849 static GHashTable* prefixes = NULL;
852 /* Register a new prefix for "delayed" initialization of field arrays */
854 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
856 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
859 g_hash_table_insert(prefixes, (gpointer)prefix, pi);
862 /* helper to call all prefix initializers */
864 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
865 ((prefix_initializer_t)v)((const char *)k);
869 /** Initialize every remaining uninitialized prefix. */
871 proto_initialize_all_prefixes(void) {
872 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
875 /* Finds a record in the hfinfo array by name.
876 * If it fails to find it in the already registered fields,
877 * it tries to find and call an initializer in the prefixes
878 * table and if so it looks again.
882 proto_registrar_get_byname(const char *field_name)
884 header_field_info *hfinfo;
885 prefix_initializer_t pi;
890 if (g_strcmp0(field_name, last_field_name) == 0) {
894 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
897 g_free(last_field_name);
898 last_field_name = g_strdup(field_name);
899 last_hfinfo = hfinfo;
906 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
908 g_hash_table_remove(prefixes, field_name);
913 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
916 g_free(last_field_name);
917 last_field_name = g_strdup(field_name);
918 last_hfinfo = hfinfo;
924 proto_registrar_get_id_byname(const char *field_name)
926 header_field_info *hfinfo;
928 hfinfo = proto_registrar_get_byname(field_name);
938 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
940 subtree_lvl *pushed_tree;
942 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
943 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
945 pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
946 DISSECTOR_ASSERT(pushed_tree != NULL);
947 if (ptvc->pushed_tree)
948 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
949 ptvc->pushed_tree = pushed_tree;
953 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
955 ptvc->pushed_tree = NULL;
956 ptvc->pushed_tree_max = 0;
957 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
958 ptvc->pushed_tree_index = 0;
961 /* Allocates an initializes a ptvcursor_t with 3 variables:
962 * proto_tree, tvbuff, and offset. */
964 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
968 ptvc = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
971 ptvc->offset = offset;
972 ptvc->pushed_tree = NULL;
973 ptvc->pushed_tree_max = 0;
974 ptvc->pushed_tree_index = 0;
979 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
981 ptvcursor_free(ptvcursor_t *ptvc)
983 ptvcursor_free_subtree_levels(ptvc);
987 /* Returns tvbuff. */
989 ptvcursor_tvbuff(ptvcursor_t *ptvc)
994 /* Returns current offset. */
996 ptvcursor_current_offset(ptvcursor_t *ptvc)
1002 ptvcursor_tree(ptvcursor_t *ptvc)
1011 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1016 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1018 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1020 subtree_lvl *subtree;
1021 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1022 ptvcursor_new_subtree_levels(ptvc);
1024 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1025 subtree->tree = ptvc->tree;
1027 ptvc->pushed_tree_index++;
1028 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1031 /* pops a subtree */
1033 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1035 subtree_lvl *subtree;
1037 if (ptvc->pushed_tree_index <= 0)
1040 ptvc->pushed_tree_index--;
1041 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1042 if (subtree->it != NULL)
1043 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1045 ptvc->tree = subtree->tree;
1048 /* saves the current tvb offset and the item in the current subtree level */
1050 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1052 subtree_lvl *subtree;
1054 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1056 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1058 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1061 /* Creates a subtree and adds it to the cursor as the working tree but does not
1062 * save the old working tree */
1064 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1066 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1071 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1073 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1074 if (length == SUBTREE_UNDEFINED_LENGTH)
1075 ptvcursor_subtree_set_item(ptvc, it);
1076 return ptvcursor_tree(ptvc);
1079 /* Add an item to the tree and create a subtree
1080 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1081 * In this case, when the subtree will be closed, the parent item length will
1082 * be equal to the advancement of the cursor since the creation of the subtree.
1085 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1086 const guint encoding, gint ett_subtree)
1090 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1091 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1095 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1097 /* Add a text node to the tree and create a subtree
1098 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1099 * In this case, when the subtree will be closed, the item length will be equal
1100 * to the advancement of the cursor since the creation of the subtree.
1103 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1104 gint ett_subtree, const char *format, ...)
1108 header_field_info *hfinfo;
1111 tree = ptvcursor_tree(ptvc);
1113 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1115 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1116 ptvcursor_current_offset(ptvc), length);
1118 TRY_TO_FAKE_THIS_REPR(pi);
1120 va_start(ap, format);
1121 proto_tree_set_representation(pi, format, ap);
1124 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1127 /* Add a text-only node, leaving it to our caller to fill the text in */
1129 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1136 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1141 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1143 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1144 const char *format, ...)
1148 header_field_info *hfinfo;
1150 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1152 pi = proto_tree_add_text_node(tree, tvb, start, length);
1154 TRY_TO_FAKE_THIS_REPR(pi);
1156 va_start(ap, format);
1157 proto_tree_set_representation(pi, format, ap);
1163 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1165 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1166 gint length, const char *format, va_list ap)
1169 header_field_info *hfinfo;
1171 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1173 pi = proto_tree_add_text_node(tree, tvb, start, length);
1175 TRY_TO_FAKE_THIS_REPR(pi);
1177 proto_tree_set_representation(pi, format, ap);
1182 /* Add a text-only node that creates a subtree underneath.
1185 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1187 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1190 /* Add a text-only node that creates a subtree underneath.
1193 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1199 va_start(ap, format);
1200 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1203 if (tree_item != NULL)
1206 pt = proto_item_add_subtree(pi, idx);
1211 /* Add a text-only node for debugging purposes. The caller doesn't need
1212 * to worry about tvbuff, start, or length. Debug message gets sent to
1215 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1220 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1223 va_start(ap, format);
1224 proto_tree_set_representation(pi, format, ap);
1227 va_start(ap, format);
1228 vprintf(format, ap);
1236 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1239 header_field_info *hfinfo;
1241 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1243 pi = proto_tree_add_text_node(tree, tvb, start, length);
1245 TRY_TO_FAKE_THIS_REPR(pi);
1247 proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1253 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1256 header_field_info *hfinfo;
1258 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1260 pi = proto_tree_add_text_node(tree, tvb, start, length);
1262 TRY_TO_FAKE_THIS_REPR(pi);
1264 proto_item_set_text(pi, "%s", tvb_format_text_wsp(tvb, start, length));
1269 void proto_report_dissector_bug(const char *message)
1271 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1274 THROW_MESSAGE(DissectorError, message);
1277 /* We could probably get away with changing is_error to a minimum length value. */
1279 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1282 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1284 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1288 THROW(ReportedBoundsError);
1293 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1296 gboolean length_error;
1301 value = tvb_get_guint8(tvb, offset);
1305 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1306 : tvb_get_ntohs(tvb, offset);
1310 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1311 : tvb_get_ntoh24(tvb, offset);
1315 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1316 : tvb_get_ntohl(tvb, offset);
1321 length_error = TRUE;
1324 length_error = FALSE;
1325 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1326 : tvb_get_ntohl(tvb, offset);
1328 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1335 * NOTE: to support code written when proto_tree_add_item() took a
1336 * gboolean as its last argument, with FALSE meaning "big-endian"
1337 * and TRUE meaning "little-endian", we treat any non-zero value of
1338 * "encoding" as meaning "little-endian".
1340 static inline guint64
1341 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1344 gboolean length_error;
1349 value = tvb_get_guint8(tvb, offset);
1353 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1354 : tvb_get_ntohs(tvb, offset);
1358 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1359 : tvb_get_ntoh24(tvb, offset);
1363 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1364 : tvb_get_ntohl(tvb, offset);
1368 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1369 : tvb_get_ntoh40(tvb, offset);
1373 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1374 : tvb_get_ntoh48(tvb, offset);
1378 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1379 : tvb_get_ntoh56(tvb, offset);
1383 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1384 : tvb_get_ntoh64(tvb, offset);
1389 length_error = TRUE;
1392 length_error = FALSE;
1393 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1394 : tvb_get_ntoh64(tvb, offset);
1396 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1403 * NOTE: to support code written when proto_tree_add_item() took a
1404 * gboolean as its last argument, with FALSE meaning "big-endian"
1405 * and TRUE meaning "little-endian", we treat any non-zero value of
1406 * "encoding" as meaning "little-endian".
1409 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1412 gboolean length_error;
1417 value = (gint8)tvb_get_guint8(tvb, offset);
1421 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1422 : tvb_get_ntohs(tvb, offset));
1426 value = encoding ? tvb_get_letoh24(tvb, offset)
1427 : tvb_get_ntoh24(tvb, offset);
1428 if (value & 0x00800000) {
1429 /* Sign bit is set; sign-extend it. */
1430 value |= 0xFF000000;
1435 value = encoding ? tvb_get_letohl(tvb, offset)
1436 : tvb_get_ntohl(tvb, offset);
1441 length_error = TRUE;
1444 length_error = FALSE;
1445 value = encoding ? tvb_get_letohl(tvb, offset)
1446 : tvb_get_ntohl(tvb, offset);
1448 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1454 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1455 * be cast-able as a gint64. This is weird, but what the code has always done.
1457 static inline guint64
1458 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1460 guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1465 value = ws_sign_ext64(value, 56);
1468 value = ws_sign_ext64(value, 48);
1471 value = ws_sign_ext64(value, 40);
1474 value = ws_sign_ext64(value, 32);
1477 value = ws_sign_ext64(value, 24);
1480 value = ws_sign_ext64(value, 16);
1483 value = ws_sign_ext64(value, 8);
1490 /* this can be called when there is no tree, so don't add that as a param */
1492 get_time_value(tvbuff_t *tvb, const gint start, const gint length, const guint encoding,
1493 nstime_t *time_stamp, const gboolean is_relative)
1498 /* relative timestamps don't do TOD/NTP */
1500 (encoding != (ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN)) &&
1501 (encoding != (ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN)) )
1503 /* XXX: I think this should call REPORT_DISSECTOR_BUG(), but
1504 the existing code didn't do that, so I'm not either */
1510 case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1512 * 4-byte UNIX epoch, possibly followed by
1513 * 4-byte fractional time in nanoseconds,
1516 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1518 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1520 time_stamp->nsecs = 0;
1523 case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1525 * 4-byte UNIX epoch, possibly followed by
1526 * 4-byte fractional time in nanoseconds,
1527 * both little-endian.
1529 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1531 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1533 time_stamp->nsecs = 0;
1536 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1538 * TOD time stamp, big-endian.
1540 /* XXX - where should this go? */
1541 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800)
1543 todsecs = tvb_get_ntoh64(tvb, start) >> 12;
1544 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1545 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1548 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1550 * TOD time stamp, big-endian.
1552 todsecs = tvb_get_letoh64(tvb, start) >> 12 ;
1553 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1554 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1557 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1559 * NTP time stamp, big-endian.
1562 /* XXX - where should this go? */
1563 #define NTP_BASETIME G_GUINT64_CONSTANT(2208988800)
1565 /* We need a temporary variable here so the unsigned math
1566 * works correctly (for years > 2036 according to RFC 2030
1569 tmpsecs = tvb_get_ntohl(tvb, start);
1571 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1573 time_stamp->secs = tmpsecs; /* 0 */
1577 * We're using nanoseconds here (and we will
1578 * display nanoseconds), but NTP's timestamps
1579 * have a precision in microseconds or greater.
1580 * Round to 1 microsecond.
1582 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1583 time_stamp->nsecs *= 1000;
1585 time_stamp->nsecs = 0;
1589 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1591 * NTP time stamp, big-endian.
1593 tmpsecs = tvb_get_letohl(tvb, start);
1595 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1597 time_stamp->secs = tmpsecs; /* 0 */
1601 * We're using nanoseconds here (and we will
1602 * display nanoseconds), but NTP's timestamps
1603 * have a precision in microseconds or greater.
1604 * Round to 1 microsecond.
1606 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1607 time_stamp->nsecs *= 1000;
1609 time_stamp->nsecs = 0;
1612 case ENC_TIME_NTP_BASE_ZERO|ENC_BIG_ENDIAN:
1614 * DDS NTP time stamp, big-endian.
1617 #define NTP_BASETIME_ZERO G_GUINT64_CONSTANT(0)
1619 tmpsecs = tvb_get_ntohl(tvb, start);
1621 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1623 time_stamp->secs = tmpsecs; /* 0 */
1627 * We're using nanoseconds here (and we will
1628 * display nanoseconds), but NTP's timestamps
1629 * have a precision in microseconds or greater.
1630 * Round to 1 microsecond.
1632 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1633 time_stamp->nsecs *= 1000;
1635 time_stamp->nsecs = 0;
1639 case ENC_TIME_NTP_BASE_ZERO|ENC_LITTLE_ENDIAN:
1641 * NTP time stamp, big-endian.
1643 tmpsecs = tvb_get_letohl(tvb, start);
1645 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1647 time_stamp->secs = tmpsecs; /* 0 */
1648 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1651 * We're using nanoseconds here (and we will
1652 * display nanoseconds), but NTP's timestamps
1653 * have a precision in microseconds or greater.
1654 * Round to 1 microsecond.
1656 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1657 time_stamp->nsecs *= 1000;
1659 time_stamp->nsecs = 0;
1664 DISSECTOR_ASSERT_NOT_REACHED();
1670 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
1672 const header_field_info *hfinfo = fi->hfinfo;
1674 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
1675 GPtrArray *ptrs = NULL;
1677 if (tree_data->interesting_hfids == NULL) {
1678 /* Initialize the hash because we now know that it is needed */
1679 tree_data->interesting_hfids =
1680 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
1681 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
1682 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
1683 GINT_TO_POINTER(hfinfo->id));
1687 /* First element triggers the creation of pointer array */
1688 ptrs = g_ptr_array_new();
1689 g_hash_table_insert(tree_data->interesting_hfids,
1690 GINT_TO_POINTER(hfinfo->id), ptrs);
1693 g_ptr_array_add(ptrs, fi);
1697 /* Add an item to a proto_tree, using the text label registered to that item;
1698 the item is extracted from the tvbuff handed to it. */
1700 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
1701 tvbuff_t *tvb, gint start, gint length,
1709 nstime_t time_stamp;
1710 gboolean length_error;
1712 switch (new_fi->hfinfo->type) {
1714 /* no value to set for FT_NONE */
1718 proto_tree_set_protocol_tvb(new_fi, tvb);
1722 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
1727 * Map all non-zero values to little-endian for
1728 * backwards compatibility.
1731 encoding = ENC_LITTLE_ENDIAN;
1732 n = get_uint_value(tree, tvb, start, length, encoding);
1733 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
1735 /* Instead of calling proto_item_set_len(), since we don't yet
1736 * have a proto_item, we set the field_info's length ourselves. */
1737 new_fi->length = n + length;
1742 * Map all non-zero values to little-endian for
1743 * backwards compatibility.
1746 encoding = ENC_LITTLE_ENDIAN;
1747 proto_tree_set_boolean(new_fi,
1748 get_uint64_value(tree, tvb, start, length, encoding));
1751 /* XXX - make these just FT_UINT? */
1757 * Map all non-zero values to little-endian for
1758 * backwards compatibility.
1761 encoding = ENC_LITTLE_ENDIAN;
1762 proto_tree_set_uint(new_fi,
1763 get_uint_value(tree, tvb, start, length, encoding));
1771 * Map all non-zero values to little-endian for
1772 * backwards compatibility.
1775 encoding = ENC_LITTLE_ENDIAN;
1776 proto_tree_set_uint64(new_fi,
1777 get_uint64_value(tree, tvb, start, length, encoding));
1780 /* XXX - make these just FT_INT? */
1786 * Map all non-zero values to little-endian for
1787 * backwards compatibility.
1790 encoding = ENC_LITTLE_ENDIAN;
1791 proto_tree_set_int(new_fi,
1792 get_int_value(tree, tvb, start, length, encoding));
1800 * Map all non-zero values to little-endian for
1801 * backwards compatibility.
1804 encoding = ENC_LITTLE_ENDIAN;
1805 proto_tree_set_int64(new_fi,
1806 get_int64_value(tree, tvb, start, length, encoding));
1811 * Map all non-zero values to little-endian for
1812 * backwards compatibility.
1815 encoding = ENC_LITTLE_ENDIAN;
1816 if (length != FT_IPv4_LEN) {
1817 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
1818 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
1820 value = tvb_get_ipv4(tvb, start);
1822 * NOTE: to support code written when
1823 * proto_tree_add_item() took a gboolean as its
1824 * last argument, with FALSE meaning "big-endian"
1825 * and TRUE meaning "little-endian", we treat any
1826 * non-zero value of "encoding" as meaning
1829 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
1833 if (length != FT_IPXNET_LEN) {
1834 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
1835 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
1837 proto_tree_set_ipxnet(new_fi,
1838 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
1842 if (length != FT_IPv6_LEN) {
1843 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
1844 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
1846 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
1850 if (length != FT_FCWWN_LEN) {
1851 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
1852 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
1854 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
1859 length_error = length < 7 ? TRUE : FALSE;
1860 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
1862 proto_tree_set_ax25_tvb(new_fi, tvb, start);
1866 if (length != VINES_ADDR_LEN) {
1867 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
1868 report_type_length_mismatch(tree, "a Vines address", length, length_error);
1870 proto_tree_set_vines_tvb(new_fi, tvb, start);
1874 if (length != FT_ETHER_LEN) {
1875 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
1876 report_type_length_mismatch(tree, "a MAC address", length, length_error);
1878 proto_tree_set_ether_tvb(new_fi, tvb, start);
1883 * Map all non-zero values to little-endian for
1884 * backwards compatibility.
1887 encoding = ENC_LITTLE_ENDIAN;
1888 if (length != FT_EUI64_LEN) {
1889 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
1890 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
1892 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
1896 * Map all non-zero values to little-endian for
1897 * backwards compatibility.
1900 encoding = ENC_LITTLE_ENDIAN;
1901 if (length != FT_GUID_LEN) {
1902 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
1903 report_type_length_mismatch(tree, "a GUID", length, length_error);
1905 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
1910 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
1914 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
1919 * NOTE: to support code written when
1920 * proto_tree_add_item() took a gboolean as its
1921 * last argument, with FALSE meaning "big-endian"
1922 * and TRUE meaning "little-endian", we treat any
1923 * non-zero value of "encoding" as meaning
1926 * At some point in the future, we might
1927 * support non-IEEE-binary floating-point
1928 * formats in the encoding as well
1929 * (IEEE decimal, System/3x0, VAX).
1932 encoding = ENC_LITTLE_ENDIAN;
1934 length_error = length < 4 ? TRUE : FALSE;
1935 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
1938 floatval = tvb_get_letohieee_float(tvb, start);
1940 floatval = tvb_get_ntohieee_float(tvb, start);
1941 proto_tree_set_float(new_fi, floatval);
1946 * NOTE: to support code written when
1947 * proto_tree_add_item() took a gboolean as its
1948 * last argument, with FALSE meaning "big-endian"
1949 * and TRUE meaning "little-endian", we treat any
1950 * non-zero value of "encoding" as meaning
1953 * At some point in the future, we might
1954 * support non-IEEE-binary floating-point
1955 * formats in the encoding as well
1956 * (IEEE decimal, System/3x0, VAX).
1958 if (encoding == TRUE)
1959 encoding = ENC_LITTLE_ENDIAN;
1961 length_error = length < 8 ? TRUE : FALSE;
1962 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
1965 doubleval = tvb_get_letohieee_double(tvb, start);
1967 doubleval = tvb_get_ntohieee_double(tvb, start);
1968 proto_tree_set_double(new_fi, doubleval);
1972 proto_tree_set_string_tvb(new_fi, tvb, start, length,
1978 report_type_length_mismatch(tree, "a string", length, TRUE);
1980 /* Instead of calling proto_item_set_len(),
1981 * since we don't yet have a proto_item, we
1982 * set the field_info's length ourselves.
1984 * XXX - our caller can't use that length to
1985 * advance an offset unless they arrange that
1986 * there always be a protocol tree into which
1987 * we're putting this item.
1990 /* This can throw an exception */
1991 string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
1992 } else if (length == 0) {
1995 /* In this case, length signifies
1996 * the length of the string.
1998 * This could either be a null-padded
1999 * string, which doesn't necessarily
2000 * have a '\0' at the end, or a
2001 * null-terminated string, with a
2002 * trailing '\0'. (Yes, there are
2003 * cases where you have a string
2004 * that's both counted and null-
2007 * In the first case, we must
2008 * allocate a buffer of length
2009 * "length+1", to make room for
2012 * In the second case, we don't
2013 * assume that there is a trailing
2014 * '\0' there, as the packet might
2015 * be malformed. (XXX - should we
2016 * throw an exception if there's no
2017 * trailing '\0'?) Therefore, we
2018 * allocate a buffer of length
2019 * "length+1", and put in a trailing
2020 * '\0', just to be safe.
2022 * (XXX - this would change if
2023 * we made string values counted
2024 * rather than null-terminated.)
2026 string = tvb_get_string_enc(wmem_packet_scope(), tvb, start, length, encoding);
2028 new_fi->length = length;
2029 proto_tree_set_string(new_fi, string);
2032 case FT_UINT_STRING:
2034 * NOTE: to support code written when
2035 * proto_tree_add_item() took a gboolean as its
2036 * last argument, with FALSE meaning "big-endian"
2037 * and TRUE meaning "little-endian", if the
2038 * encoding value is TRUE, treat that as
2039 * ASCII with a little-endian length.
2041 * This won't work for code that passes
2042 * arbitrary non-zero values; that code
2043 * will need to be fixed.
2045 if (encoding == TRUE)
2046 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2047 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
2048 proto_tree_set_string_tvb(new_fi, tvb, start + length, n,
2051 /* Instead of calling proto_item_set_len(), since we
2052 * don't yet have a proto_item, we set the
2053 * field_info's length ourselves.
2055 * XXX - our caller can't use that length to
2056 * advance an offset unless they arrange that
2057 * there always be a protocol tree into which
2058 * we're putting this item.
2060 new_fi->length = n + length;
2065 * XXX - currently, string values are null-
2066 * terminated, so a "zero-padded" string
2067 * isn't special. If we represent string
2068 * values as something that includes a counted
2069 * array of bytes, we'll need to strip
2072 proto_tree_set_string_tvb(new_fi, tvb, start, length,
2076 case FT_ABSOLUTE_TIME:
2078 * Absolute times can be in any of a number of
2079 * formats, and they can be big-endian or
2082 * Historically FT_TIMEs were only timespecs;
2083 * the only question was whether they were stored
2084 * in big- or little-endian format.
2086 * For backwards compatibility, we interpret an
2087 * encoding of 1 as meaning "little-endian timespec",
2088 * so that passing TRUE is interpreted as that.
2090 if (encoding == TRUE)
2091 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2093 if (length != 8 && length != 4) {
2094 length_error = length < 4 ? TRUE : FALSE;
2095 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2098 get_time_value(tvb, start, length, encoding, &time_stamp, FALSE);
2100 proto_tree_set_time(new_fi, &time_stamp);
2103 case FT_RELATIVE_TIME:
2105 * Relative times can be in any of a number of
2106 * formats, and they can be big-endian or
2109 * Historically FT_TIMEs were only timespecs;
2110 * the only question was whether they were stored
2111 * in big- or little-endian format.
2113 * For backwards compatibility, we interpret an
2114 * encoding of 1 as meaning "little-endian timespec",
2115 * so that passing TRUE is interpreted as that.
2117 if (encoding == TRUE)
2118 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2120 if (length != 8 && length != 4) {
2121 length_error = length < 4 ? TRUE : FALSE;
2122 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2125 get_time_value(tvb, start, length, encoding, &time_stamp, TRUE);
2127 proto_tree_set_time(new_fi, &time_stamp);
2131 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2132 new_fi->hfinfo->type,
2133 ftype_name(new_fi->hfinfo->type));
2134 DISSECTOR_ASSERT_NOT_REACHED();
2137 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2139 /* Don't add new node to proto_tree until now so that any exceptions
2140 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2141 /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2142 * to know which item caused exception? */
2143 pi = proto_tree_add_node(tree, new_fi);
2149 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2150 const gint start, gint length, const guint encoding,
2153 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2157 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2159 switch (hfinfo->type){
2166 DISSECTOR_ASSERT_NOT_REACHED();
2169 /* length validation for native number encoding caught by get_uint_value() */
2170 /* length has to be -1 or > 0 regardless of encoding */
2171 if (length < -1 || length == 0)
2172 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2173 "Invalid length %d passed to proto_tree_add_item_ret_int",
2176 if (encoding & ENC_STRING) {
2177 REPORT_DISSECTOR_BUG("wrong encoding");
2179 /* I believe it's ok if this is called with a NULL tree */
2180 value = get_int_value(tree, tvb, start, length, encoding);
2185 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2187 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2192 proto_tree_set_int(new_fi, value);
2195 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2197 return proto_tree_add_node(tree, new_fi);
2201 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2202 const gint start, gint length, const guint encoding,
2205 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2209 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2211 switch (hfinfo->type){
2218 DISSECTOR_ASSERT_NOT_REACHED();
2221 /* length validation for native number encoding caught by get_uint_value() */
2222 /* length has to be -1 or > 0 regardless of encoding */
2223 if (length < -1 || length == 0)
2224 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2225 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2228 if (encoding & ENC_STRING) {
2229 REPORT_DISSECTOR_BUG("wrong encoding");
2231 /* I believe it's ok if this is called with a NULL tree */
2232 value = get_uint_value(tree, tvb, start, length, encoding);
2237 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2239 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2244 proto_tree_set_uint(new_fi, value);
2247 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2249 return proto_tree_add_node(tree, new_fi);
2254 * Validates that field length bytes are available starting from
2255 * start (pos/neg). Throws an exception if they aren't.
2258 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2259 gint start, gint length)
2266 if (hfinfo->type == FT_STRINGZ) {
2267 /* If we're fetching until the end of the TVB, only validate
2268 * that the offset is within range.
2274 tvb_ensure_bytes_exist(tvb, start, size);
2277 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2278 and returns proto_item* */
2280 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
2281 const guint encoding)
2284 header_field_info *hfinfo;
2289 /* We can't fake it just yet. We have to advance the cursor
2290 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo); */
2292 offset = ptvc->offset;
2293 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2294 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
2295 ptvc->offset += length;
2296 if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
2298 * The length of the rest of the item is in the first N
2299 * bytes of the item.
2301 n = get_uint_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
2305 test_length(hfinfo, ptvc->tvb, offset, item_length);
2307 /* Coast clear. Try and fake it */
2308 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2310 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2312 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2313 offset, length, encoding);
2316 /* Add an item to a proto_tree, using the text label registered to that item;
2317 the item is extracted from the tvbuff handed to it. */
2319 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
2320 const gint start, gint length, const guint encoding)
2325 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2327 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2328 test_length(hfinfo, tvb, start, item_length);
2330 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2332 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2337 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2341 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2342 const gint start, gint length, const guint encoding)
2344 register header_field_info *hfinfo;
2346 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2347 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
2350 /* which FT_ types can use proto_tree_add_bytes_item() */
2351 static inline gboolean
2352 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
2354 return (type == FT_BYTES ||
2355 type == FT_UINT_BYTES ||
2357 type == FT_REL_OID ||
2358 type == FT_SYSTEM_ID );
2361 /* Note: this does no validation that the byte array of an FT_OID or
2362 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
2363 so I think it's ok to continue not validating it?
2366 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2367 const gint start, gint length, const guint encoding,
2368 GByteArray *retval, gint *endoff, gint *err)
2371 GByteArray *bytes = retval;
2372 GByteArray *created_bytes = NULL;
2375 header_field_info *hfinfo;
2376 gboolean generate = (bytes || tree) ? TRUE : FALSE;
2378 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2380 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2382 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
2383 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
2385 /* length has to be -1 or > 0 regardless of encoding */
2386 /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
2387 if (length < -1 || length == 0) {
2388 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2389 "Invalid length %d passed to proto_tree_add_bytes_item for %s",
2390 length, ftype_name(hfinfo->type)));
2393 if (encoding & ENC_STR_NUM) {
2394 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
2397 if (generate && (encoding & ENC_STR_HEX)) {
2398 if (hfinfo->type == FT_UINT_BYTES) {
2399 /* can't decode FT_UINT_BYTES from strings */
2400 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
2401 "FT_UINT_BYTES type, but as ENC_STR_HEX");
2405 /* caller doesn't care about return value, but we need it to
2406 call tvb_get_string_bytes() and set the tree later */
2407 bytes = created_bytes = g_byte_array_new();
2410 /* bytes might be NULL after this, but can't add expert error until later */
2411 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
2413 /* grab the errno now before it gets overwritten */
2416 else if (generate) {
2417 tvb_ensure_bytes_exist(tvb, start, length);
2420 /* caller doesn't care about return value, but we need it to
2421 call tvb_get_string_bytes() and set the tree later */
2422 bytes = created_bytes = g_byte_array_new();
2425 if (hfinfo->type == FT_UINT_BYTES) {
2426 n = length; /* n is now the "header" length */
2427 length = get_uint_value(tree, tvb, start, n, encoding);
2428 /* length is now the value's length; only store the value in the array */
2429 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
2431 else if (length > 0) {
2432 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
2436 *endoff = start + n + length;
2439 if (err) *err = saved_err;
2441 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
2444 g_byte_array_free(created_bytes, TRUE);
2445 created_bytes = NULL;
2449 /* n will be zero except when it's a FT_UINT_BYTES */
2450 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
2455 if (encoding & ENC_STRING) {
2456 if (saved_err == ERANGE)
2457 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2458 else if (!bytes || saved_err != 0)
2459 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2462 proto_tree_set_bytes_gbytearray(new_fi, bytes);
2464 proto_tree_set_bytes(new_fi, NULL, 0);
2467 g_byte_array_free(created_bytes, TRUE);
2470 /* n will be zero except when it's a FT_UINT_BYTES */
2471 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
2474 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2477 return proto_tree_add_node(tree, new_fi);
2482 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2483 const gint start, gint length, const guint encoding,
2484 nstime_t *retval, gint *endoff, gint *err)
2487 nstime_t time_stamp;
2489 header_field_info *hfinfo;
2491 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2493 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2495 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
2497 /* length has to be -1 or > 0 regardless of encoding */
2498 if (length < -1 || length == 0) {
2499 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2500 "Invalid length %d passed to proto_tree_add_time_item", length));
2503 time_stamp.secs = 0;
2504 time_stamp.nsecs = 0;
2506 if (encoding & ENC_STR_TIME_MASK) {
2507 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
2508 /* grab the errno now before it gets overwritten */
2512 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
2514 if (length != 8 && length != 4) {
2515 const gboolean length_error = length < 4 ? TRUE : FALSE;
2517 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2519 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2522 tvb_ensure_bytes_exist(tvb, start, length);
2523 get_time_value(tvb, start, length, encoding, &time_stamp, is_relative);
2524 if (endoff) *endoff = length;
2527 if (err) *err = saved_err;
2530 retval->secs = time_stamp.secs;
2531 retval->nsecs = time_stamp.nsecs;
2534 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2536 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2541 proto_tree_set_time(new_fi, &time_stamp);
2543 if (encoding & ENC_STRING) {
2544 if (saved_err == ERANGE)
2545 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2546 else if (saved_err == EDOM)
2547 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2551 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2554 return proto_tree_add_node(tree, new_fi);
2557 /* Add a FT_NONE to a proto_tree */
2559 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
2560 const gint start, gint length, const char *format,
2565 header_field_info *hfinfo;
2567 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2569 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
2571 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2573 TRY_TO_FAKE_THIS_REPR(pi);
2575 va_start(ap, format);
2576 proto_tree_set_representation(pi, format, ap);
2579 /* no value to set for FT_NONE */
2583 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
2584 * offset, and returns proto_item* */
2586 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
2587 const guint encoding)
2591 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
2597 /* Advance the ptvcursor's offset within its tvbuff without
2598 * adding anything to the proto_tree. */
2600 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
2602 ptvc->offset += length;
2607 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
2609 fvalue_set_tvbuff(&fi->value, tvb);
2612 /* Add a FT_PROTOCOL to a proto_tree */
2614 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2615 gint start, gint length, const char *format, ...)
2619 header_field_info *hfinfo;
2621 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2623 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
2625 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2627 proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length)));
2629 TRY_TO_FAKE_THIS_REPR(pi);
2631 va_start(ap, format);
2632 proto_tree_set_representation(pi, format, ap);
2638 /* Add a FT_BYTES to a proto_tree */
2640 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2641 gint length, const guint8 *start_ptr)
2644 header_field_info *hfinfo;
2647 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2648 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2649 test_length(hfinfo, tvb, start, item_length);
2651 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2653 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2655 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2656 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
2661 /* Add a FT_BYTES to a proto_tree */
2663 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2664 gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
2667 header_field_info *hfinfo;
2670 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2671 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length);
2672 test_length(hfinfo, tvb, start, item_length);
2674 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2676 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2678 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
2679 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
2685 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2686 gint start, gint length,
2687 const guint8 *start_ptr,
2688 const char *format, ...)
2692 header_field_info *hfinfo;
2695 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2696 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2697 test_length(hfinfo, tvb, start, item_length);
2699 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2702 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2705 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2706 tvb_get_ptr(tvb, start, length));
2708 va_start(ap, format);
2709 proto_tree_set_representation_value(pi, format, ap);
2716 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2717 gint start, gint length, const guint8 *start_ptr,
2718 const char *format, ...)
2722 header_field_info *hfinfo;
2725 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2726 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2727 test_length(hfinfo, tvb, start, item_length);
2729 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2732 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2735 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2736 tvb_get_ptr(tvb, start, length));
2738 TRY_TO_FAKE_THIS_REPR(pi);
2740 va_start(ap, format);
2741 proto_tree_set_representation(pi, format, ap);
2748 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
2752 DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
2754 bytes = g_byte_array_new();
2756 g_byte_array_append(bytes, start_ptr, length);
2758 fvalue_set_byte_array(&fi->value, bytes);
2763 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
2765 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
2769 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
2773 DISSECTOR_ASSERT(value != NULL);
2775 bytes = byte_array_dup(value);
2777 fvalue_set_byte_array(&fi->value, bytes);
2780 /* Add a FT_*TIME to a proto_tree */
2782 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2783 gint length, const nstime_t *value_ptr)
2786 header_field_info *hfinfo;
2788 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2790 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
2792 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2793 proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
2799 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2800 gint start, gint length, nstime_t *value_ptr,
2801 const char *format, ...)
2806 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
2808 va_start(ap, format);
2809 proto_tree_set_representation_value(pi, format, ap);
2817 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2818 gint start, gint length, nstime_t *value_ptr,
2819 const char *format, ...)
2824 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
2826 TRY_TO_FAKE_THIS_REPR(pi);
2828 va_start(ap, format);
2829 proto_tree_set_representation(pi, format, ap);
2836 /* Set the FT_*TIME value */
2838 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
2840 DISSECTOR_ASSERT(value_ptr != NULL);
2842 fvalue_set_time(&fi->value, value_ptr);
2845 /* Add a FT_IPXNET to a proto_tree */
2847 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2848 gint length, guint32 value)
2851 header_field_info *hfinfo;
2853 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2855 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
2857 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2858 proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
2864 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2865 gint start, gint length, guint32 value,
2866 const char *format, ...)
2871 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
2873 va_start(ap, format);
2874 proto_tree_set_representation_value(pi, format, ap);
2882 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2883 gint start, gint length, guint32 value,
2884 const char *format, ...)
2889 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
2891 TRY_TO_FAKE_THIS_REPR(pi);
2893 va_start(ap, format);
2894 proto_tree_set_representation(pi, format, ap);
2901 /* Set the FT_IPXNET value */
2903 proto_tree_set_ipxnet(field_info *fi, guint32 value)
2905 fvalue_set_uinteger(&fi->value, value);
2908 /* Add a FT_IPv4 to a proto_tree */
2910 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2911 gint length, guint32 value)
2914 header_field_info *hfinfo;
2916 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2918 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
2920 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2921 proto_tree_set_ipv4(PNODE_FINFO(pi), value);
2927 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2928 gint start, gint length, guint32 value,
2929 const char *format, ...)
2934 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
2936 va_start(ap, format);
2937 proto_tree_set_representation_value(pi, format, ap);
2945 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2946 gint start, gint length, guint32 value,
2947 const char *format, ...)
2952 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
2954 TRY_TO_FAKE_THIS_REPR(pi);
2956 va_start(ap, format);
2957 proto_tree_set_representation(pi, format, ap);
2964 /* Set the FT_IPv4 value */
2966 proto_tree_set_ipv4(field_info *fi, guint32 value)
2968 fvalue_set_uinteger(&fi->value, value);
2971 /* Add a FT_IPv6 to a proto_tree */
2973 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2974 gint length, const struct e_in6_addr *value_ptr)
2977 header_field_info *hfinfo;
2979 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2981 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
2983 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2984 proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
2990 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2991 gint start, gint length,
2992 const struct e_in6_addr *value_ptr,
2993 const char *format, ...)
2998 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3000 va_start(ap, format);
3001 proto_tree_set_representation_value(pi, format, ap);
3009 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3010 gint start, gint length,
3011 const struct e_in6_addr *value_ptr,
3012 const char *format, ...)
3017 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3019 TRY_TO_FAKE_THIS_REPR(pi);
3021 va_start(ap, format);
3022 proto_tree_set_representation(pi, format, ap);
3029 /* Set the FT_IPv6 value */
3031 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
3033 DISSECTOR_ASSERT(value_ptr != NULL);
3034 fvalue_set_bytes(&fi->value, value_ptr);
3038 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3040 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
3043 /* Set the FT_FCWWN value */
3045 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
3047 DISSECTOR_ASSERT(value_ptr != NULL);
3048 fvalue_set_bytes(&fi->value, value_ptr);
3052 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3054 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
3057 /* Add a FT_GUID to a proto_tree */
3059 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3060 gint length, const e_guid_t *value_ptr)
3063 header_field_info *hfinfo;
3065 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3067 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
3069 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3070 proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
3076 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3077 gint start, gint length,
3078 const e_guid_t *value_ptr,
3079 const char *format, ...)
3084 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3086 va_start(ap, format);
3087 proto_tree_set_representation_value(pi, format, ap);
3095 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3096 gint start, gint length, const e_guid_t *value_ptr,
3097 const char *format, ...)
3102 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3104 TRY_TO_FAKE_THIS_REPR(pi);
3106 va_start(ap, format);
3107 proto_tree_set_representation(pi, format, ap);
3114 /* Set the FT_GUID value */
3116 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
3118 DISSECTOR_ASSERT(value_ptr != NULL);
3119 fvalue_set_guid(&fi->value, value_ptr);
3123 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
3124 const guint encoding)
3128 tvb_get_guid(tvb, start, &guid, encoding);
3129 proto_tree_set_guid(fi, &guid);
3132 /* Add a FT_OID to a proto_tree */
3134 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3135 gint length, const guint8* value_ptr)
3138 header_field_info *hfinfo;
3140 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3142 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
3144 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3145 proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
3151 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3152 gint start, gint length,
3153 const guint8* value_ptr,
3154 const char *format, ...)
3159 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3161 va_start(ap, format);
3162 proto_tree_set_representation_value(pi, format, ap);
3170 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3171 gint start, gint length, const guint8* value_ptr,
3172 const char *format, ...)
3177 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3179 TRY_TO_FAKE_THIS_REPR(pi);
3181 va_start(ap, format);
3182 proto_tree_set_representation(pi, format, ap);
3189 /* Set the FT_OID value */
3191 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
3195 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3197 bytes = g_byte_array_new();
3199 g_byte_array_append(bytes, value_ptr, length);
3201 fvalue_set_byte_array(&fi->value, bytes);
3205 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3207 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
3210 /* Set the FT_SYSTEM_ID value */
3212 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
3216 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3218 bytes = g_byte_array_new();
3220 g_byte_array_append(bytes, value_ptr, length);
3222 fvalue_set_byte_array(&fi->value, bytes);
3226 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3228 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
3231 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
3232 * own copy of string, and frees it when the proto_tree is destroyed. */
3234 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3235 gint length, const char* value)
3238 header_field_info *hfinfo;
3240 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3242 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
3244 if (hfinfo->display == STR_UNICODE) {
3245 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
3248 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3249 DISSECTOR_ASSERT(length >= 0);
3250 proto_tree_set_string(PNODE_FINFO(pi), value);
3256 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3257 gint start, gint length, const char* value,
3264 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3266 va_start(ap, format);
3267 proto_tree_set_representation_value(pi, format, ap);
3275 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3276 gint start, gint length, const char* value,
3277 const char *format, ...)
3282 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3284 TRY_TO_FAKE_THIS_REPR(pi);
3286 va_start(ap, format);
3287 proto_tree_set_representation(pi, format, ap);
3294 /* Appends string data to a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD,
3295 * allowing progressive field info update instead of only updating the
3296 * representation as does proto_item_append_text()
3298 /* NOTE: this function will break with the TRY_TO_FAKE_THIS_ITEM()
3299 * speed optimization.
3300 * Currently only WSP use this function so it is not that bad but try to
3301 * avoid using this one if possible.
3302 * IF you must use this function you MUST also disable the
3303 * TRY_TO_FAKE_THIS_ITEM() optimization for your dissector/function
3304 * using proto_item_append_string().
3305 * Do that by faking that the tree is visible by calling
3306 * proto_tree_set_visible(tree, TRUE) (see packet-wsp.c)
3307 * BEFORE you create the item you are later going to use
3308 * proto_item_append_string() on.
3311 proto_item_append_string(proto_item *pi, const char *str)
3314 header_field_info *hfinfo;
3315 const gchar *old_str, *new_str;
3322 fi = PITEM_FINFO(pi);
3323 DISSECTOR_ASSERT_HINT(fi, "proto_tree_set_visible(tree, TRUE) should have been called previously");
3325 hfinfo = fi->hfinfo;
3326 if (hfinfo->type == FT_PROTOCOL) {
3327 /* TRY_TO_FAKE_THIS_ITEM() speed optimization: silently skip */
3330 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
3331 old_str = (guint8 *)fvalue_get(&fi->value);
3332 if (old_str && old_str[0])
3333 new_str = wmem_strconcat(wmem_packet_scope(), old_str, str, NULL);
3336 fvalue_set_string(&fi->value, new_str);
3339 /* Set the FT_STRING value */
3341 proto_tree_set_string(field_info *fi, const char* value)
3344 fvalue_set_string(&fi->value, value);
3346 fvalue_set_string(&fi->value, "[ Null ]");
3351 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding)
3356 length = tvb_ensure_captured_length_remaining(tvb, start);
3359 string = tvb_get_string_enc(wmem_packet_scope(), tvb, start, length, encoding);
3360 proto_tree_set_string(fi, string);
3363 /* Set the FT_AX25 value */
3365 proto_tree_set_ax25(field_info *fi, const guint8* value)
3367 fvalue_set_bytes(&fi->value, value);
3371 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3373 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
3376 /* Set the FT_VINES value */
3378 proto_tree_set_vines(field_info *fi, const guint8* value)
3380 fvalue_set_bytes(&fi->value, value);
3384 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3386 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
3389 /* Add a FT_ETHER to a proto_tree */
3391 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3392 gint length, const guint8* value)
3395 header_field_info *hfinfo;
3397 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3399 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
3401 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3402 proto_tree_set_ether(PNODE_FINFO(pi), value);
3408 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3409 gint start, gint length, const guint8* value,
3410 const char *format, ...)
3415 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3417 va_start(ap, format);
3418 proto_tree_set_representation_value(pi, format, ap);
3426 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3427 gint start, gint length, const guint8* value,
3428 const char *format, ...)
3433 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3435 TRY_TO_FAKE_THIS_REPR(pi);
3437 va_start(ap, format);
3438 proto_tree_set_representation(pi, format, ap);
3445 /* Set the FT_ETHER value */
3447 proto_tree_set_ether(field_info *fi, const guint8* value)
3449 fvalue_set_bytes(&fi->value, value);
3453 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3455 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
3458 /* Add a FT_BOOLEAN to a proto_tree */
3460 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3461 gint length, guint32 value)
3464 header_field_info *hfinfo;
3466 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3468 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3470 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3471 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3477 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
3478 tvbuff_t *tvb, gint start, gint length,
3479 guint32 value, const char *format, ...)
3484 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3486 va_start(ap, format);
3487 proto_tree_set_representation_value(pi, format, ap);
3495 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3496 gint start, gint length, guint32 value,
3497 const char *format, ...)
3502 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3504 TRY_TO_FAKE_THIS_REPR(pi);
3506 va_start(ap, format);
3507 proto_tree_set_representation(pi, format, ap);
3515 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3516 gint length, guint64 value)
3519 header_field_info *hfinfo;
3521 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3523 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3525 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3526 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3531 /* Set the FT_BOOLEAN value */
3533 proto_tree_set_boolean(field_info *fi, guint64 value)
3535 proto_tree_set_uint64(fi, value);
3538 /* Generate, into "buf", a string showing the bits of a bitfield.
3539 Return a pointer to the character after that string. */
3540 /*XXX this needs a buf_len check */
3542 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3550 bit = G_GUINT64_CONSTANT(1) << (width - 1);
3553 /* This bit is part of the field. Show its value. */
3559 /* This bit is not part of the field. */
3574 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3578 p = other_decode_bitfield_value(buf, val, mask, width);
3579 p = g_stpcpy(p, " = ");
3584 /* Add a FT_FLOAT to a proto_tree */
3586 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3587 gint length, float value)
3590 header_field_info *hfinfo;
3592 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3594 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
3596 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3597 proto_tree_set_float(PNODE_FINFO(pi), value);
3603 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3604 gint start, gint length, float value,
3605 const char *format, ...)
3610 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3612 va_start(ap, format);
3613 proto_tree_set_representation_value(pi, format, ap);
3621 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3622 gint start, gint length, float value,
3623 const char *format, ...)
3628 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3630 TRY_TO_FAKE_THIS_REPR(pi);
3632 va_start(ap, format);
3633 proto_tree_set_representation(pi, format, ap);
3640 /* Set the FT_FLOAT value */
3642 proto_tree_set_float(field_info *fi, float value)
3644 fvalue_set_floating(&fi->value, value);
3647 /* Add a FT_DOUBLE to a proto_tree */
3649 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3650 gint length, double value)
3653 header_field_info *hfinfo;
3655 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3657 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
3659 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3660 proto_tree_set_double(PNODE_FINFO(pi), value);
3666 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3667 gint start, gint length, double value,
3668 const char *format, ...)
3673 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3675 va_start(ap, format);
3676 proto_tree_set_representation_value(pi, format, ap);
3684 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3685 gint start, gint length, double value,
3686 const char *format, ...)
3691 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3693 TRY_TO_FAKE_THIS_REPR(pi);
3695 va_start(ap, format);
3696 proto_tree_set_representation(pi, format, ap);
3703 /* Set the FT_DOUBLE value */
3705 proto_tree_set_double(field_info *fi, double value)
3707 fvalue_set_floating(&fi->value, value);
3710 /* Add FT_UINT{8,16,24,32} to a proto_tree */
3712 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3713 gint length, guint32 value)
3715 proto_item *pi = NULL;
3716 header_field_info *hfinfo;
3718 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3720 switch (hfinfo->type) {
3726 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3727 proto_tree_set_uint(PNODE_FINFO(pi), value);
3731 DISSECTOR_ASSERT_NOT_REACHED();
3738 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3739 gint start, gint length, guint32 value,
3740 const char *format, ...)
3745 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3747 va_start(ap, format);
3748 proto_tree_set_representation_value(pi, format, ap);
3756 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3757 gint start, gint length, guint32 value,
3758 const char *format, ...)
3763 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3765 TRY_TO_FAKE_THIS_REPR(pi);
3767 va_start(ap, format);
3768 proto_tree_set_representation(pi, format, ap);
3775 /* Set the FT_UINT{8,16,24,32} value */
3777 proto_tree_set_uint(field_info *fi, guint32 value)
3779 header_field_info *hfinfo;
3782 hfinfo = fi->hfinfo;
3785 if (hfinfo->bitmask) {
3786 /* Mask out irrelevant portions */
3787 integer &= (guint32)(hfinfo->bitmask);
3790 integer >>= hfinfo_bitshift(hfinfo);
3793 fvalue_set_uinteger(&fi->value, integer);
3796 /* Add FT_UINT{40,48,56,64} to a proto_tree */
3798 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3799 gint length, guint64 value)
3801 proto_item *pi = NULL;
3802 header_field_info *hfinfo;
3804 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3806 switch (hfinfo->type) {
3812 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3813 proto_tree_set_uint64(PNODE_FINFO(pi), value);
3817 DISSECTOR_ASSERT_NOT_REACHED();
3824 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3825 gint start, gint length, guint64 value,
3826 const char *format, ...)
3831 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
3833 va_start(ap, format);
3834 proto_tree_set_representation_value(pi, format, ap);
3842 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3843 gint start, gint length, guint64 value,
3844 const char *format, ...)
3849 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
3851 TRY_TO_FAKE_THIS_REPR(pi);
3853 va_start(ap, format);
3854 proto_tree_set_representation(pi, format, ap);
3861 /* Set the FT_UINT{40,48,56,64} value */
3863 proto_tree_set_uint64(field_info *fi, guint64 value)
3865 header_field_info *hfinfo;
3869 hfinfo = fi->hfinfo;
3872 if (hfinfo->bitmask) {
3873 /* Mask out irrelevant portions */
3874 integer &= hfinfo->bitmask;
3877 integer >>= hfinfo_bitshift(hfinfo);
3879 no_of_bits = ws_count_ones(hfinfo->bitmask);
3880 integer = ws_sign_ext64(integer, no_of_bits);
3883 fvalue_set_uinteger64(&fi->value, integer);
3886 /* Add FT_INT{8,16,24,32} to a proto_tree */
3888 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3889 gint length, gint32 value)
3891 proto_item *pi = NULL;
3892 header_field_info *hfinfo;
3894 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3896 switch (hfinfo->type) {
3901 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3902 proto_tree_set_int(PNODE_FINFO(pi), value);
3906 DISSECTOR_ASSERT_NOT_REACHED();
3913 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3914 gint start, gint length, gint32 value,
3915 const char *format, ...)
3920 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
3922 va_start(ap, format);
3923 proto_tree_set_representation_value(pi, format, ap);
3931 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3932 gint start, gint length, gint32 value,
3933 const char *format, ...)
3938 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
3940 TRY_TO_FAKE_THIS_REPR(pi);
3942 va_start(ap, format);
3943 proto_tree_set_representation(pi, format, ap);
3950 /* Set the FT_INT{8,16,24,32} value */
3952 proto_tree_set_int(field_info *fi, gint32 value)
3954 header_field_info *hfinfo;
3958 hfinfo = fi->hfinfo;
3959 integer = (guint32) value;
3961 if (hfinfo->bitmask) {
3962 /* Mask out irrelevant portions */
3963 integer &= (guint32)(hfinfo->bitmask);
3966 integer >>= hfinfo_bitshift(hfinfo);
3968 no_of_bits = ws_count_ones(hfinfo->bitmask);
3969 integer = ws_sign_ext32(integer, no_of_bits);
3972 fvalue_set_sinteger(&fi->value, integer);
3975 /* Add FT_INT{40,48,56,64} to a proto_tree */
3977 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3978 gint length, gint64 value)
3980 proto_item *pi = NULL;
3981 header_field_info *hfinfo;
3983 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3985 switch (hfinfo->type) {
3990 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3991 proto_tree_set_int64(PNODE_FINFO(pi), value);
3995 DISSECTOR_ASSERT_NOT_REACHED();
4002 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4003 gint start, gint length, gint64 value,
4004 const char *format, ...)
4009 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4011 va_start(ap, format);
4012 proto_tree_set_representation_value(pi, format, ap);
4019 /* Set the FT_INT{40,48,56,64} value */
4021 proto_tree_set_int64(field_info *fi, gint64 value)
4023 header_field_info *hfinfo;
4027 hfinfo = fi->hfinfo;
4030 if (hfinfo->bitmask) {
4031 /* Mask out irrelevant portions */
4032 integer &= hfinfo->bitmask;
4035 integer >>= hfinfo_bitshift(hfinfo);
4037 no_of_bits = ws_count_ones(hfinfo->bitmask);
4038 integer = ws_sign_ext64(integer, no_of_bits);
4041 fvalue_set_sinteger64(&fi->value, integer);
4045 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4046 gint start, gint length, gint64 value,
4047 const char *format, ...)
4052 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4054 TRY_TO_FAKE_THIS_REPR(pi);
4056 va_start(ap, format);
4057 proto_tree_set_representation(pi, format, ap);
4064 /* Add a FT_EUI64 to a proto_tree */
4066 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4067 gint length, const guint64 value)
4070 header_field_info *hfinfo;
4072 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4074 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
4076 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4077 proto_tree_set_eui64(PNODE_FINFO(pi), value);
4083 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4084 gint start, gint length, const guint64 value,
4085 const char *format, ...)
4090 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4092 va_start(ap, format);
4093 proto_tree_set_representation_value(pi, format, ap);
4101 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4102 gint start, gint length, const guint64 value,
4103 const char *format, ...)
4108 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4110 TRY_TO_FAKE_THIS_REPR(pi);
4112 va_start(ap, format);
4113 proto_tree_set_representation(pi, format, ap);
4120 /* Set the FT_EUI64 value */
4122 proto_tree_set_eui64(field_info *fi, const guint64 value)
4124 fvalue_set_uinteger64(&fi->value, value);
4127 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
4131 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
4133 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
4137 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
4139 proto_tree_add_node(proto_tree *tree, field_info *fi)
4141 proto_node *pnode, *tnode, *sibling;
4145 * Make sure "tree" is ready to have subtrees under it, by
4146 * checking whether it's been given an ett_ value.
4148 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
4149 * node of the protocol tree. That node is not displayed,
4150 * so it doesn't need an ett_ value to remember whether it
4154 tfi = PNODE_FINFO(tnode);
4155 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
4156 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4157 "\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
4158 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
4159 /* XXX - is it safe to continue here? */
4162 pnode = wmem_new(PNODE_POOL(tree), proto_node);
4163 PROTO_NODE_INIT(pnode);
4164 pnode->parent = tnode;
4165 PNODE_FINFO(pnode) = fi;
4166 pnode->tree_data = PTREE_DATA(tree);
4168 if (tnode->last_child != NULL) {
4169 sibling = tnode->last_child;
4170 DISSECTOR_ASSERT(sibling->next == NULL);
4171 sibling->next = pnode;
4173 tnode->first_child = pnode;
4174 tnode->last_child = pnode;
4176 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
4178 return (proto_item *)pnode;
4182 /* Generic way to allocate field_info and add to proto_tree.
4183 * Sets *pfi to address of newly-allocated field_info struct */
4185 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
4192 get_hfi_length(hfinfo, tvb, start, length, &item_length);
4193 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4194 pi = proto_tree_add_node(tree, fi);
4201 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
4204 gint length_remaining;
4207 * We only allow a null tvbuff if the item has a zero length,
4208 * i.e. if there's no data backing it.
4210 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
4213 * XXX - in some protocols, there are 32-bit unsigned length
4214 * fields, so lengths in protocol tree and tvbuff routines
4215 * should really be unsigned. We should have, for those
4216 * field types for which "to the end of the tvbuff" makes sense,
4217 * additional routines that take no length argument and
4218 * add fields that run to the end of the tvbuff.
4220 if (*length == -1) {
4222 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
4223 * FT_STRINGZPAD fields, a length of -1 means "set the
4224 * length to what remains in the tvbuff".
4226 * The assumption is either that
4228 * 1) the length of the item can only be determined
4229 * by dissection (typically true of items with
4230 * subitems, which are probably FT_NONE or
4235 * 2) if the tvbuff is "short" (either due to a short
4236 * snapshot length or due to lack of reassembly of
4237 * fragments/segments/whatever), we want to display
4238 * what's available in the field (probably FT_BYTES
4239 * or FT_STRING) and then throw an exception later
4243 * 3) the field is defined to be "what's left in the
4246 * so we set the length to what remains in the tvbuff so
4247 * that, if we throw an exception while dissecting, it
4248 * has what is probably the right value.
4250 * For FT_STRINGZ, it means "the string is null-terminated,
4251 * not null-padded; set the length to the actual length
4252 * of the string", and if the tvbuff if short, we just
4253 * throw an exception.
4255 * It's not valid for any other type of field. For those
4256 * fields, we treat -1 the same way we treat other
4257 * negative values - we assume the length is a Really
4258 * Big Positive Number, and throw a ReportedBoundsError
4259 * exception, under the assumption that the Really Big
4260 * Length would run past the end of the packet.
4262 switch (hfinfo->type) {
4270 * We allow FT_PROTOCOLs to be zero-length -
4271 * for example, an ONC RPC NULL procedure has
4272 * neither arguments nor reply, so the
4273 * payload for that protocol is empty.
4275 * We also allow the others to be zero-length -
4276 * because that's the way the code has been for a
4279 * However, we want to ensure that the start
4280 * offset is not *past* the byte past the end
4281 * of the tvbuff: we throw an exception in that
4284 *length = tvb_ensure_captured_length_remaining(tvb, start);
4285 DISSECTOR_ASSERT(*length >= 0);
4290 * Leave the length as -1, so our caller knows
4296 THROW(ReportedBoundsError);
4297 DISSECTOR_ASSERT_NOT_REACHED();
4299 *item_length = *length;
4301 *item_length = *length;
4302 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
4304 * These types are for interior nodes of the
4305 * tree, and don't have data associated with
4306 * them; if the length is negative (XXX - see
4307 * above) or goes past the end of the tvbuff,
4308 * cut it short at the end of the tvbuff.
4309 * That way, if this field is selected in
4310 * Wireshark, we don't highlight stuff past
4311 * the end of the data.
4313 /* XXX - what to do, if we don't have a tvb? */
4315 length_remaining = tvb_captured_length_remaining(tvb, start);
4316 if (*item_length < 0 ||
4317 (*item_length > 0 &&
4318 (length_remaining < *item_length)))
4319 *item_length = length_remaining;
4322 if (*item_length < 0) {
4323 THROW(ReportedBoundsError);
4329 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4330 const gint start, const gint item_length)
4334 FIELD_INFO_NEW(PNODE_POOL(tree), fi);
4336 fi->hfinfo = hfinfo;
4338 fi->start += (tvb)?tvb_raw_offset(tvb):0;
4339 fi->length = item_length;
4342 if (!PTREE_DATA(tree)->visible)
4343 FI_SET_FLAG(fi, FI_HIDDEN);
4344 fvalue_init(&fi->value, fi->hfinfo->type);
4347 /* add the data source tvbuff */
4348 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
4350 fi->appendix_start = 0;
4351 fi->appendix_length = 0;
4356 /* If the protocol tree is to be visible, set the representation of a
4357 proto_tree entry with the name of the field for the item and with
4358 the value formatted with the supplied printf-style format and
4361 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
4365 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
4366 * items string representation */
4367 if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
4369 field_info *fi = PITEM_FINFO(pi);
4370 header_field_info *hf;
4372 DISSECTOR_ASSERT(fi);
4376 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4377 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
4381 if (IS_FT_UINT(hf->type))
4382 val = fvalue_get_uinteger(&fi->value);
4384 val = fvalue_get_uinteger64(&fi->value);
4386 val <<= hfinfo_bitshift(hf);
4388 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_bitwidth(hf));
4389 ret = (int) (p - fi->rep->representation);
4392 /* put in the hf name */
4393 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
4395 /* If possible, Put in the value of the string */
4396 if (ret < ITEM_LABEL_LENGTH) {
4397 ret += g_vsnprintf(fi->rep->representation + ret,
4398 ITEM_LABEL_LENGTH - ret, format, ap);
4400 if (ret >= ITEM_LABEL_LENGTH) {
4401 /* Uh oh, we don't have enough room. Tell the user
4402 * that the field is truncated.
4404 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4409 /* If the protocol tree is to be visible, set the representation of a
4410 proto_tree entry with the representation formatted with the supplied
4411 printf-style format and argument list. */
4413 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
4415 int ret; /*tmp return value */
4416 field_info *fi = PITEM_FINFO(pi);
4418 DISSECTOR_ASSERT(fi);
4420 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4421 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4422 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
4424 if (ret >= ITEM_LABEL_LENGTH) {
4425 /* Uh oh, we don't have enough room. Tell the user
4426 * that the field is truncated.
4428 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4434 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
4436 switch (hfinfo->display) {
4438 return format_text(string, strlen(string));
4441 return format_text_wsp(string, strlen(string));
4444 /* XXX, format_unicode_text() */
4448 return format_text(string, strlen(string));
4452 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
4454 gsize res = g_strlcpy(dest, src, dest_size);
4456 if (res > dest_size)
4461 static header_field_info *
4462 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
4464 header_field_info *dup_hfinfo;
4466 if (hfinfo->same_name_prev_id == -1)
4468 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
4473 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
4475 g_free(last_field_name);
4476 last_field_name = NULL;
4478 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
4479 /* No hfinfo with the same name */
4480 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
4484 if (hfinfo->same_name_next) {
4485 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
4488 if (hfinfo->same_name_prev_id != -1) {
4489 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
4490 same_name_prev->same_name_next = hfinfo->same_name_next;
4491 if (!hfinfo->same_name_next) {
4492 /* It's always the latest added hfinfo which is stored in gpa_name_map */
4493 g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
4498 /* -------------------------- */
4500 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
4501 gchar *result, gchar *expr, const int size)
4507 struct e_in6_addr *ipv6;
4509 guint32 n_addr; /* network-order IPv4 address */
4511 const true_false_string *tfstring;
4513 int len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
4515 field_info *finfo = NULL;
4516 header_field_info* hfinfo;
4517 const gchar *abbrev = NULL;
4519 const char *hf_str_val;
4520 char number_buf[48];
4521 const char *number_out;
4527 g_assert(field_ids != NULL);
4528 while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
4529 field_id = *field_idx;
4530 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
4532 /* do we need to rewind ? */
4536 if (occurrence < 0) {
4537 /* Search other direction */
4538 while (hfinfo->same_name_prev_id != -1) {
4539 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
4544 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
4546 if (!finfos || !(len = g_ptr_array_len(finfos))) {
4547 if (occurrence < 0) {
4548 hfinfo = hfinfo->same_name_next;
4550 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4555 /* Are there enough occurrences of the field? */
4556 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
4557 if (occurrence < 0) {
4558 hfinfo = hfinfo->same_name_next;
4560 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4566 /* Calculate single index or set outer bounderies */
4567 if (occurrence < 0) {
4568 i = occurrence + len + prev_len;
4570 } else if (occurrence > 0) {
4571 i = occurrence - 1 - prev_len;
4578 prev_len += len; /* Count handled occurrences */
4581 finfo = (field_info *)g_ptr_array_index(finfos, i);
4583 if (offset_r && (offset_r < (size - 2)))
4584 result[offset_r++] = ',';
4586 if (offset_e && (offset_e < (size - 2)))
4587 expr[offset_e++] = ',';
4589 switch (hfinfo->type) {
4591 case FT_NONE: /* Nothing to add */
4592 if (offset_r == 0) {
4594 } else if (result[offset_r-1] == ',') {
4595 result[offset_r-1] = '\0';
4600 /* prevent multiple "yes" entries by setting result directly */
4601 g_strlcpy(result, "Yes", size);
4606 bytes = (guint8 *)fvalue_get(&finfo->value);
4608 switch(hfinfo->display)
4611 str = (char*)bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
4614 str = (char*)bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
4617 str = (char*)bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
4620 str = (char*)bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
4624 if (prefs.display_byte_fields_with_spaces)
4626 str = (char*)bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
4630 str = (char*)bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
4634 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
4635 wmem_free(NULL, str);
4638 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
4642 case FT_ABSOLUTE_TIME:
4643 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
4644 offset_r += protoo_strlcpy(result+offset_r,
4647 wmem_free(NULL, tmpbuf);
4650 case FT_RELATIVE_TIME:
4651 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
4652 offset_r += protoo_strlcpy(result+offset_r,
4655 wmem_free(NULL, tmpbuf);
4659 number = fvalue_get_uinteger(&finfo->value);
4660 tfstring = (const true_false_string *)&tfs_true_false;
4661 if (hfinfo->strings) {
4662 tfstring = (const struct true_false_string*) hfinfo->strings;
4664 offset_r += protoo_strlcpy(result+offset_r,
4666 tfstring->true_string :
4667 tfstring->false_string, size-offset_r);
4669 offset_e += protoo_strlcpy(expr+offset_e,
4670 number ? "1" : "0", size-offset_e);
4673 /* XXX - make these just FT_NUMBER? */
4684 number = IS_FT_INT(hfinfo->type) ?
4685 (guint32) fvalue_get_sinteger(&finfo->value) :
4686 fvalue_get_uinteger(&finfo->value);
4688 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
4689 gchar tmp[ITEM_LABEL_LENGTH];
4690 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
4692 DISSECTOR_ASSERT(fmtfunc);
4693 fmtfunc(tmp, number);
4695 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
4697 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
4698 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
4701 number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
4703 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
4706 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
4708 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
4711 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
4712 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
4714 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
4716 g_strlcpy(expr+offset_e, number_out, size-offset_e);
4719 offset_e = (int)strlen(expr);
4731 number64 = IS_FT_INT(hfinfo->type) ?
4732 (guint64) fvalue_get_sinteger64(&finfo->value) :
4733 fvalue_get_uinteger64(&finfo->value);
4735 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
4736 gchar tmp[ITEM_LABEL_LENGTH];
4737 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
4739 DISSECTOR_ASSERT(fmtfunc64);
4740 fmtfunc64(tmp, number64);
4741 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
4742 } else if (hfinfo->strings) {
4743 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
4746 number_out = hfinfo_number_value_format_display64(hfinfo, BASE_DEC, number_buf, number64);
4748 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
4751 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
4753 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
4756 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
4757 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
4759 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
4761 g_strlcpy(expr+offset_e, number_out, size-offset_e);
4764 offset_e = (int)strlen(expr);
4768 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
4769 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
4770 wmem_free(NULL, str);
4774 ipv4 = (ipv4_addr *)fvalue_get(&finfo->value);
4775 n_addr = ipv4_get_net_order_addr(ipv4);
4776 set_address (&addr, AT_IPv4, 4, &n_addr);
4777 address_to_str_buf(&addr, result+offset_r, size-offset_r);
4778 offset_r = (int)strlen(result);
4782 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
4783 set_address (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
4784 address_to_str_buf(&addr, result+offset_r, size-offset_r);
4785 offset_r = (int)strlen(result);
4789 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
4790 address_to_str_buf(&addr, result+offset_r, size-offset_r);
4791 offset_r = (int)strlen(result);
4795 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
4796 address_to_str_buf(&addr, result+offset_r, size-offset_r);
4797 offset_r = (int)strlen(result);
4801 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
4802 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
4803 wmem_free(NULL, str);
4807 bytes = (guint8 *)fvalue_get(&finfo->value);
4808 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
4809 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
4810 wmem_free(NULL, str);
4812 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
4813 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
4814 wmem_free(NULL, str);
4818 bytes = (guint8 *)fvalue_get(&finfo->value);
4819 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
4820 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
4821 wmem_free(NULL, str);
4823 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
4824 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
4825 wmem_free(NULL, str);
4829 bytes = (guint8 *)fvalue_get(&finfo->value);
4830 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
4831 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
4832 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
4833 wmem_free(NULL, str);
4837 g_snprintf(result+offset_r, size-offset_r,
4838 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
4839 offset_r = (int)strlen(result);
4843 g_snprintf(result+offset_r, size-offset_r,
4844 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
4845 offset_r = (int)strlen(result);
4850 case FT_UINT_STRING:
4852 bytes = (guint8 *)fvalue_get(&finfo->value);
4853 offset_r += protoo_strlcpy(result+offset_r,
4854 hfinfo_format_text(hfinfo, bytes),
4858 case FT_IPXNET: /*XXX really No column custom ?*/
4861 g_error("hfinfo->type %d (%s) not handled\n",
4863 ftype_name(hfinfo->type));
4864 DISSECTOR_ASSERT_NOT_REACHED();
4870 switch (hfinfo->type) {
4893 /* for these types, "expr" is filled in the loop above */
4897 /* for all others, just copy "result" to "expr" */
4898 g_strlcpy(expr, result, size);
4903 /* Store abbrev for return value */
4904 abbrev = hfinfo->abbrev;
4907 if (occurrence == 0) {
4908 /* Fetch next hfinfo with same name (abbrev) */
4909 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4916 return abbrev ? abbrev : "";
4920 /* Set text of proto_item after having already been created. */
4922 proto_item_set_text(proto_item *pi, const char *format, ...)
4924 field_info *fi = NULL;
4927 TRY_TO_FAKE_THIS_REPR_VOID(pi);
4929 fi = PITEM_FINFO(pi);
4934 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
4938 va_start(ap, format);
4939 proto_tree_set_representation(pi, format, ap);
4943 /* Append to text of proto_item after having already been created. */
4945 proto_item_append_text(proto_item *pi, const char *format, ...)
4947 field_info *fi = NULL;
4951 TRY_TO_FAKE_THIS_REPR_VOID(pi);
4953 fi = PITEM_FINFO(pi);
4958 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4960 * If we don't already have a representation,
4961 * generate the default representation.
4963 if (fi->rep == NULL) {
4964 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4965 proto_item_fill_label(fi, fi->rep->representation);
4968 curlen = strlen(fi->rep->representation);
4969 if (ITEM_LABEL_LENGTH > curlen) {
4970 va_start(ap, format);
4971 g_vsnprintf(fi->rep->representation + curlen,
4972 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
4978 /* Prepend to text of proto_item after having already been created. */
4980 proto_item_prepend_text(proto_item *pi, const char *format, ...)
4982 field_info *fi = NULL;
4983 char representation[ITEM_LABEL_LENGTH];
4986 TRY_TO_FAKE_THIS_REPR_VOID(pi);
4988 fi = PITEM_FINFO(pi);
4993 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4995 * If we don't already have a representation,
4996 * generate the default representation.
4998 if (fi->rep == NULL) {
4999 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5000 proto_item_fill_label(fi, representation);
5002 g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
5004 va_start(ap, format);
5005 g_vsnprintf(fi->rep->representation,
5006 ITEM_LABEL_LENGTH, format, ap);
5008 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
5013 proto_item_set_len(proto_item *pi, const gint length)
5017 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5019 fi = PITEM_FINFO(pi);
5023 DISSECTOR_ASSERT(length >= 0);
5024 fi->length = length;
5027 * You cannot just make the "len" field of a GByteArray
5028 * larger, if there's no data to back that length;
5029 * you can only make it smaller.
5031 if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
5032 fi->value.value.bytes->len = length;
5036 * Sets the length of the item based on its start and on the specified
5037 * offset, which is the offset past the end of the item; as the start
5038 * in the item is relative to the beginning of the data source tvbuff,
5039 * we need to pass in a tvbuff - the end offset is relative to the beginning
5043 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
5047 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5049 fi = PITEM_FINFO(pi);
5053 end += tvb_raw_offset(tvb);
5054 DISSECTOR_ASSERT(end >= fi->start);
5055 fi->length = end - fi->start;
5059 proto_item_get_len(const proto_item *pi)
5061 field_info *fi = PITEM_FINFO(pi);
5062 return fi ? fi->length : -1;
5066 proto_tree_create_root(packet_info *pinfo)
5070 /* Initialize the proto_node */
5071 pnode = g_slice_new(proto_tree);
5072 PROTO_NODE_INIT(pnode);
5073 pnode->parent = NULL;
5074 PNODE_FINFO(pnode) = NULL;
5075 pnode->tree_data = g_slice_new(tree_data_t);
5077 /* Make sure we can access pinfo everywhere */
5078 pnode->tree_data->pinfo = pinfo;
5080 /* Don't initialize the tree_data_t. Wait until we know we need it */
5081 pnode->tree_data->interesting_hfids = NULL;
5083 /* Set the default to FALSE so it's easier to
5084 * find errors; if we expect to see the protocol tree
5085 * but for some reason the default 'visible' is not
5086 * changed, then we'll find out very quickly. */
5087 pnode->tree_data->visible = FALSE;
5089 /* Make sure that we fake protocols (if possible) */
5090 pnode->tree_data->fake_protocols = TRUE;
5092 /* Keep track of the number of children */
5093 pnode->tree_data->count = 0;
5095 return (proto_tree *)pnode;
5099 /* "prime" a proto_tree with a single hfid that a dfilter
5100 * is interested in. */
5102 proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
5104 header_field_info *hfinfo;
5106 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
5107 /* this field is referenced by a filter so increase the refcount.
5108 also increase the refcount for the parent, i.e the protocol.
5110 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
5111 /* only increase the refcount if there is a parent.
5112 if this is a protocol and not a field then parent will be -1
5113 and there is no parent to add any refcounting for.
5115 if (hfinfo->parent != -1) {
5116 header_field_info *parent_hfinfo;
5117 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
5119 /* Mark parent as indirectly referenced unless it is already directly
5120 * referenced, i.e. the user has specified the parent in a filter.
5122 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
5123 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
5128 proto_item_add_subtree(proto_item *pi, const gint idx) {
5134 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
5136 fi = PITEM_FINFO(pi);
5138 return (proto_tree *)pi;
5140 fi->tree_type = idx;
5142 return (proto_tree *)pi;
5146 proto_item_get_subtree(proto_item *pi) {
5151 fi = PITEM_FINFO(pi);
5152 if ( (!fi) || (fi->tree_type == -1) )
5154 return (proto_tree *)pi;
5158 proto_item_get_parent(const proto_item *ti) {
5165 proto_item_get_parent_nth(proto_item *ti, int gen) {
5178 proto_tree_get_parent(proto_tree *tree) {
5181 return (proto_item *)tree;
5185 proto_tree_get_parent_tree(proto_tree *tree) {
5189 /* we're the root tree, there's no parent
5190 return ourselves so the caller has at least a tree to attach to */
5194 return (proto_tree *)tree->parent;
5198 proto_tree_get_root(proto_tree *tree) {
5201 while (tree->parent) {
5202 tree = tree->parent;
5208 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
5209 proto_item *item_to_move)
5212 /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
5213 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
5215 /* This function doesn't generate any values. It only reorganizes the prococol tree
5216 * so we can bail out immediately if it isn't visible. */
5217 if (!tree || !PTREE_DATA(tree)->visible)
5220 DISSECTOR_ASSERT(item_to_move->parent == tree);
5221 DISSECTOR_ASSERT(fixed_item->parent == tree);
5223 /*** cut item_to_move out ***/
5225 /* is item_to_move the first? */
5226 if (tree->first_child == item_to_move) {
5227 /* simply change first child to next */
5228 tree->first_child = item_to_move->next;
5230 DISSECTOR_ASSERT(tree->last_child != item_to_move);
5232 proto_item *curr_item;
5233 /* find previous and change it's next */
5234 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
5235 if (curr_item->next == item_to_move) {
5240 DISSECTOR_ASSERT(curr_item);
5242 curr_item->next = item_to_move->next;
5244 /* fix last_child if required */
5245 if (tree->last_child == item_to_move) {
5246 tree->last_child = curr_item;
5250 /*** insert to_move after fixed ***/
5251 item_to_move->next = fixed_item->next;
5252 fixed_item->next = item_to_move;
5253 if (tree->last_child == fixed_item) {
5254 tree->last_child = item_to_move;
5259 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
5267 fi = PTREE_FINFO(tree);
5271 start += tvb_raw_offset(tvb);
5272 DISSECTOR_ASSERT(start >= 0);
5273 DISSECTOR_ASSERT(length >= 0);
5275 fi->appendix_start = start;
5276 fi->appendix_length = length;
5280 proto_register_protocol(const char *name, const char *short_name,
5281 const char *filter_name)
5283 protocol_t *protocol;
5284 const protocol_t *existing_protocol = NULL;
5285 header_field_info *hfinfo;
5287 const char *existing_name;
5291 gboolean found_invalid;
5294 * Make sure there's not already a protocol with any of those
5295 * names. Crash if there is, as that's an error in the code
5296 * or an inappropriate plugin.
5297 * This situation has to be fixed to not register more than one
5298 * protocol with the same name.
5300 * This is done by reducing the number of strcmp (and alike) calls
5301 * as much as possible, as this significally slows down startup time.
5303 * Drawback: As a hash value is used to reduce insert time,
5304 * this might lead to a hash collision.
5305 * However, although we have somewhat over 1000 protocols, we're using
5306 * a 32 bit int so this is very, very unlikely.
5309 key = (gint *)g_malloc (sizeof(gint));
5310 *key = wrs_str_hash(name);
5312 existing_name = (const char *)g_hash_table_lookup(proto_names, key);
5313 if (existing_name != NULL) {
5314 /* g_error will terminate the program */
5315 g_error("Duplicate protocol name \"%s\"!"
5316 " This might be caused by an inappropriate plugin or a development error.", name);
5318 g_hash_table_insert(proto_names, key, (gpointer)name);
5320 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, (gpointer)short_name);
5321 if (existing_protocol != NULL) {
5322 g_error("Duplicate protocol short_name \"%s\"!"
5323 " This might be caused by an inappropriate plugin or a development error.", short_name);
5326 found_invalid = FALSE;
5327 for (i = 0; filter_name[i]; i++) {
5329 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
5330 found_invalid = TRUE;
5333 if (found_invalid) {
5334 g_error("Protocol filter name \"%s\" has one or more invalid characters."
5335 " Allowed are lower characters, digits, '-', '_' and '.'."
5336 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5338 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, (gpointer)filter_name);
5339 if (existing_protocol != NULL) {
5340 g_error("Duplicate protocol filter_name \"%s\"!"
5341 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5344 /* Add this protocol to the list of known protocols; the list
5345 is sorted by protocol short name. */
5346 protocol = g_new(protocol_t, 1);
5347 protocol->name = name;
5348 protocol->short_name = short_name;
5349 protocol->filter_name = filter_name;
5350 protocol->fields = g_ptr_array_new();
5351 protocol->is_enabled = TRUE; /* protocol is enabled by default */
5352 protocol->can_toggle = TRUE;
5353 protocol->heur_list = NULL;
5354 /* list will be sorted later by name, when all protocols completed registering */
5355 protocols = g_list_prepend(protocols, protocol);
5356 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
5357 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
5359 /* Here we allocate a new header_field_info struct */
5360 hfinfo = g_slice_new(header_field_info);
5361 hfinfo->name = name;
5362 hfinfo->abbrev = filter_name;
5363 hfinfo->type = FT_PROTOCOL;
5364 hfinfo->display = BASE_NONE;
5365 hfinfo->strings = protocol;
5366 hfinfo->bitmask = 0;
5367 hfinfo->ref_type = HF_REF_TYPE_NONE;
5368 hfinfo->blurb = NULL;
5369 hfinfo->parent = -1; /* this field differentiates protos and fields */
5371 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
5372 protocol->proto_id = proto_id;
5377 proto_deregister_protocol(const char *short_name)
5379 protocol_t *protocol;
5380 header_field_info *hfinfo;
5385 proto_id = proto_get_id_by_short_name(short_name);
5386 protocol = find_protocol_by_id(proto_id);
5387 if (protocol == NULL)
5390 key = (gint *)g_malloc(sizeof(gint));
5391 *key = wrs_str_hash(protocol->name);
5393 g_hash_table_remove(proto_names, key);
5396 g_hash_table_remove(proto_short_names, (gpointer)short_name);
5397 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
5399 for (i = 0; i < protocol->fields->len; i++) {
5400 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
5401 hfinfo_remove_from_gpa_name_map(hfinfo);
5402 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
5404 g_ptr_array_free(protocol->fields, TRUE);
5405 protocol->fields = NULL;
5407 /* Remove this protocol from the list of known protocols */
5408 protocols = g_list_remove(protocols, protocol);
5410 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
5411 g_hash_table_steal(gpa_name_map, protocol->filter_name);
5413 g_free(last_field_name);
5414 last_field_name = NULL;
5420 * Routines to use to iterate over the protocols.
5421 * The argument passed to the iterator routines is an opaque cookie to
5422 * their callers; it's the GList pointer for the current element in
5424 * The ID of the protocol is returned, or -1 if there is no protocol.
5427 proto_get_first_protocol(void **cookie)
5429 protocol_t *protocol;
5431 if (protocols == NULL)
5433 *cookie = protocols;
5434 protocol = (protocol_t *)protocols->data;
5435 return protocol->proto_id;
5439 proto_get_data_protocol(void *cookie)
5441 GList *list_item = (GList *)cookie;
5443 protocol_t *protocol = (protocol_t *)list_item->data;
5444 return protocol->proto_id;
5448 proto_get_next_protocol(void **cookie)
5450 GList *list_item = (GList *)*cookie;
5451 protocol_t *protocol;
5453 list_item = g_list_next(list_item);
5454 if (list_item == NULL)
5456 *cookie = list_item;
5457 protocol = (protocol_t *)list_item->data;
5458 return protocol->proto_id;
5461 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
5462 assume that the cookie stored by
5463 proto_get_(first|next)_protocol_field() will never have a
5464 value of NULL. So, to preserve this semantic, the cookie value
5465 below is adjusted so that the cookie value stored is 1 + the
5466 current (zero-based) array index.
5469 proto_get_first_protocol_field(const int proto_id, void **cookie)
5471 protocol_t *protocol = find_protocol_by_id(proto_id);
5473 if ((protocol == NULL) || (protocol->fields->len == 0))
5476 *cookie = GUINT_TO_POINTER(0 + 1);
5477 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
5481 proto_get_next_protocol_field(const int proto_id, void **cookie)
5483 protocol_t *protocol = find_protocol_by_id(proto_id);
5484 guint i = GPOINTER_TO_UINT(*cookie) - 1;
5488 if (i >= protocol->fields->len)
5491 *cookie = GUINT_TO_POINTER(i + 1);
5492 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
5496 find_protocol_by_id(const int proto_id)
5498 header_field_info *hfinfo;
5503 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
5504 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
5505 return (protocol_t *)hfinfo->strings;
5509 proto_get_id(const protocol_t *protocol)
5511 return protocol->proto_id;
5515 proto_get_id_by_filter_name(const gchar *filter_name)
5517 const protocol_t *protocol = NULL;
5519 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
5521 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, (gpointer)filter_name);
5523 if (protocol == NULL)
5525 return protocol->proto_id;
5529 proto_get_id_by_short_name(const gchar *short_name)
5531 const protocol_t *protocol = NULL;
5533 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
5535 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, (gpointer)short_name);
5537 if (protocol == NULL)
5539 return protocol->proto_id;
5543 proto_get_protocol_name(const int proto_id)
5545 protocol_t *protocol;
5547 protocol = find_protocol_by_id(proto_id);
5549 if (protocol == NULL)
5551 return protocol->name;
5555 proto_get_protocol_short_name(const protocol_t *protocol)
5557 if (protocol == NULL)
5559 return protocol->short_name;
5563 proto_get_protocol_long_name(const protocol_t *protocol)
5565 if (protocol == NULL)
5567 return protocol->name;
5571 proto_get_protocol_filter_name(const int proto_id)
5573 protocol_t *protocol;
5575 protocol = find_protocol_by_id(proto_id);
5576 if (protocol == NULL)
5578 return protocol->filter_name;
5581 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
5583 heur_dtbl_entry_t* heuristic_dissector;
5585 if (protocol == NULL)
5588 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
5589 if (heuristic_dissector != NULL)
5591 protocol->heur_list = g_list_append (protocol->heur_list, heuristic_dissector);
5595 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
5597 if (protocol == NULL)
5600 g_list_foreach(protocol->heur_list, func, user_data);
5604 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
5605 gboolean *is_tcp, gboolean *is_udp,
5606 gboolean *is_sctp, gboolean *is_ssl,
5608 gboolean *is_lte_rlc)
5610 wmem_list_frame_t *protos = wmem_list_head(layers);
5612 const char *proto_name;
5614 /* Walk the list of a available protocols in the packet and
5615 find "major" ones. */
5616 /* It might make more sense to assemble and return a bitfield. */
5617 while (protos != NULL)
5619 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
5620 proto_name = proto_get_protocol_filter_name(proto_id);
5622 if (is_ip && ((!strcmp(proto_name, "ip")) ||
5623 (!strcmp(proto_name, "ipv6")))) {
5625 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
5627 } else if (is_udp && !strcmp(proto_name, "udp")) {
5629 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
5631 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
5633 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
5635 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
5639 protos = wmem_list_frame_next(protos);
5644 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
5646 wmem_list_frame_t *protos = wmem_list_head(layers);
5650 /* Walk the list of a available protocols in the packet and
5651 find "major" ones. */
5652 /* It might make more sense to assemble and return a bitfield. */
5653 while (protos != NULL)
5655 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
5656 name = proto_get_protocol_filter_name(proto_id);
5658 if (!strcmp(name, proto_name))
5663 protos = wmem_list_frame_next(protos);
5671 proto_is_protocol_enabled(const protocol_t *protocol)
5673 return protocol->is_enabled;
5677 proto_can_toggle_protocol(const int proto_id)
5679 protocol_t *protocol;
5681 protocol = find_protocol_by_id(proto_id);
5682 return protocol->can_toggle;
5686 proto_set_decoding(const int proto_id, const gboolean enabled)
5688 protocol_t *protocol;
5690 protocol = find_protocol_by_id(proto_id);
5691 DISSECTOR_ASSERT(protocol->can_toggle);
5692 protocol->is_enabled = enabled;
5696 proto_enable_all(void)
5698 protocol_t *protocol;
5699 GList *list_item = protocols;
5701 if (protocols == NULL)
5705 protocol = (protocol_t *)list_item->data;
5706 if (protocol->can_toggle)
5707 protocol->is_enabled = TRUE;
5708 list_item = g_list_next(list_item);
5713 proto_set_cant_toggle(const int proto_id)
5715 protocol_t *protocol;
5717 protocol = find_protocol_by_id(proto_id);
5718 protocol->can_toggle = FALSE;
5722 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
5724 if (proto != NULL) {
5725 g_ptr_array_add(proto->fields, hfi);
5728 return proto_register_field_init(hfi, parent);
5731 /* for use with static arrays only, since we don't allocate our own copies
5732 of the header_field_info struct contained within the hf_register_info struct */
5734 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
5736 hf_register_info *ptr = hf;
5740 proto = find_protocol_by_id(parent);
5741 for (i = 0; i < num_records; i++, ptr++) {
5743 * Make sure we haven't registered this yet.
5744 * Most fields have variables associated with them
5745 * that are initialized to -1; some have array elements,
5746 * or possibly uninitialized variables, so we also allow
5747 * 0 (which is unlikely to be the field ID we get back
5748 * from "proto_register_field_init()").
5750 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
5752 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
5753 ptr->hfinfo.abbrev);
5757 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
5762 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
5767 proto = find_protocol_by_id(parent);
5768 for (i = 0; i < num_records; i++) {
5770 * Make sure we haven't registered this yet.
5772 if (hfi[i].id != -1) {
5774 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
5779 proto_register_field_common(proto, &hfi[i], parent);
5784 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
5789 proto = find_protocol_by_id(parent);
5790 for (i = 0; i < num_records; i++) {
5792 * Make sure we haven't registered this yet.
5794 if (hfi[i]->id != -1) {
5796 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
5801 proto_register_field_common(proto, hfi[i], parent);
5805 /* deregister already registered fields */
5807 proto_deregister_field (const int parent, gint hf_id)
5809 header_field_info *hfi;
5813 g_free(last_field_name);
5814 last_field_name = NULL;
5816 if (hf_id == -1 || hf_id == 0)
5819 proto = find_protocol_by_id (parent);
5820 if (!proto || proto->fields->len == 0) {
5824 for (i = 0; i < proto->fields->len; i++) {
5825 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
5826 if (hfi->id == hf_id) {
5827 /* Found the hf_id in this protocol */
5828 g_hash_table_steal(gpa_name_map, hfi->abbrev);
5829 g_ptr_array_remove_index_fast(proto->fields, i);
5830 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
5837 proto_add_deregistered_data (void *data)
5839 g_ptr_array_add(deregistered_data, data);
5843 free_deregistered_field (gpointer data, gpointer user_data _U_)
5845 header_field_info *hfi = (header_field_info *) data;
5846 gint hf_id = hfi->id;
5848 g_free((char *)hfi->name);
5849 g_free((char *)hfi->abbrev);
5850 g_free((char *)hfi->blurb);
5853 switch (hfi->type) {
5855 protocol_t *protocol = (protocol_t *)hfi->strings;
5856 g_free((gchar *)protocol->short_name);
5860 true_false_string *tf = (true_false_string *)hfi->strings;
5861 g_free ((gchar *)tf->true_string);
5862 g_free ((gchar *)tf->false_string);
5867 val64_string *vs64 = (val64_string *)hfi->strings;
5868 while (vs64->strptr) {
5869 g_free((gchar *)vs64->strptr);
5875 /* Other Integer types */
5876 value_string *vs = (value_string *)hfi->strings;
5877 while (vs->strptr) {
5878 g_free((gchar *)vs->strptr);
5884 g_free((void *)hfi->strings);
5887 if (hfi->parent == -1)
5888 g_slice_free(header_field_info, hfi);
5890 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
5894 free_deregistered_data (gpointer data, gpointer user_data _U_)
5899 /* free deregistered fields and data */
5901 proto_free_deregistered_fields (void)
5903 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
5904 g_ptr_array_free(deregistered_fields, TRUE);
5905 deregistered_fields = g_ptr_array_new();
5907 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
5908 g_ptr_array_free(deregistered_data, TRUE);
5909 deregistered_data = g_ptr_array_new();
5912 /* chars allowed in field abbrev */
5914 const guint8 fld_abbrev_chars[256] = {
5915 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
5916 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
5917 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
5918 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
5919 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
5920 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
5921 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
5922 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
5923 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
5924 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
5925 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
5926 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
5927 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
5928 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
5929 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
5930 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
5933 static const value_string hf_display[] = {
5934 { BASE_NONE, "BASE_NONE" },
5935 { BASE_DEC, "BASE_DEC" },
5936 { BASE_HEX, "BASE_HEX" },
5937 { BASE_OCT, "BASE_OCT" },
5938 { BASE_DEC_HEX, "BASE_DEC_HEX" },
5939 { BASE_HEX_DEC, "BASE_HEX_DEC" },
5940 { BASE_CUSTOM, "BASE_CUSTOM" },
5941 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
5942 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
5943 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
5944 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
5945 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
5946 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
5947 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
5948 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
5949 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
5950 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
5951 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
5952 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
5953 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
5954 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
5955 /* { STR_ASCII, "STR_ASCII" }, */
5956 { STR_UNICODE, "STR_UNICODE" },
5957 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
5958 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
5959 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
5960 { BASE_PT_UDP, "BASE_PT_UDP" },
5961 { BASE_PT_TCP, "BASE_PT_TCP" },
5962 { BASE_PT_DCCP, "BASE_PT_DCCP" },
5963 { BASE_PT_SCTP, "BASE_PT_SCTP" },
5966 static inline port_type
5967 display_to_port_type(field_display_e e)
5984 /* temporary function containing assert part for easier profiling */
5986 tmp_fld_check_assert(header_field_info *hfinfo)
5990 /* The field must have a name (with length > 0) */
5991 if (!hfinfo->name || !hfinfo->name[0]) {
5993 /* Try to identify the field */
5994 g_error("Field (abbrev='%s') does not have a name\n",
5998 g_error("Field does not have a name (nor an abbreviation)\n");
6001 /* fields with an empty string for an abbreviation aren't filterable */
6002 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
6003 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
6005 /* These types of fields are allowed to have value_strings,
6006 * true_false_strings or a protocol_t struct
6008 if (hfinfo->strings != NULL && !(
6009 (hfinfo->type == FT_UINT8) ||
6010 (hfinfo->type == FT_UINT16) ||
6011 (hfinfo->type == FT_UINT24) ||
6012 (hfinfo->type == FT_UINT32) ||
6013 (hfinfo->type == FT_UINT40) ||
6014 (hfinfo->type == FT_UINT48) ||
6015 (hfinfo->type == FT_UINT56) ||
6016 (hfinfo->type == FT_UINT64) ||
6017 (hfinfo->type == FT_INT8) ||
6018 (hfinfo->type == FT_INT16) ||
6019 (hfinfo->type == FT_INT24) ||
6020 (hfinfo->type == FT_INT32) ||
6021 (hfinfo->type == FT_INT40) ||
6022 (hfinfo->type == FT_INT48) ||
6023 (hfinfo->type == FT_INT56) ||
6024 (hfinfo->type == FT_INT64) ||
6025 (hfinfo->type == FT_BOOLEAN) ||
6026 (hfinfo->type == FT_PROTOCOL) ||
6027 (hfinfo->type == FT_FRAMENUM) ))
6028 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
6029 " (which is not allowed to have strings)\n",
6030 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
6032 /* TODO: This check may slow down startup, and output quite a few warnings.
6033 It would be good to be able to enable this (and possibly other checks?)
6034 in non-release builds. */
6036 /* Check for duplicate value_string values.
6037 There are lots that have the same value *and* string, so for now only
6038 report those that have same value but different string. */
6039 if ((hfinfo->strings != NULL) &&
6040 !(hfinfo->display & BASE_RANGE_STRING) &&
6041 !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
6043 (hfinfo->type == FT_UINT8) ||
6044 (hfinfo->type == FT_UINT16) ||
6045 (hfinfo->type == FT_UINT24) ||
6046 (hfinfo->type == FT_UINT32) ||
6047 (hfinfo->type == FT_INT8) ||
6048 (hfinfo->type == FT_INT16) ||
6049 (hfinfo->type == FT_INT24) ||
6050 (hfinfo->type == FT_INT32) ||
6051 (hfinfo->type == FT_FRAMENUM) )) {
6054 const value_string *start_values;
6055 const value_string *current;
6057 if (hfinfo->display & BASE_EXT_STRING)
6058 start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
6060 start_values = (const value_string*)hfinfo->strings;
6061 current = start_values;
6063 for (n=0; current; n++, current++) {
6064 /* Drop out if we reached the end. */
6065 if ((current->value == 0) && (current->strptr == NULL)) {
6069 /* Check value against all previous */
6070 for (m=0; m < n; m++) {
6071 /* There are lots of duplicates with the same string,
6072 so only report if different... */
6073 if ((start_values[m].value == current->value) &&
6074 (strcmp(start_values[m].strptr, current->strptr) != 0)) {
6075 g_warning("Field '%s' (%s) has a conflicting entry in its"
6076 " value_string: %u is at indices %u (%s) and %u (%s))\n",
6077 hfinfo->name, hfinfo->abbrev,
6078 current->value, m, start_values[m].strptr, n, current->strptr);
6086 switch (hfinfo->type) {
6096 /* Hexadecimal and octal are, in printf() and everywhere
6097 * else, unsigned so don't allow dissectors to register a
6098 * signed field to be displayed unsigned. (Else how would
6099 * we display negative values?)
6101 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6106 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6107 g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
6108 hfinfo->name, hfinfo->abbrev,
6109 ftype_name(hfinfo->type), tmp_str);
6110 wmem_free(NULL, tmp_str);
6121 if (IS_BASE_PORT(hfinfo->display)) {
6122 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6123 if (hfinfo->type != FT_UINT16) {
6124 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
6125 hfinfo->name, hfinfo->abbrev,
6126 tmp_str, ftype_name(hfinfo->type));
6128 if (hfinfo->strings != NULL) {
6129 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
6130 hfinfo->name, hfinfo->abbrev,
6131 ftype_name(hfinfo->type), tmp_str);
6133 if (hfinfo->bitmask != 0) {
6134 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
6135 hfinfo->name, hfinfo->abbrev,
6136 ftype_name(hfinfo->type), tmp_str);
6138 wmem_free(NULL, tmp_str);
6141 /* Require integral types (other than frame number,
6142 * which is always displayed in decimal) to have a
6144 * If there is a strings value then this base is not
6145 * normally used except when constructing a display
6146 * filter for a value not found in the strings lookup.
6148 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6154 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6157 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6158 g_error("Field '%s' (%s) is an integral value (%s)"
6159 " but is being displayed as %s\n",
6160 hfinfo->name, hfinfo->abbrev,
6161 ftype_name(hfinfo->type), tmp_str);
6162 wmem_free(NULL, tmp_str);
6166 /* Require bytes to have a "display type" that could
6167 * add a character between displayed bytes.
6169 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6177 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6178 g_error("Field '%s' (%s) is an byte array but is being displayed as %s instead of BASE_NONE, SEP_DOT, SEP_DASH, SEP_COLON, or SEP_SPACE\n",
6179 hfinfo->name, hfinfo->abbrev, tmp_str);
6180 wmem_free(NULL, tmp_str);
6182 if (hfinfo->bitmask != 0)
6183 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6184 hfinfo->name, hfinfo->abbrev,
6185 ftype_name(hfinfo->type));
6186 if (hfinfo->strings != NULL)
6187 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6188 hfinfo->name, hfinfo->abbrev,
6189 ftype_name(hfinfo->type));
6194 if (hfinfo->display != BASE_NONE) {
6195 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6196 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6197 hfinfo->name, hfinfo->abbrev,
6198 ftype_name(hfinfo->type), tmp_str);
6199 wmem_free(NULL, tmp_str);
6201 if (hfinfo->bitmask != 0)
6202 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6203 hfinfo->name, hfinfo->abbrev,
6204 ftype_name(hfinfo->type));
6210 case FT_ABSOLUTE_TIME:
6211 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
6212 hfinfo->display == ABSOLUTE_TIME_UTC ||
6213 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
6214 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6215 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
6216 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
6217 wmem_free(NULL, tmp_str);
6219 if (hfinfo->bitmask != 0)
6220 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6221 hfinfo->name, hfinfo->abbrev,
6222 ftype_name(hfinfo->type));
6227 case FT_UINT_STRING:
6229 switch (hfinfo->display) {
6235 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6236 g_error("Field '%s' (%s) is an string value (%s)"
6237 " but is being displayed as %s\n",
6238 hfinfo->name, hfinfo->abbrev,
6239 ftype_name(hfinfo->type), tmp_str);
6240 wmem_free(NULL, tmp_str);
6243 if (hfinfo->bitmask != 0)
6244 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6245 hfinfo->name, hfinfo->abbrev,
6246 ftype_name(hfinfo->type));
6247 if (hfinfo->strings != NULL)
6248 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6249 hfinfo->name, hfinfo->abbrev,
6250 ftype_name(hfinfo->type));
6254 switch (hfinfo->display) {
6260 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6261 g_error("Field '%s' (%s) is an IPv4 value (%s)"
6262 " but is being displayed as %s\n",
6263 hfinfo->name, hfinfo->abbrev,
6264 ftype_name(hfinfo->type), tmp_str);
6265 wmem_free(NULL, tmp_str);
6270 if (hfinfo->display != BASE_NONE) {
6271 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6272 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6273 hfinfo->name, hfinfo->abbrev,
6274 ftype_name(hfinfo->type),
6276 wmem_free(NULL, tmp_str);
6278 if (hfinfo->bitmask != 0)
6279 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6280 hfinfo->name, hfinfo->abbrev,
6281 ftype_name(hfinfo->type));
6282 if (hfinfo->strings != NULL)
6283 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6284 hfinfo->name, hfinfo->abbrev,
6285 ftype_name(hfinfo->type));
6291 register_type_length_mismatch(void)
6293 static ei_register_info ei[] = {
6294 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
6295 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
6298 expert_module_t* expert_type_length_mismatch;
6300 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
6302 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
6303 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
6305 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
6306 disabling them makes no sense. */
6307 proto_set_cant_toggle(proto_type_length_mismatch);
6311 register_number_string_decoding_error(void)
6313 static ei_register_info ei[] = {
6314 { &ei_number_string_decoding_failed_error,
6315 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
6316 "Failed to decode number from string", EXPFILL
6319 { &ei_number_string_decoding_erange_error,
6320 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
6321 "Decoded number from string is out of valid range", EXPFILL
6326 expert_module_t* expert_number_string_decoding_error;
6328 proto_number_string_decoding_error =
6329 proto_register_protocol("Number-String Decoding Error",
6330 "Number-string decoding error",
6331 "_ws.number_string.decoding_error");
6333 expert_number_string_decoding_error =
6334 expert_register_protocol(proto_number_string_decoding_error);
6335 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
6337 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
6338 disabling them makes no sense. */
6339 proto_set_cant_toggle(proto_number_string_decoding_error);
6342 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (170000+PRE_ALLOC_EXPERT_FIELDS_MEM)
6344 proto_register_field_init(header_field_info *hfinfo, const int parent)
6347 tmp_fld_check_assert(hfinfo);
6349 hfinfo->parent = parent;
6350 hfinfo->same_name_next = NULL;
6351 hfinfo->same_name_prev_id = -1;
6353 /* if we always add and never delete, then id == len - 1 is correct */
6354 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
6355 if (!gpa_hfinfo.hfi) {
6356 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
6357 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
6359 gpa_hfinfo.allocated_len += 1000;
6360 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
6361 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
6362 /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
6365 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
6367 hfinfo->id = gpa_hfinfo.len - 1;
6369 /* if we have real names, enter this field in the name tree */
6370 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
6372 header_field_info *same_name_next_hfinfo;
6375 /* Check that the filter name (abbreviation) is legal;
6376 * it must contain only alphanumerics, '-', "_", and ".". */
6377 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
6379 if (g_ascii_isprint(c))
6380 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
6382 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
6383 DISSECTOR_ASSERT_NOT_REACHED();
6386 /* We allow multiple hfinfo's to be registered under the same
6387 * abbreviation. This was done for X.25, as, depending
6388 * on whether it's modulo-8 or modulo-128 operation,
6389 * some bitfield fields may be in different bits of
6390 * a byte, and we want to be able to refer to that field
6391 * with one name regardless of whether the packets
6392 * are modulo-8 or modulo-128 packets. */
6394 same_name_hfinfo = NULL;
6396 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
6397 /* GLIB 2.x - if it is already present
6398 * the previous hfinfo with the same name is saved
6399 * to same_name_hfinfo by value destroy callback */
6400 if (same_name_hfinfo) {
6401 /* There's already a field with this name.
6402 * Put the current field *before* that field
6403 * in the list of fields with this name, Thus,
6404 * we end up with an effectively
6405 * doubly-linked-list of same-named hfinfo's,
6406 * with the head of the list (stored in the
6407 * hash) being the last seen hfinfo.
6409 same_name_next_hfinfo =
6410 same_name_hfinfo->same_name_next;
6412 hfinfo->same_name_next = same_name_next_hfinfo;
6413 if (same_name_next_hfinfo)
6414 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
6416 same_name_hfinfo->same_name_next = hfinfo;
6417 hfinfo->same_name_prev_id = same_name_hfinfo->id;
6425 proto_register_subtree_array(gint *const *indices, const int num_indices)
6428 gint *const *ptr = indices;
6431 * If we've already allocated the array of tree types, expand
6432 * it; this lets plugins such as mate add tree types after
6433 * the initial startup. (If we haven't already allocated it,
6434 * we don't allocate it; on the first pass, we just assign
6435 * ett values and keep track of how many we've assigned, and
6436 * when we're finished registering all dissectors we allocate
6437 * the array, so that we do only one allocation rather than
6438 * wasting CPU time and memory by growing the array for each
6439 * dissector that registers ett values.)
6441 if (tree_is_expanded != NULL) {
6442 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
6444 /* set new items to 0 */
6445 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
6446 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
6447 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
6451 * Assign "num_indices" subtree numbers starting at "num_tree_types",
6452 * returning the indices through the pointers in the array whose
6453 * first element is pointed to by "indices", and update
6454 * "num_tree_types" appropriately.
6456 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
6458 /* g_error will terminate the program */
6459 g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
6460 " This is a development error:"
6461 " Either the subtree item type has already been assigned or"
6462 " was not initialized to -1.");
6464 **ptr = num_tree_types;
6469 label_concat(char *label_str, gsize pos, const char *str)
6471 if (pos < ITEM_LABEL_LENGTH)
6472 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
6478 label_mark_truncated(char *label_str, gsize name_pos)
6480 static const char trunc_str[] = " [truncated]";
6481 const size_t trunc_len = sizeof(trunc_str)-1;
6484 /* ..... field_name: dataaaaaaaaaaaaa
6488 * ..... field_name [truncated]: dataaaaaaaaaaaaa
6490 * name_pos==0 means that we have only data or only a field_name
6493 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
6494 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
6495 memcpy(label_str + name_pos, trunc_str, trunc_len);
6497 /* in general, label_str is UTF-8
6498 we can truncate it only at the beginning of a new character
6499 we go backwards from the byte right after our buffer and
6500 find the next starting byte of a UTF-8 character, this is
6502 there's no need to use g_utf8_find_prev_char(), the search
6503 will always succeed since we copied trunc_str into the
6505 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH]);
6508 } else if (name_pos < ITEM_LABEL_LENGTH)
6509 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
6513 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
6517 /* "%s: %s", hfinfo->name, text */
6518 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
6519 pos = label_concat(label_str, pos, ": ");
6520 pos = label_concat(label_str, pos, text ? text : "(null)");
6522 if (pos >= ITEM_LABEL_LENGTH) {
6523 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
6524 label_mark_truncated(label_str, name_pos);
6531 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
6535 /* "%s: %s (%s)", hfinfo->name, text, descr */
6536 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
6537 pos = label_concat(label_str, pos, ": ");
6538 pos = label_concat(label_str, pos, text ? text : "(null)");
6539 pos = label_concat(label_str, pos, " (");
6540 pos = label_concat(label_str, pos, descr ? descr : "(null)");
6541 pos = label_concat(label_str, pos, ")");
6543 if (pos >= ITEM_LABEL_LENGTH) {
6544 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
6545 label_mark_truncated(label_str, name_pos);
6552 proto_item_fill_label(field_info *fi, gchar *label_str)
6554 header_field_info *hfinfo;
6560 guint32 n_addr; /* network-order IPv4 address */
6569 /* XXX: Check validity of hfinfo->type */
6573 hfinfo = fi->hfinfo;
6575 switch (hfinfo->type) {
6578 g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
6582 fill_label_boolean(fi, label_str);
6587 bytes = (guint8 *)fvalue_get(&fi->value);
6590 switch(hfinfo->display)
6593 str = (char*)bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
6596 str = (char*)bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
6599 str = (char*)bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
6602 str = (char*)bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
6606 if (prefs.display_byte_fields_with_spaces)
6608 str = (char*)bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
6612 str = (char*)bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
6616 label_fill(label_str, 0, hfinfo, str);
6617 wmem_free(NULL, str);
6619 label_fill(label_str, 0, hfinfo, "<MISSING>");
6623 /* Four types of integers to take care of:
6624 * Bitfield, with val_string
6625 * Bitfield, w/o val_string
6626 * Non-bitfield, with val_string
6627 * Non-bitfield, w/o val_string
6633 if (hfinfo->bitmask) {
6634 fill_label_bitfield(fi, label_str, FALSE);
6636 fill_label_number(fi, label_str, FALSE);
6641 fill_label_number(fi, label_str, FALSE);
6648 if (hfinfo->bitmask) {
6649 fill_label_bitfield64(fi, label_str, FALSE);
6651 fill_label_number64(fi, label_str, FALSE);
6659 if (hfinfo->bitmask) {
6660 fill_label_bitfield(fi, label_str, TRUE);
6662 fill_label_number(fi, label_str, TRUE);
6670 if (hfinfo->bitmask) {
6671 fill_label_bitfield64(fi, label_str, TRUE);
6673 fill_label_number64(fi, label_str, TRUE);
6678 g_snprintf(label_str, ITEM_LABEL_LENGTH,
6679 "%s: %." G_STRINGIFY(FLT_DIG) "g",
6680 hfinfo->name, fvalue_get_floating(&fi->value));
6684 g_snprintf(label_str, ITEM_LABEL_LENGTH,
6685 "%s: %." G_STRINGIFY(DBL_DIG) "g",
6686 hfinfo->name, fvalue_get_floating(&fi->value));
6689 case FT_ABSOLUTE_TIME:
6690 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
6691 label_fill(label_str, 0, hfinfo, tmp);
6692 wmem_free(NULL, tmp);
6695 case FT_RELATIVE_TIME:
6696 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
6697 g_snprintf(label_str, ITEM_LABEL_LENGTH,
6698 "%s: %s seconds", hfinfo->name, tmp);
6699 wmem_free(NULL, tmp);
6703 integer = fvalue_get_uinteger(&fi->value);
6704 tmp = (char*)get_ipxnet_name(NULL, integer);
6705 g_snprintf(label_str, ITEM_LABEL_LENGTH,
6706 "%s: %s (0x%08X)", hfinfo->name,
6708 wmem_free(NULL, tmp);
6712 addr.type = AT_AX25;
6713 addr.len = AX25_ADDR_LEN;
6714 addr.data = (guint8 *)fvalue_get(&fi->value);
6716 addr_str = (char*)address_to_str(NULL, &addr);
6717 g_snprintf(label_str, ITEM_LABEL_LENGTH,
6718 "%s: %s", hfinfo->name, addr_str);
6719 wmem_free(NULL, addr_str);
6723 addr.type = AT_VINES;
6724 addr.len = VINES_ADDR_LEN;
6725 addr.data = (guint8 *)fvalue_get(&fi->value);
6727 addr_str = (char*)address_to_str(NULL, &addr);
6728 g_snprintf(label_str, ITEM_LABEL_LENGTH,
6729 "%s: %s", hfinfo->name, addr_str);
6730 wmem_free(NULL, addr_str);
6734 bytes = (guint8 *)fvalue_get(&fi->value);
6736 addr.type = AT_ETHER;
6740 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
6741 g_snprintf(label_str, ITEM_LABEL_LENGTH,
6742 "%s: %s", hfinfo->name, addr_str);
6743 wmem_free(NULL, addr_str);
6747 ipv4 = (ipv4_addr *)fvalue_get(&fi->value);
6748 n_addr = ipv4_get_net_order_addr(ipv4);
6750 addr.type = AT_IPv4;
6752 addr.data = &n_addr;
6754 if (hfinfo->display == BASE_NETMASK)
6756 addr_str = (char*)address_to_str(NULL, &addr);
6760 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
6762 g_snprintf(label_str, ITEM_LABEL_LENGTH,
6763 "%s: %s", hfinfo->name, addr_str);
6764 wmem_free(NULL, addr_str);
6768 bytes = (guint8 *)fvalue_get(&fi->value);
6770 addr.type = AT_IPv6;
6774 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
6775 g_snprintf(label_str, ITEM_LABEL_LENGTH,
6776 "%s: %s", hfinfo->name, addr_str);
6777 wmem_free(NULL, addr_str);
6781 addr.type = AT_FCWWN;
6782 addr.len = FCWWN_ADDR_LEN;
6783 addr.data = (guint8 *)fvalue_get(&fi->value);
6785 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
6786 g_snprintf(label_str, ITEM_LABEL_LENGTH,
6787 "%s: %s", hfinfo->name, addr_str);
6788 wmem_free(NULL, addr_str);
6792 guid = (e_guid_t *)fvalue_get(&fi->value);
6793 tmp = guid_to_str(NULL, guid);
6794 label_fill(label_str, 0, hfinfo, tmp);
6795 wmem_free(NULL, tmp);
6799 bytes = (guint8 *)fvalue_get(&fi->value);
6800 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
6801 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
6803 label_fill_descr(label_str, 0, hfinfo, tmp, name);
6804 wmem_free(NULL, name);
6806 label_fill(label_str, 0, hfinfo, tmp);
6808 wmem_free(NULL, tmp);
6812 bytes = (guint8 *)fvalue_get(&fi->value);
6813 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
6814 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
6816 label_fill_descr(label_str, 0, hfinfo, tmp, name);
6817 wmem_free(NULL, name);
6819 label_fill(label_str, 0, hfinfo, tmp);
6821 wmem_free(NULL, tmp);
6825 bytes = (guint8 *)fvalue_get(&fi->value);
6826 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
6827 label_fill(label_str, 0, hfinfo, tmp);
6828 wmem_free(NULL, tmp);
6832 integer64 = fvalue_get_uinteger64(&fi->value);
6833 addr_str = eui64_to_str(NULL, integer64);
6834 tmp = (char*)eui64_to_display(NULL, integer64);
6835 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
6836 wmem_free(NULL, tmp);
6837 wmem_free(NULL, addr_str);
6841 case FT_UINT_STRING:
6843 bytes = (guint8 *)fvalue_get(&fi->value);
6844 label_fill(label_str, 0, hfinfo, hfinfo_format_text(hfinfo, bytes));
6848 g_error("hfinfo->type %d (%s) not handled\n",
6849 hfinfo->type, ftype_name(hfinfo->type));
6850 DISSECTOR_ASSERT_NOT_REACHED();
6856 fill_label_boolean(field_info *fi, gchar *label_str)
6858 char *p = label_str;
6859 int bitfield_byte_length = 0, bitwidth;
6860 guint64 unshifted_value;
6863 header_field_info *hfinfo = fi->hfinfo;
6864 const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
6866 if (hfinfo->strings) {
6867 tfstring = (const struct true_false_string*) hfinfo->strings;
6870 value = fvalue_get_uinteger64(&fi->value);
6871 if (hfinfo->bitmask) {
6872 /* Figure out the bit width */
6873 bitwidth = hfinfo_bitwidth(hfinfo);
6876 unshifted_value = value;
6877 unshifted_value <<= hfinfo_bitshift(hfinfo);
6879 /* Create the bitfield first */
6880 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
6881 bitfield_byte_length = (int) (p - label_str);
6884 /* Fill in the textual info */
6885 label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
6889 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
6891 if (hfinfo->display & BASE_RANGE_STRING)
6892 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
6894 if (hfinfo->display & BASE_EXT_STRING)
6895 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
6897 if (hfinfo->display & BASE_VAL64_STRING)
6898 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
6900 return try_val_to_str(value, (const value_string *) hfinfo->strings);
6904 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
6906 if (hfinfo->display & BASE_VAL64_STRING)
6907 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
6909 /* If this is reached somebody registered a 64-bit field with a 32-bit
6910 * value-string, which isn't right. */
6911 DISSECTOR_ASSERT_NOT_REACHED();
6913 /* This is necessary to squelch MSVC errors; is there
6914 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
6920 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
6922 const char *str = hf_try_val_to_str(value, hfinfo);
6924 return (str) ? str : unknown_str;
6928 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
6930 const char *str = hf_try_val64_to_str(value, hfinfo);
6932 return (str) ? str : unknown_str;
6935 /* Fills data for bitfield ints with val_strings */
6937 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
6940 int bitfield_byte_length, bitwidth;
6941 guint32 unshifted_value;
6947 header_field_info *hfinfo = fi->hfinfo;
6949 /* Figure out the bit width */
6950 bitwidth = hfinfo_bitwidth(hfinfo);
6954 unshifted_value = fvalue_get_sinteger(&fi->value);
6956 unshifted_value = fvalue_get_uinteger(&fi->value);
6958 value = unshifted_value;
6959 if (hfinfo->bitmask) {
6960 unshifted_value <<= hfinfo_bitshift(hfinfo);
6963 /* Create the bitfield first */
6964 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
6965 bitfield_byte_length = (int) (p - label_str);
6967 /* Fill in the textual info using stored (shifted) value */
6968 if (hfinfo->display == BASE_CUSTOM) {
6969 gchar tmp[ITEM_LABEL_LENGTH];
6970 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
6972 DISSECTOR_ASSERT(fmtfunc);
6973 fmtfunc(tmp, value);
6974 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
6976 else if (hfinfo->strings) {
6977 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
6979 out = hfinfo_number_vals_format(hfinfo, buf, value);
6980 if (out == NULL) /* BASE_NONE so don't put integer in descr */
6981 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
6983 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
6986 out = hfinfo_number_value_format(hfinfo, buf, value);
6988 label_fill(label_str, bitfield_byte_length, hfinfo, out);
6993 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
6996 int bitfield_byte_length, bitwidth;
6997 guint64 unshifted_value;
7003 header_field_info *hfinfo = fi->hfinfo;
7005 /* Figure out the bit width */
7006 bitwidth = hfinfo_bitwidth(hfinfo);
7010 unshifted_value = fvalue_get_sinteger64(&fi->value);
7012 unshifted_value = fvalue_get_uinteger64(&fi->value);
7014 value = unshifted_value;
7015 if (hfinfo->bitmask) {
7016 unshifted_value <<= hfinfo_bitshift(hfinfo); /* XXX 64-bit function needed? */
7019 /* Create the bitfield first */
7020 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7021 bitfield_byte_length = (int) (p - label_str);
7023 /* Fill in the textual info using stored (shifted) value */
7024 if (hfinfo->display == BASE_CUSTOM) {
7025 gchar tmp[ITEM_LABEL_LENGTH];
7026 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7028 DISSECTOR_ASSERT(fmtfunc64);
7029 fmtfunc64(tmp, value);
7030 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7032 else if (hfinfo->strings) {
7033 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7035 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7036 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7037 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7039 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7042 out = hfinfo_number_value_format64(hfinfo, buf, value);
7044 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7049 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
7051 header_field_info *hfinfo = fi->hfinfo;
7058 value = fvalue_get_sinteger(&fi->value);
7060 value = fvalue_get_uinteger(&fi->value);
7062 /* Fill in the textual info */
7063 if (hfinfo->display == BASE_CUSTOM) {
7064 gchar tmp[ITEM_LABEL_LENGTH];
7065 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7067 DISSECTOR_ASSERT(fmtfunc);
7068 fmtfunc(tmp, value);
7069 label_fill(label_str, 0, hfinfo, tmp);
7071 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) { /* Add fill_label_framenum? */
7072 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7074 out = hfinfo_number_vals_format(hfinfo, buf, value);
7075 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7076 label_fill(label_str, 0, hfinfo, val_str);
7078 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7080 else if (IS_BASE_PORT(hfinfo->display)) {
7081 gchar tmp[ITEM_LABEL_LENGTH];
7083 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
7084 display_to_port_type((field_display_e)hfinfo->display), value);
7085 label_fill(label_str, 0, hfinfo, tmp);
7088 out = hfinfo_number_value_format(hfinfo, buf, value);
7090 label_fill(label_str, 0, hfinfo, out);
7095 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
7097 header_field_info *hfinfo = fi->hfinfo;
7104 value = fvalue_get_sinteger64(&fi->value);
7106 value = fvalue_get_uinteger64(&fi->value);
7108 /* Fill in the textual info */
7109 if (hfinfo->display == BASE_CUSTOM) {
7110 gchar tmp[ITEM_LABEL_LENGTH];
7111 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7113 DISSECTOR_ASSERT(fmtfunc64);
7114 fmtfunc64(tmp, value);
7115 label_fill(label_str, 0, hfinfo, tmp);
7117 else if (hfinfo->strings) {
7118 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7120 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7121 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7122 label_fill(label_str, 0, hfinfo, val_str);
7124 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7127 out = hfinfo_number_value_format64(hfinfo, buf, value);
7129 label_fill(label_str, 0, hfinfo, out);
7134 hfinfo_bitshift(const header_field_info *hfinfo)
7136 return ws_ctz(hfinfo->bitmask);
7140 hfinfo_bitwidth(const header_field_info *hfinfo)
7144 if (!hfinfo->bitmask) {
7148 switch (hfinfo->type) {
7182 bitwidth = hfinfo->display; /* hacky? :) */
7185 DISSECTOR_ASSERT_NOT_REACHED();
7192 _hfinfo_type_hex_octet(int type)
7228 DISSECTOR_ASSERT_NOT_REACHED();
7235 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
7237 char *ptr = &buf[31];
7238 gboolean isint = IS_FT_INT(hfinfo->type);
7241 /* Properly format value */
7242 switch (display & FIELD_DISPLAY_E_MASK) {
7244 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7248 ptr = hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
7251 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7255 return oct_to_str_back(ptr, value);
7258 return hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
7262 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7265 ptr = hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
7272 port_with_resolution_to_str_buf(buf, 32,
7273 display_to_port_type((field_display_e)display), value);
7277 g_assert_not_reached();
7283 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
7285 char *ptr = &buf[47];
7286 gboolean isint = IS_FT_INT(hfinfo->type);
7289 /* Properly format value */
7292 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7296 ptr = hex64_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
7299 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7303 return oct64_to_str_back(ptr, value);
7306 return hex64_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
7310 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7313 ptr = hex64_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
7317 g_assert_not_reached();
7323 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7325 int display = hfinfo->display;
7327 if (hfinfo->type == FT_FRAMENUM) {
7329 * Frame numbers are always displayed in decimal.
7334 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7338 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7340 int display = hfinfo->display;
7342 if (hfinfo->type == FT_FRAMENUM) {
7344 * Frame numbers are always displayed in decimal.
7349 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7353 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7355 /* Get the underlying BASE_ value */
7356 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7358 if (hfinfo->type == FT_FRAMENUM) {
7360 * Frame numbers are always displayed in decimal.
7367 /* case BASE_DEC: */
7369 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
7374 /* case BASE_HEX: */
7380 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7384 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7386 /* Get the underlying BASE_ value */
7387 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7389 if (hfinfo->type == FT_FRAMENUM) {
7391 * Frame numbers are always displayed in decimal.
7398 /* case BASE_DEC: */
7400 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
7405 /* case BASE_HEX: */
7411 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7415 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7417 /* Get the underlying BASE_ value */
7418 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7420 if (display == BASE_NONE)
7423 if (display == BASE_DEC_HEX)
7425 if (display == BASE_HEX_DEC)
7428 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7432 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7434 /* Get the underlying BASE_ value */
7435 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7437 if (display == BASE_NONE)
7440 if (display == BASE_DEC_HEX)
7442 if (display == BASE_HEX_DEC)
7445 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7449 proto_registrar_get_name(const int n)
7451 header_field_info *hfinfo;
7453 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7454 return hfinfo->name;
7458 proto_registrar_get_abbrev(const int n)
7460 header_field_info *hfinfo;
7462 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7463 return hfinfo->abbrev;
7467 proto_registrar_get_ftype(const int n)
7469 header_field_info *hfinfo;
7471 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7472 return hfinfo->type;
7476 proto_registrar_get_parent(const int n)
7478 header_field_info *hfinfo;
7480 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7481 return hfinfo->parent;
7485 proto_registrar_is_protocol(const int n)
7487 header_field_info *hfinfo;
7489 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7490 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
7493 /* Returns length of field in packet (not necessarily the length
7494 * in our internal representation, as in the case of IPv4).
7495 * 0 means undeterminable at time of registration
7496 * -1 means the field is not registered. */
7498 proto_registrar_get_length(const int n)
7500 header_field_info *hfinfo;
7502 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7503 return ftype_length(hfinfo->type);
7506 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
7507 * it exists anywhere, or FALSE if it exists nowhere. */
7509 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
7511 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
7516 else if (g_ptr_array_len(ptrs) > 0) {
7524 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
7525 * This only works if the hfindex was "primed" before the dissection
7526 * took place, as we just pass back the already-created GPtrArray*.
7527 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
7530 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
7535 if (PTREE_DATA(tree)->interesting_hfids != NULL)
7536 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
7537 GINT_TO_POINTER(id));
7543 proto_tracking_interesting_fields(const proto_tree *tree)
7545 GHashTable *interesting_hfids;
7550 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
7552 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
7555 /* Helper struct for proto_find_info() and proto_all_finfos() */
7561 /* Helper function for proto_find_info() */
7563 find_finfo(proto_node *node, gpointer data)
7565 field_info *fi = PNODE_FINFO(node);
7566 if (fi && fi->hfinfo) {
7567 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
7568 g_ptr_array_add(((ffdata_t*)data)->array, fi);
7572 /* Don't stop traversing. */
7576 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
7577 * This works on any proto_tree, primed or unprimed, but actually searches
7578 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
7579 * The caller does need to free the returned GPtrArray with
7580 * g_ptr_array_free(<array>, TRUE).
7583 proto_find_finfo(proto_tree *tree, const int id)
7587 ffdata.array = g_ptr_array_new();
7590 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
7592 return ffdata.array;
7595 /* Helper function for proto_all_finfos() */
7597 every_finfo(proto_node *node, gpointer data)
7599 field_info *fi = PNODE_FINFO(node);
7600 if (fi && fi->hfinfo) {
7601 g_ptr_array_add(((ffdata_t*)data)->array, fi);
7604 /* Don't stop traversing. */
7608 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
7610 proto_all_finfos(proto_tree *tree)
7614 ffdata.array = g_ptr_array_new();
7617 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
7619 return ffdata.array;
7630 check_for_offset(proto_node *node, const gpointer data)
7632 field_info *fi = PNODE_FINFO(node);
7633 offset_search_t *offsearch = (offset_search_t *)data;
7635 /* !fi == the top most container node which holds nothing */
7636 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
7637 if (offsearch->offset >= (guint) fi->start &&
7638 offsearch->offset < (guint) (fi->start + fi->length)) {
7640 offsearch->finfo = fi;
7641 return FALSE; /* keep traversing */
7644 return FALSE; /* keep traversing */
7647 /* Search a proto_tree backwards (from leaves to root) looking for the field
7648 * whose start/length occupies 'offset' */
7649 /* XXX - I couldn't find an easy way to search backwards, so I search
7650 * forwards, w/o stopping. Therefore, the last finfo I find will the be
7651 * the one I want to return to the user. This algorithm is inefficient
7652 * and could be re-done, but I'd have to handle all the children and
7653 * siblings of each node myself. When I have more time I'll do that.
7656 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
7658 offset_search_t offsearch;
7660 offsearch.offset = offset;
7661 offsearch.finfo = NULL;
7662 offsearch.tvb = tvb;
7664 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
7666 return offsearch.finfo;
7671 check_for_undecoded(proto_node *node, const gpointer data)
7673 field_info *fi = PNODE_FINFO(node);
7674 gchar* decoded = (gchar*)data;
7679 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
7680 for (i = fi->start; i < fi->start + fi->length; i++) {
7683 decoded[byte] |= (1 << bit);
7691 proto_find_undecoded_data(proto_tree *tree, guint length)
7693 gchar* decoded = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
7695 proto_tree_traverse_pre_order(tree, check_for_undecoded, decoded);
7699 /* Dumps the protocols in the registration database to stdout. An independent
7700 * program can take this output and format it into nice tables or HTML or
7703 * There is one record per line. The fields are tab-delimited.
7705 * Field 1 = protocol name
7706 * Field 2 = protocol short name
7707 * Field 3 = protocol filter name
7710 proto_registrar_dump_protocols(void)
7712 protocol_t *protocol;
7714 void *cookie = NULL;
7717 i = proto_get_first_protocol(&cookie);
7719 protocol = find_protocol_by_id(i);
7720 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
7721 protocol->filter_name);
7722 i = proto_get_next_protocol(&cookie);
7726 /* Dumps the value_strings, extended value string headers, range_strings
7727 * or true/false strings for fields that have them.
7728 * There is one record per line. Fields are tab-delimited.
7729 * There are four types of records: Value String, Extended Value String Header,
7730 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
7731 * the type of record.
7733 * Note that a record will be generated only if the value_string,... is referenced
7734 * in a registered hfinfo entry.
7740 * Field 2 = Field abbreviation to which this value string corresponds
7741 * Field 3 = Integer value
7744 * Extended Value String Headers
7745 * -----------------------------
7747 * Field 2 = Field abbreviation to which this extended value string header corresponds
7748 * Field 3 = Extended Value String "Name"
7749 * Field 4 = Number of entries in the associated value_string array
7750 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
7755 * Field 2 = Field abbreviation to which this range string corresponds
7756 * Field 3 = Integer value: lower bound
7757 * Field 4 = Integer value: upper bound
7760 * True/False Strings
7761 * ------------------
7763 * Field 2 = Field abbreviation to which this true/false string corresponds
7764 * Field 3 = True String
7765 * Field 4 = False String
7768 proto_registrar_dump_values(void)
7770 header_field_info *hfinfo;
7772 const value_string *vals;
7773 const val64_string *vals64;
7774 const range_string *range;
7775 const true_false_string *tfs;
7777 len = gpa_hfinfo.len;
7778 for (i = 0; i < len ; i++) {
7779 if (gpa_hfinfo.hfi[i] == NULL)
7780 continue; /* This is a deregistered protocol or field */
7782 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
7784 if (hfinfo->id == hf_text_only) {
7788 /* ignore protocols */
7789 if (proto_registrar_is_protocol(i)) {
7792 /* process header fields */
7793 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
7795 * If this field isn't at the head of the list of
7796 * fields with this name, skip this field - all
7797 * fields with the same name are really just versions
7798 * of the same field stored in different bits, and
7799 * should have the same type/radix/value list, and
7800 * just differ in their bit masks. (If a field isn't
7801 * a bitfield, but can be, say, 1 or 2 bytes long,
7802 * it can just be made FT_UINT16, meaning the
7803 * *maximum* length is 2 bytes, and be used
7806 if (hfinfo->same_name_prev_id != -1)
7814 if (hfinfo->strings != NULL) {
7815 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) != BASE_CUSTOM &&
7816 (hfinfo->type == FT_UINT8 ||
7817 hfinfo->type == FT_UINT16 ||
7818 hfinfo->type == FT_UINT24 ||
7819 hfinfo->type == FT_UINT32 ||
7820 hfinfo->type == FT_UINT40 ||
7821 hfinfo->type == FT_UINT48 ||
7822 hfinfo->type == FT_UINT56 ||
7823 hfinfo->type == FT_UINT64 ||
7824 hfinfo->type == FT_INT8 ||
7825 hfinfo->type == FT_INT16 ||
7826 hfinfo->type == FT_INT24 ||
7827 hfinfo->type == FT_INT32 ||
7828 hfinfo->type == FT_INT40 ||
7829 hfinfo->type == FT_INT48 ||
7830 hfinfo->type == FT_INT56 ||
7831 hfinfo->type == FT_INT64)) {
7833 if (hfinfo->display & BASE_RANGE_STRING) {
7834 range = (const range_string *)hfinfo->strings;
7835 } else if (hfinfo->display & BASE_EXT_STRING) {
7836 vals = VALUE_STRING_EXT_VS_P((value_string_ext *)hfinfo->strings);
7837 } else if (hfinfo->display & BASE_VAL64_STRING) {
7838 vals64 = (const val64_string *)hfinfo->strings;
7840 vals = (const value_string *)hfinfo->strings;
7843 else if (hfinfo->type == FT_BOOLEAN) {
7844 tfs = (const struct true_false_string *)hfinfo->strings;
7848 /* Print value strings? */
7850 if (hfinfo->display & BASE_EXT_STRING) {
7851 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
7852 if (!value_string_ext_validate(vse_p)) {
7853 g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
7856 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
7857 printf("E\t%s\t%u\t%s\t%s\n",
7859 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
7860 VALUE_STRING_EXT_VS_NAME(vse_p),
7861 value_string_ext_match_type_str(vse_p));
7864 while (vals[vi].strptr) {
7865 /* Print in the proper base */
7866 if (hfinfo->display == BASE_HEX) {
7867 printf("V\t%s\t0x%x\t%s\n",
7873 printf("V\t%s\t%u\t%s\n",
7883 while (vals64[vi].strptr) {
7884 printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
7892 /* print range strings? */
7895 while (range[vi].strptr) {
7896 /* Print in the proper base */
7897 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_HEX) {
7898 printf("R\t%s\t0x%x\t0x%x\t%s\n",
7900 range[vi].value_min,
7901 range[vi].value_max,
7905 printf("R\t%s\t%u\t%u\t%s\n",
7907 range[vi].value_min,
7908 range[vi].value_max,
7915 /* Print true/false strings? */
7917 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
7918 tfs->true_string, tfs->false_string);
7923 /* Prints the number of registered fields.
7924 * Useful for determining an appropriate value for
7925 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
7927 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
7928 * the number of fields, TRUE otherwise.
7931 proto_registrar_dump_fieldcount(void)
7934 header_field_info *hfinfo;
7935 guint32 deregistered_count = 0;
7936 guint32 same_name_count = 0;
7937 guint32 protocol_count = 0;
7939 for (i = 0; i < gpa_hfinfo.len; i++) {
7940 if (gpa_hfinfo.hfi[i] == NULL) {
7941 deregistered_count++;
7942 continue; /* This is a deregistered protocol or header field */
7945 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
7947 if (proto_registrar_is_protocol(i))
7950 if (hfinfo->same_name_prev_id != -1)
7954 printf ("There are %d header fields registered, of which:\n"
7955 "\t%d are deregistered\n"
7956 "\t%d are protocols\n"
7957 "\t%d have the same name as another field\n\n",
7958 gpa_hfinfo.len, deregistered_count, protocol_count,
7961 printf ("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
7962 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
7963 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
7966 printf ("The header field table consumes %d KiB of memory.\n",
7967 (int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
7968 printf ("The fields themselves consume %d KiB of memory.\n",
7969 (int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
7971 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
7975 /* Dumps the contents of the registration database to stdout. An independent
7976 * program can take this output and format it into nice tables or HTML or
7979 * There is one record per line. Each record is either a protocol or a header
7980 * field, differentiated by the first field. The fields are tab-delimited.
7985 * Field 2 = descriptive protocol name
7986 * Field 3 = protocol abbreviation
7991 * Field 2 = descriptive field name
7992 * Field 3 = field abbreviation
7993 * Field 4 = type ( textual representation of the the ftenum type )
7994 * Field 5 = parent protocol abbreviation
7995 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
7996 * Field 7 = bitmask: format: hex: 0x....
7997 * Field 8 = blurb describing field
8000 proto_registrar_dump_fields(void)
8002 header_field_info *hfinfo, *parent_hfinfo;
8004 const char *enum_name;
8005 const char *base_name;
8009 len = gpa_hfinfo.len;
8010 for (i = 0; i < len ; i++) {
8011 if (gpa_hfinfo.hfi[i] == NULL)
8012 continue; /* This is a deregistered protocol or header field */
8014 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8017 * Skip the pseudo-field for "proto_tree_add_text()" since
8018 * we don't want it in the list of filterable fields.
8020 if (hfinfo->id == hf_text_only)
8023 /* format for protocols */
8024 if (proto_registrar_is_protocol(i)) {
8025 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
8027 /* format for header fields */
8030 * If this field isn't at the head of the list of
8031 * fields with this name, skip this field - all
8032 * fields with the same name are really just versions
8033 * of the same field stored in different bits, and
8034 * should have the same type/radix/value list, and
8035 * just differ in their bit masks. (If a field isn't
8036 * a bitfield, but can be, say, 1 or 2 bytes long,
8037 * it can just be made FT_UINT16, meaning the
8038 * *maximum* length is 2 bytes, and be used
8041 if (hfinfo->same_name_prev_id != -1)
8044 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
8046 enum_name = ftype_name(hfinfo->type);
8049 if (hfinfo->type == FT_UINT8 ||
8050 hfinfo->type == FT_UINT16 ||
8051 hfinfo->type == FT_UINT24 ||
8052 hfinfo->type == FT_UINT32 ||
8053 hfinfo->type == FT_UINT40 ||
8054 hfinfo->type == FT_UINT48 ||
8055 hfinfo->type == FT_UINT56 ||
8056 hfinfo->type == FT_UINT64 ||
8057 hfinfo->type == FT_INT8 ||
8058 hfinfo->type == FT_INT16 ||
8059 hfinfo->type == FT_INT24 ||
8060 hfinfo->type == FT_INT32 ||
8061 hfinfo->type == FT_INT40 ||
8062 hfinfo->type == FT_INT48 ||
8063 hfinfo->type == FT_INT56 ||
8064 hfinfo->type == FT_INT64) {
8066 switch (FIELD_DISPLAY(hfinfo->display)) {
8078 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
8084 } else if (hfinfo->type == FT_BOOLEAN) {
8085 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
8086 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
8090 blurb = hfinfo->blurb;
8093 else if (strlen(blurb) == 0)
8096 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
8097 hfinfo->name, hfinfo->abbrev, enum_name,
8098 parent_hfinfo->abbrev, base_name,
8099 hfinfo->bitmask, blurb);
8104 /* Dumps field types and descriptive names to stdout. An independent
8105 * program can take this output and format it into nice tables or HTML or
8108 * There is one record per line. The fields are tab-delimited.
8110 * Field 1 = field type name, e.g. FT_UINT8
8111 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
8114 proto_registrar_dump_ftypes(void)
8118 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
8119 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
8123 /* This function indicates whether it's possible to construct a
8124 * "match selected" display filter string for the specified field,
8125 * returns an indication of whether it's possible, and, if it's
8126 * possible and "filter" is non-null, constructs the filter and
8127 * sets "*filter" to point to it.
8128 * You do not need to [g_]free() this string since it will be automatically
8129 * freed once the next packet is dissected.
8132 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
8135 header_field_info *hfinfo;
8140 gint start, length, length_remaining;
8142 gchar is_signed_num = FALSE;
8147 hfinfo = finfo->hfinfo;
8148 DISSECTOR_ASSERT(hfinfo);
8149 abbrev_len = (int) strlen(hfinfo->abbrev);
8151 if (hfinfo->strings && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
8152 const gchar *str = NULL;
8154 switch (hfinfo->type) {
8160 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
8167 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
8174 if (str != NULL && filter != NULL) {
8175 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
8181 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
8182 * functions for FT_UINT and FT_INT types, as we choose the base in
8183 * the string expression based on the display base of the field.
8185 * Note that the base does matter, as this is also used for
8186 * the protocolinfo tap.
8188 * It might be nice to use them in "proto_item_fill_label()"
8189 * as well, although, there, you'd have to deal with the base
8190 * *and* with resolved values for addresses.
8192 * Perhaps we need two different val_to_string routines, one
8193 * to generate items for display filters and one to generate
8194 * strings for display, and pass to both of them the
8195 * "display" and "strings" values in the header_field_info
8196 * structure for the field, so they can get the base and,
8197 * if the field is Boolean or an enumerated integer type,
8198 * the tables used to generate human-readable values.
8200 switch (hfinfo->type) {
8206 is_signed_num = TRUE;
8213 if (filter != NULL) {
8220 number = fvalue_get_sinteger(&finfo->value);
8222 number = fvalue_get_uinteger(&finfo->value);
8224 out = hfinfo_numeric_value_format(hfinfo, buf, number);
8226 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
8234 is_signed_num = TRUE;
8240 if (filter != NULL) {
8247 number = fvalue_get_sinteger64(&finfo->value);
8249 number = fvalue_get_uinteger64(&finfo->value);
8251 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
8253 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
8259 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
8264 * If the length is 0, just match the name of the
8267 * (Also check for negative values, just in case,
8268 * as we'll cast it to an unsigned value later.)
8270 length = finfo->length;
8273 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
8280 * This doesn't have a value, so we'd match
8281 * on the raw bytes at this address.
8283 * Should we be allowed to access to the raw bytes?
8284 * If "edt" is NULL, the answer is "no".
8290 * Is this field part of the raw frame tvbuff?
8291 * If not, we can't use "frame[N:M]" to match
8294 * XXX - should this be frame-relative, or
8295 * protocol-relative?
8297 * XXX - does this fallback for non-registered
8298 * fields even make sense?
8300 if (finfo->ds_tvb != edt->tvb)
8301 return FALSE; /* you lose */
8304 * Don't go past the end of that tvbuff.
8306 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
8307 if (length > length_remaining)
8308 length = length_remaining;
8312 if (filter != NULL) {
8313 start = finfo->start;
8314 buf_len = 32 + length * 3;
8315 *filter = (char *)wmem_alloc0(NULL, buf_len);
8318 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
8319 "frame[%d:%d] == ", finfo->start, length);
8320 for (i=0; i<length; i++) {
8321 c = tvb_get_guint8(finfo->ds_tvb, start);
8324 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
8327 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
8334 /* FT_PCRE never appears as a type for a registered field. It is
8335 * only used internally. */
8336 DISSECTOR_ASSERT_NOT_REACHED();
8339 /* By default, use the fvalue's "to_string_repr" method. */
8341 /* Figure out the string length needed.
8342 * The ft_repr length.
8343 * 4 bytes for " == ".
8344 * 1 byte for trailing NUL.
8346 if (filter != NULL) {
8347 dfilter_len = fvalue_string_repr_len(&finfo->value,
8348 FTREPR_DFILTER, finfo->hfinfo->display);
8349 dfilter_len += abbrev_len + 4 + 1;
8350 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
8352 /* Create the string */
8353 g_snprintf(*filter, dfilter_len, "%s == ",
8355 fvalue_to_string_repr(&finfo->value,
8356 FTREPR_DFILTER, finfo->hfinfo->display,
8357 &(*filter)[abbrev_len + 4]);
8366 * Returns TRUE if we can do a "match selected" on the field, FALSE
8370 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
8372 return construct_match_selected_string(finfo, edt, NULL);
8375 /* This function attempts to construct a "match selected" display filter
8376 * string for the specified field; if it can do so, it returns a pointer
8377 * to the string, otherwise it returns NULL.
8379 * The string is allocated with packet lifetime scope.
8380 * You do not need to [g_]free() this string since it will be automatically
8381 * freed once the next packet is dissected.
8384 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
8386 char *filter = NULL;
8388 if (!construct_match_selected_string(finfo, edt, &filter))
8390 wmem_free(NULL, filter);
8396 /* This function is common code for both proto_tree_add_bitmask() and
8397 * proto_tree_add_bitmask_text() functions.
8400 /* NOTE: to support code written when proto_tree_add_bitmask() and
8401 * proto_tree_add_bitmask_text took a
8402 * gboolean as its last argument, with FALSE meaning "big-endian"
8403 * and TRUE meaning "little-endian", we treat any non-zero value of
8404 * "encoding" as meaning "little-endian".
8407 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
8408 const int len, const gint ett, const int **fields,
8409 const guint encoding, const int flags,
8410 gboolean first, gboolean use_parent_tree, gboolean use_value,
8411 proto_tree* tree, guint64 value)
8413 guint64 available_bits = 0;
8415 header_field_info *hf;
8419 if (use_value == FALSE)
8420 value = tvb_get_guint8(tvb, offset);
8421 available_bits = 0xFF;
8424 if (use_value == FALSE)
8425 value = encoding ? tvb_get_letohs(tvb, offset) : tvb_get_ntohs(tvb, offset);
8426 available_bits = 0xFFFF;
8429 if (use_value == FALSE)
8430 value = encoding ? tvb_get_letoh24(tvb, offset) : tvb_get_ntoh24(tvb, offset);
8431 available_bits = 0xFFFFFF;
8434 if (use_value == FALSE)
8435 value = encoding ? tvb_get_letohl(tvb, offset) : tvb_get_ntohl(tvb, offset);
8436 available_bits = 0xFFFFFFFF;
8439 if (use_value == FALSE)
8440 value = encoding ? tvb_get_letoh40(tvb, offset) : tvb_get_ntoh40(tvb, offset);
8441 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFF);
8444 if (use_value == FALSE)
8445 value = encoding ? tvb_get_letoh48(tvb, offset) : tvb_get_ntoh48(tvb, offset);
8446 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFF);
8449 if (use_value == FALSE)
8450 value = encoding ? tvb_get_letoh56(tvb, offset) : tvb_get_ntoh56(tvb, offset);
8451 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFF);
8454 if (use_value == FALSE)
8455 value = encoding ? tvb_get_letoh64(tvb, offset) : tvb_get_ntoh64(tvb, offset);
8456 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
8459 g_assert_not_reached();
8462 if (use_parent_tree == FALSE)
8463 tree = proto_item_add_subtree(item, ett);
8466 guint64 present_bits;
8467 PROTO_REGISTRAR_GET_NTH(**fields,hf);
8468 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
8470 /* Skip fields that aren't fully present */
8471 present_bits = available_bits & hf->bitmask;
8472 if (present_bits != hf->bitmask) {
8488 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
8499 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
8503 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
8507 DISSECTOR_ASSERT_NOT_REACHED();
8513 proto_tree_add_item(tree, **fields, tvb, offset, len, encoding);
8515 if (flags & BMT_NO_APPEND) {
8519 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
8538 if (hf->display == BASE_CUSTOM) {
8539 gchar lbl[ITEM_LABEL_LENGTH];
8540 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
8542 DISSECTOR_ASSERT(fmtfunc);
8543 fmtfunc(lbl, (guint32) tmpval);
8544 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8548 else if (hf->strings) {
8549 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8550 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
8553 else if (!(flags & BMT_NO_INT)) {
8558 proto_item_append_text(item, ", ");
8561 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
8562 proto_item_append_text(item, "%s: %s", hf->name, out);
8568 if (hf->strings && !(flags & BMT_NO_TFS)) {
8569 /* If we have true/false strings, emit full - otherwise messages
8571 const struct true_false_string *tfs =
8572 (const struct true_false_string *)hf->strings;
8575 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8576 hf->name, tfs->true_string);
8578 } else if (!(flags & BMT_NO_FALSE)) {
8579 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8580 hf->name, tfs->false_string);
8583 } else if (hf->bitmask & value) {
8584 /* If the flag is set, show the name */
8585 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
8590 DISSECTOR_ASSERT_NOT_REACHED();
8600 /* This function will dissect a sequence of bytes that describe a
8602 * hf_hdr is a 8/16/24/32 bit integer that describes the bitmask to be dissected.
8603 * This field will form an expansion under which the individual fields of the
8604 * bitmask is dissected and displayed.
8605 * This field must be of the type FT_[U]INT{8|16|24|32}.
8607 * fields is an array of pointers to int that lists all the fields of the
8608 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
8609 * or another integer of the same type/size as hf_hdr with a mask specified.
8610 * This array is terminated by a NULL entry.
8612 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
8613 * FT_integer fields that have a value_string attached will have the
8614 * matched string displayed on the expansion line.
8617 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
8618 const guint offset, const int hf_hdr,
8619 const gint ett, const int **fields,
8620 const guint encoding)
8622 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
8625 /* The same as proto_tree_add_bitmask(), but uses user-supplied flags to determine
8626 * what data is appended to the header.
8629 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
8630 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
8632 proto_item *item = NULL;
8633 header_field_info *hf;
8636 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
8637 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
8638 len = ftype_length(hf->type);
8641 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
8642 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields, encoding,
8643 flags, FALSE, FALSE, FALSE, NULL, 0);
8649 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
8650 can't be retrieved directly from tvb) */
8652 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
8653 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
8655 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
8656 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
8659 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
8660 WS_DLL_PUBLIC proto_item *
8661 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
8662 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
8664 proto_item *item = NULL;
8665 header_field_info *hf;
8668 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
8669 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
8670 len = ftype_length(hf->type);
8674 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
8676 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
8678 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
8679 0, flags, FALSE, FALSE, TRUE, NULL, value);
8686 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
8688 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
8689 const int len, const int **fields, const guint encoding)
8692 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
8693 encoding, BMT_NO_APPEND, FALSE, TRUE, FALSE, tree, 0);
8697 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
8698 * This is intended to support bitmask fields whose lengths can vary, perhaps
8699 * as the underlying standard evolves over time.
8700 * With this API there is the possibility of being called to display more or
8701 * less data than the dissector was coded to support.
8702 * In such cases, it is assumed that bitmasks are extended on the MSb end.
8703 * Thus when presented with "too much" or "too little" data, MSbits will be
8704 * ignored or MSfields sacrificed.
8706 * Only fields for which all defined bits are available are displayed.
8709 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
8710 const guint offset, const guint len, const int hf_hdr,
8711 const gint ett, const int **fields, struct expert_field* exp,
8712 const guint encoding)
8714 proto_item *item = NULL;
8715 header_field_info *hf;
8716 guint decodable_len;
8717 guint decodable_offset;
8718 guint32 decodable_value;
8720 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
8721 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
8723 decodable_offset = offset;
8724 decodable_len = MIN(len, (guint) ftype_length(hf->type));
8726 /* If we are ftype_length-limited,
8727 * make sure we decode as many LSBs as possible.
8729 if (encoding == ENC_BIG_ENDIAN) {
8730 decodable_offset += (len - decodable_len);
8734 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
8735 decodable_len, encoding);
8737 /* The root item covers all the bytes even if we can't decode them all */
8738 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
8742 if (decodable_len < len) {
8743 /* Dissector likely requires updating for new protocol revision */
8744 expert_add_info_format(NULL, item, exp,
8745 "Only least-significant %d of %d bytes decoded",
8746 decodable_len, len);
8750 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
8751 ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, FALSE, NULL, 0);
8757 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
8759 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
8760 const guint offset, const guint len,
8761 const char *name, const char *fallback,
8762 const gint ett, const int **fields,
8763 const guint encoding, const int flags)
8765 proto_item *item = NULL;
8768 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
8769 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields, encoding,
8770 flags, TRUE, FALSE, FALSE, NULL, 0) && fallback) {
8771 /* Still at first item - append 'fallback' text if any */
8772 proto_item_append_text(item, "%s", fallback);
8780 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
8781 const guint bit_offset, const gint no_of_bits,
8782 const guint encoding)
8784 header_field_info *hfinfo;
8788 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
8790 octet_length = (no_of_bits + 7) >> 3;
8791 octet_offset = bit_offset >> 3;
8792 test_length(hfinfo, tvb, octet_offset, octet_length);
8794 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
8795 * but only after doing a bunch more work (which we can, in the common
8796 * case, shortcut here).
8798 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
8800 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
8804 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
8805 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
8806 * Offset should be given in bits from the start of the tvb.
8810 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
8811 const guint bit_offset, const gint no_of_bits,
8812 guint64 *return_value, const guint encoding)
8818 char lbl_str[ITEM_LABEL_LENGTH];
8822 header_field_info *hf_field;
8824 const true_false_string *tfstring;
8826 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
8827 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
8829 if (hf_field->bitmask != 0) {
8830 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
8831 "Incompatible use of proto_tree_add_bits_ret_val"
8832 " with field '%s' (%s) with bitmask != 0",
8833 hf_field->abbrev, hf_field->name));
8836 DISSECTOR_ASSERT(no_of_bits > 0);
8838 /* Byte align offset */
8839 offset = bit_offset>>3;
8842 * Calculate the number of octets used to hold the bits
8844 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
8845 length = (tot_no_bits + 7) >> 3;
8847 if (no_of_bits < 65) {
8848 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
8850 DISSECTOR_ASSERT_NOT_REACHED();
8854 /* Sign extend for signed types */
8855 switch (hf_field->type) {
8864 value = ws_sign_ext64(value, no_of_bits);
8872 *return_value = value;
8875 /* Coast clear. Try and fake it */
8876 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
8878 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
8880 switch (hf_field->type) {
8883 tfstring = (const true_false_string *) &tfs_true_false;
8884 if (hf_field->strings)
8885 tfstring = (const true_false_string *)hf_field->strings;
8886 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
8888 bf_str, hf_field->name,
8889 (guint64)value ? tfstring->true_string : tfstring->false_string);
8896 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
8897 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
8904 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
8905 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
8912 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
8913 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
8920 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
8921 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
8925 DISSECTOR_ASSERT_NOT_REACHED();
8930 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
8935 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
8936 const guint bit_offset, const crumb_spec_t *crumb_spec,
8937 guint64 *return_value)
8942 guint mask_initial_bit_offset;
8943 guint mask_greatest_bit_offset;
8947 char lbl_str[ITEM_LABEL_LENGTH];
8949 guint64 composite_bitmask;
8950 guint64 composite_bitmap;
8952 header_field_info *hf_field;
8953 const true_false_string *tfstring;
8955 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
8956 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
8958 if (hf_field->bitmask != 0) {
8959 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
8960 "Incompatible use of proto_tree_add_split_bits_item_ret_val"
8961 " with field '%s' (%s) with bitmask != 0",
8962 hf_field->abbrev, hf_field->name));
8965 mask_initial_bit_offset = bit_offset % 8;
8970 mask_greatest_bit_offset = 0;
8971 composite_bitmask = 0;
8972 composite_bitmap = 0;
8974 while (crumb_spec[i].crumb_bit_length != 0) {
8975 guint64 crumb_mask, crumb_value;
8976 guint8 crumb_end_bit_offset;
8978 DISSECTOR_ASSERT(i < 64);
8979 crumb_value = tvb_get_bits64(tvb,
8980 bit_offset + crumb_spec[i].crumb_bit_offset,
8981 crumb_spec[i].crumb_bit_length,
8983 value += crumb_value;
8984 no_of_bits += crumb_spec[i].crumb_bit_length;
8986 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
8987 octet containing the initial offset.
8988 If the mask is beyond 32 bits, then give up on bit map display.
8989 This could be improved in future, probably showing a table
8990 of 32 or 64 bits per row */
8991 if (mask_greatest_bit_offset < 32) {
8992 crumb_end_bit_offset = mask_initial_bit_offset
8993 + crumb_spec[i].crumb_bit_offset
8994 + crumb_spec[i].crumb_bit_length;
8995 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
8997 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
8998 mask_greatest_bit_offset = crumb_end_bit_offset;
9000 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
9001 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
9003 /* Shift left for the next segment */
9004 value <<= crumb_spec[++i].crumb_bit_length;
9007 /* Sign extend for signed types */
9008 switch (hf_field->type) {
9017 value = ws_sign_ext64(value, no_of_bits);
9024 *return_value = value;
9027 /* Coast clear. Try and fake it */
9028 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9030 /* initialise the format string */
9033 octet_offset = bit_offset >> 3;
9035 /* Round up mask length to nearest octet */
9036 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
9037 mask_greatest_bit_offset = octet_length << 3;
9039 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
9040 It would be a useful enhancement to eliminate this restriction. */
9041 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
9042 other_decode_bitfield_value(bf_str,
9043 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
9044 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
9045 mask_greatest_bit_offset);
9048 switch (hf_field->type) {
9049 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
9051 tfstring = (const true_false_string *) &tfs_true_false;
9052 if (hf_field->strings)
9053 tfstring = (const true_false_string *) hf_field->strings;
9054 return proto_tree_add_boolean_format(tree, hfindex,
9055 tvb, octet_offset, octet_length, (guint32)value,
9057 bf_str, hf_field->name,
9058 (guint64)value ? tfstring->true_string : tfstring->false_string);
9065 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
9066 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
9073 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
9074 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
9081 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
9082 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
9089 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
9090 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
9094 DISSECTOR_ASSERT_NOT_REACHED();
9098 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
9103 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
9104 const crumb_spec_t *crumb_spec, guint16 crumb_index)
9106 header_field_info *hfinfo;
9108 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9109 proto_tree_add_text_internal(tree, tvb,
9111 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
9112 "%s crumb %d of %s (decoded above)",
9113 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
9116 crumb_spec[crumb_index].crumb_bit_length,
9123 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9124 const guint bit_offset, const gint no_of_bits,
9125 guint64 *return_value, const guint encoding)
9129 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
9130 bit_offset, no_of_bits,
9131 return_value, encoding))) {
9132 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
9133 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
9139 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
9140 tvbuff_t *tvb, const guint bit_offset,
9141 const gint no_of_bits, void *value_ptr,
9149 header_field_info *hf_field;
9151 /* We do not have to return a value, try to fake it as soon as possible */
9152 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9154 if (hf_field->bitmask != 0) {
9155 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9156 "Incompatible use of proto_tree_add_bits_format_value"
9157 " with field '%s' (%s) with bitmask != 0",
9158 hf_field->abbrev, hf_field->name));
9161 DISSECTOR_ASSERT(no_of_bits > 0);
9163 /* Byte align offset */
9164 offset = bit_offset>>3;
9167 * Calculate the number of octets used to hold the bits
9169 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
9170 length = tot_no_bits>>3;
9171 /* If we are using part of the next octet, increase length by 1 */
9172 if (tot_no_bits & 0x07)
9175 if (no_of_bits < 65) {
9176 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
9178 DISSECTOR_ASSERT_NOT_REACHED();
9182 str = decode_bits_in_field(bit_offset, no_of_bits, value);
9184 g_strlcat(str, " = ", 256+64);
9185 g_strlcat(str, hf_field->name, 256+64);
9188 * This function does not receive an actual value but a dimensionless pointer to that value.
9189 * For this reason, the type of the header field is examined in order to determine
9190 * what kind of value we should read from this address.
9191 * The caller of this function must make sure that for the specific header field type the address of
9192 * a compatible value is provided.
9194 switch (hf_field->type) {
9196 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
9197 "%s: %s", str, value_str);
9204 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
9205 "%s: %s", str, value_str);
9212 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
9213 "%s: %s", str, value_str);
9220 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
9221 "%s: %s", str, value_str);
9228 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
9229 "%s: %s", str, value_str);
9233 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
9234 "%s: %s", str, value_str);
9238 DISSECTOR_ASSERT_NOT_REACHED();
9245 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
9246 tvbuff_t *tvb, const guint bit_offset,
9247 const gint no_of_bits, void *value_ptr,
9252 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
9253 tvb, bit_offset, no_of_bits,
9254 value_ptr, value_str))) {
9255 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
9256 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
9261 #define CREATE_VALUE_STRING(dst,format,ap) \
9262 va_start(ap, format); \
9263 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
9267 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
9268 tvbuff_t *tvb, const guint bit_offset,
9269 const gint no_of_bits, guint32 value,
9270 const char *format, ...)
9274 header_field_info *hf_field;
9276 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9278 switch (hf_field->type) {
9286 DISSECTOR_ASSERT_NOT_REACHED();
9291 CREATE_VALUE_STRING(dst, format, ap);
9293 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9297 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
9298 tvbuff_t *tvb, const guint bit_offset,
9299 const gint no_of_bits, guint64 value,
9300 const char *format, ...)
9304 header_field_info *hf_field;
9306 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9308 switch (hf_field->type) {
9316 DISSECTOR_ASSERT_NOT_REACHED();
9321 CREATE_VALUE_STRING(dst, format, ap);
9323 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9327 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
9328 tvbuff_t *tvb, const guint bit_offset,
9329 const gint no_of_bits, float value,
9330 const char *format, ...)
9334 header_field_info *hf_field;
9336 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9338 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
9340 CREATE_VALUE_STRING(dst, format, ap);
9342 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9346 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
9347 tvbuff_t *tvb, const guint bit_offset,
9348 const gint no_of_bits, gint32 value,
9349 const char *format, ...)
9353 header_field_info *hf_field;
9355 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9357 switch (hf_field->type) {
9365 DISSECTOR_ASSERT_NOT_REACHED();
9370 CREATE_VALUE_STRING(dst, format, ap);
9372 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9376 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
9377 tvbuff_t *tvb, const guint bit_offset,
9378 const gint no_of_bits, gint64 value,
9379 const char *format, ...)
9383 header_field_info *hf_field;
9385 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9387 switch (hf_field->type) {
9395 DISSECTOR_ASSERT_NOT_REACHED();
9400 CREATE_VALUE_STRING(dst, format, ap);
9402 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9406 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
9407 tvbuff_t *tvb, const guint bit_offset,
9408 const gint no_of_bits, guint32 value,
9409 const char *format, ...)
9413 header_field_info *hf_field;
9415 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9417 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
9419 CREATE_VALUE_STRING(dst, format, ap);
9421 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9425 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
9426 tvbuff_t *tvb, const guint bit_offset,
9427 const gint no_of_bits, guint64 value,
9428 const char *format, ...)
9432 header_field_info *hf_field;
9434 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9436 DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
9438 CREATE_VALUE_STRING(dst, format, ap);
9440 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9444 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9445 const guint bit_offset, const gint no_of_chars)
9448 header_field_info *hfinfo;
9453 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9455 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
9457 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
9458 byte_offset = bit_offset >> 3;
9460 string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
9462 if (hfinfo->display == STR_UNICODE) {
9463 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
9466 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
9467 DISSECTOR_ASSERT(byte_length >= 0);
9468 proto_tree_set_string(PNODE_FINFO(pi), string);
9474 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9475 const guint bit_offset, const gint no_of_chars)
9478 header_field_info *hfinfo;
9483 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9485 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
9487 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
9488 byte_offset = bit_offset >> 3;
9490 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
9492 if (hfinfo->display == STR_UNICODE) {
9493 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
9496 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
9497 DISSECTOR_ASSERT(byte_length >= 0);
9498 proto_tree_set_string(PNODE_FINFO(pi), string);
9504 proto_check_field_name(const gchar *field_name)
9506 return wrs_check_charset(fld_abbrev_chars, field_name);
9510 tree_expanded(int tree_type)
9512 g_assert(tree_type >= 0 && tree_type < num_tree_types);
9513 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
9517 tree_expanded_set(int tree_type, gboolean value)
9519 g_assert(tree_type >= 0 && tree_type < num_tree_types);
9522 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
9524 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
9528 * Editor modelines - http://www.wireshark.org/tools/modelines.html
9533 * indent-tabs-mode: t
9536 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
9537 * :indentSize=8:tabSize=8:noTabs=false: