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"
58 #include <wsutil/plugins.h>
59 #include <wsutil/ws_printf.h> /* ws_debug_printf/ws_g_warning */
60 #include <wsutil/glib-compat.h>
62 /* Ptvcursor limits */
63 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
64 #define SUBTREE_MAX_LEVELS 256
66 /* Throw an exception if our tree exceeds these. */
67 /* XXX - These should probably be preferences */
68 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
69 #define MAX_TREE_LEVELS (5 * 100)
71 typedef struct __subtree_lvl {
78 subtree_lvl *pushed_tree;
79 guint8 pushed_tree_index;
80 guint8 pushed_tree_max;
86 #define cVALS(x) (const value_string*)(x)
88 /** See inlined comments.
89 @param tree the tree to append this item to
90 @param free_block a code block to call to free resources if this returns
91 @return NULL if 'tree' is null */
92 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block) \
98 /** See inlined comments.
99 @param tree the tree to append this item to
100 @param free_block a code block to call to free resources if this returns
101 @return NULL if 'tree' is null */
102 #define CHECK_FOR_NULL_TREE(tree) \
103 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
105 /** See inlined comments.
106 @param tree the tree to append this item to
107 @param hfindex field index
108 @param hfinfo header_field
109 @param free_block a code block to call to free resources if this returns
110 @return the header field matching 'hfinfo' */
111 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
112 /* If this item is not referenced we don't have to do much work \
113 at all but we should still return a node so that field items \
114 below this node (think proto_item_add_subtree()) will still \
115 have somewhere to attach to or else filtering will not work \
116 (they would be ignored since tree would be NULL). \
117 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
118 since dissectors that want to do proto_item_set_len() or \
119 other operations that dereference this would crash. \
120 We fake FT_PROTOCOL unless some clients have requested us \
123 PTREE_DATA(tree)->count++; \
124 if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
126 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
127 g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
128 /* Let the exception handler add items to the tree */ \
129 PTREE_DATA(tree)->count = 0; \
130 THROW_MESSAGE(DissectorError, \
131 wmem_strdup_printf(wmem_packet_scope(), "More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
133 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
134 if (!(PTREE_DATA(tree)->visible)) { \
135 if (PTREE_FINFO(tree)) { \
136 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
137 && (hfinfo->type != FT_PROTOCOL || \
138 PTREE_DATA(tree)->fake_protocols)) { \
140 /* just return tree back to the caller */\
146 /** See inlined comments.
147 @param tree the tree to append this item to
148 @param hfindex field index
149 @param hfinfo header_field
150 @return the header field matching 'hfinfo' */
151 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
152 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
155 /** See inlined comments.
156 @param pi the created protocol item we're about to return */
157 #define TRY_TO_FAKE_THIS_REPR(pi) \
159 if (!(PTREE_DATA(pi)->visible)) { \
160 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
161 * items string representation */ \
164 /* Same as above but returning void */
165 #define TRY_TO_FAKE_THIS_REPR_VOID(pi) \
168 if (!(PTREE_DATA(pi)->visible)) { \
169 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
170 * items string representation */ \
173 /* Similar to above, but allows a NULL tree */
174 #define TRY_TO_FAKE_THIS_REPR_NESTED(pi) \
175 if ((pi == NULL) || (!(PTREE_DATA(pi)->visible))) { \
176 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
177 * items string representation */ \
181 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
182 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
183 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
185 static void label_mark_truncated(char *label_str, gsize name_pos);
186 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
188 static void fill_label_boolean(field_info *fi, gchar *label_str);
189 static void fill_label_bitfield_char(field_info *fi, gchar *label_str);
190 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
191 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
192 static void fill_label_char(field_info *fi, gchar *label_str);
193 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
194 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
196 static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value);
197 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
198 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
199 static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
200 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
201 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
202 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
203 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
204 static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
205 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
206 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
208 static void proto_cleanup_base(void);
211 proto_tree_add_node(proto_tree *tree, field_info *fi);
214 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
218 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
219 gint length, guint item_length, const gint encoding);
222 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
223 const gint start, const gint item_length);
226 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
227 gint start, gint *length);
230 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
232 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
235 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
237 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
239 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
241 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
243 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
245 proto_tree_set_string(field_info *fi, const char* value);
247 proto_tree_set_ax25(field_info *fi, const guint8* value);
249 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
251 proto_tree_set_vines(field_info *fi, const guint8* value);
253 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
255 proto_tree_set_ether(field_info *fi, const guint8* value);
257 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
259 proto_tree_set_ipxnet(field_info *fi, guint32 value);
261 proto_tree_set_ipv4(field_info *fi, guint32 value);
263 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
265 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
267 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
269 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
271 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
273 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
275 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
277 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
279 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
281 proto_tree_set_boolean(field_info *fi, guint64 value);
283 proto_tree_set_float(field_info *fi, float value);
285 proto_tree_set_double(field_info *fi, double value);
287 proto_tree_set_uint(field_info *fi, guint32 value);
289 proto_tree_set_int(field_info *fi, gint32 value);
291 proto_tree_set_uint64(field_info *fi, guint64 value);
293 proto_tree_set_int64(field_info *fi, gint64 value);
295 proto_tree_set_eui64(field_info *fi, const guint64 value);
297 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
299 /* Handle type length mismatch (now filterable) expert info */
300 static int proto_type_length_mismatch = -1;
301 static expert_field ei_type_length_mismatch_error = EI_INIT;
302 static expert_field ei_type_length_mismatch_warn = EI_INIT;
303 static void register_type_length_mismatch(void);
305 /* Handle number string decoding errors with expert info */
306 static int proto_number_string_decoding_error = -1;
307 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
308 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
309 static void register_number_string_decoding_error(void);
311 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
313 /* special-case header field used within proto.c */
314 static header_field_info hfi_text_only =
315 { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
316 int hf_text_only = -1;
318 /* Structure for information about a protocol */
320 const char *name; /* long description */
321 const char *short_name; /* short description */
322 const char *filter_name; /* name of this protocol in filters */
323 GPtrArray *fields; /* fields for this protocol */
324 int proto_id; /* field ID for this protocol */
325 gboolean is_enabled; /* TRUE if protocol is enabled */
326 gboolean enabled_by_default; /* TRUE if protocol is enabled by default */
327 gboolean can_toggle; /* TRUE if is_enabled can be changed */
328 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
329 For dissectors that need a protocol name so they
330 can be added to a dissector table, but use the
331 parent_proto_id for things like enable/disable */
332 GList *heur_list; /* Heuristic dissectors associated with this protocol */
335 /* List of all protocols */
336 static GList *protocols = NULL;
337 static GList *pino_protocols = NULL;
339 /* Deregistered fields */
340 static GPtrArray *deregistered_fields = NULL;
341 static GPtrArray *deregistered_data = NULL;
343 /* indexed by prefix, contains initializers */
344 static GHashTable* prefixes = NULL;
346 /* Contains information about a field when a dissector calls
347 * proto_tree_add_item. */
348 #define FIELD_INFO_NEW(pool, fi) fi = wmem_new(pool, field_info)
349 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
351 /* Contains the space for proto_nodes. */
352 #define PROTO_NODE_INIT(node) \
353 node->first_child = NULL; \
354 node->last_child = NULL; \
357 #define PROTO_NODE_FREE(pool, node) \
358 wmem_free(pool, node)
360 /* String space for protocol and field items for the GUI */
361 #define ITEM_LABEL_NEW(pool, il) \
362 il = wmem_new(pool, item_label_t);
363 #define ITEM_LABEL_FREE(pool, il) \
366 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
367 if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
368 g_error("Unregistered hf! index=%d", hfindex); \
369 DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
370 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
371 hfinfo = gpa_hfinfo.hfi[hfindex];
373 /* List which stores protocols and fields that have been registered */
374 typedef struct _gpa_hfinfo_t {
376 guint32 allocated_len;
377 header_field_info **hfi;
380 static gpa_hfinfo_t gpa_hfinfo;
382 /* Hash table of abbreviations and IDs */
383 static GHashTable *gpa_name_map = NULL;
384 static header_field_info *same_name_hfinfo;
386 * We're called repeatedly with the same field name when sorting a column.
387 * Cache our last gpa_name_map hit for faster lookups.
389 static char *last_field_name = NULL;
390 static header_field_info *last_hfinfo;
392 static void save_same_name_hfinfo(gpointer data)
394 same_name_hfinfo = (header_field_info*)data;
397 /* Cached value for VINES address type (used for FT_VINES) */
398 static int vines_address_type = -1;
400 /* Points to the first element of an array of bits, indexed by
401 a subtree item type; that array element is TRUE if subtrees of
402 an item of that type are to be expanded. */
403 static guint32 *tree_is_expanded;
405 /* Number of elements in that array. */
408 /* Name hashtables for fast detection of duplicate names */
409 static GHashTable* proto_names = NULL;
410 static GHashTable* proto_short_names = NULL;
411 static GHashTable* proto_filter_names = NULL;
414 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
416 const protocol_t *p1 = (const protocol_t *)p1_arg;
417 const protocol_t *p2 = (const protocol_t *)p2_arg;
419 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
424 * List of dissector plugins.
427 void (*register_protoinfo)(void); /* routine to call to register protocol information */
428 void (*reg_handoff)(void); /* routine to call to register dissector handoff */
431 static GSList *dissector_plugins = NULL;
434 * Callback for each plugin found.
437 check_for_dissector_plugin(GModule *handle)
440 void (*register_protoinfo)(void);
441 void (*reg_handoff)(void);
442 dissector_plugin *plugin;
445 * Do we have a register routine?
447 if (g_module_symbol(handle, "plugin_register", &gp)) {
449 register_protoinfo = (void (*)(void))gp;
453 register_protoinfo = NULL;
457 * Do we have a reg_handoff routine?
459 if (g_module_symbol(handle, "plugin_reg_handoff", &gp)) {
461 reg_handoff = (void (*)(void))gp;
469 * If we have neither, we're not a dissector plugin.
471 if (register_protoinfo == NULL && reg_handoff == NULL)
475 * Add this one to the list of dissector plugins.
477 plugin = (dissector_plugin *)g_malloc(sizeof (dissector_plugin));
478 plugin->register_protoinfo = register_protoinfo;
479 plugin->reg_handoff = reg_handoff;
480 dissector_plugins = g_slist_prepend(dissector_plugins, plugin);
485 register_dissector_plugin(gpointer data, gpointer user_data _U_)
487 dissector_plugin *plugin = (dissector_plugin *)data;
489 if (plugin->register_protoinfo)
490 (plugin->register_protoinfo)();
494 reg_handoff_dissector_plugin(gpointer data, gpointer user_data _U_)
496 dissector_plugin *plugin = (dissector_plugin *)data;
498 if (plugin->reg_handoff)
499 (plugin->reg_handoff)();
503 * Register dissector plugin type.
506 register_dissector_plugin_type(void)
508 add_plugin_type("dissector", check_for_dissector_plugin);
512 dissector_plugin_destroy(gpointer p)
517 #endif /* HAVE_PLUGINS */
519 /* initialize data structures and register protocols and fields */
521 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
522 void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
524 gpointer client_data)
526 proto_cleanup_base();
528 proto_names = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
529 proto_short_names = g_hash_table_new(wrs_str_hash, g_str_equal);
530 proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
533 gpa_hfinfo.allocated_len = 0;
534 gpa_hfinfo.hfi = NULL;
535 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
536 deregistered_fields = g_ptr_array_new();
537 deregistered_data = g_ptr_array_new();
539 /* Initialize the ftype subsystem */
542 /* Initialize the addres type subsystem */
543 address_types_initialize();
545 /* Register one special-case FT_TEXT_ONLY field for use when
546 converting wireshark to new-style proto_tree. These fields
547 are merely strings on the GUI tree; they are not filterable */
548 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
550 /* Register the pseudo-protocols used for exceptions. */
551 register_show_exception();
552 register_type_length_mismatch();
553 register_number_string_decoding_error();
555 /* Have each built-in dissector register its protocols, fields,
556 dissector tables, and dissectors to be called through a
557 handle, and do whatever one-time initialization it needs to
559 register_all_protocols_func(cb, client_data);
561 /* Now that the VINES dissector has registered it's address
562 type, grab the value for the field type */
563 vines_address_type = address_type_get_by_name("AT_VINES");
565 /* Now call the registration routines for all disssector
568 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
569 g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL);
572 /* Now call the "handoff registration" routines of all built-in
573 dissectors; those routines register the dissector in other
574 dissectors' handoff tables, and fetch any dissector handles
576 register_all_handoffs_func(cb, client_data);
579 /* Now do the same with plugins. */
581 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
582 g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL);
585 /* sort the protocols by protocol name */
586 protocols = g_list_sort(protocols, proto_compare_name);
588 /* We've assigned all the subtree type values; allocate the array
589 for them, and zero it out. */
590 tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
594 proto_cleanup_base(void)
596 protocol_t *protocol;
597 header_field_info *hfinfo;
599 /* Free the abbrev/ID hash table */
601 g_hash_table_destroy(gpa_name_map);
604 g_free(last_field_name);
605 last_field_name = NULL;
608 protocol = (protocol_t *)protocols->data;
609 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
610 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
612 g_slice_free(header_field_info, hfinfo);
613 if (protocol->fields) {
614 g_ptr_array_free(protocol->fields, TRUE);
616 g_list_free(protocol->heur_list);
617 protocols = g_list_remove(protocols, protocol);
621 while (pino_protocols) {
622 protocol = (protocol_t *)pino_protocols->data;
623 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
624 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
625 DISSECTOR_ASSERT(protocol->fields == NULL); //helpers should not have any registered fields
626 g_slice_free(header_field_info, hfinfo);
627 DISSECTOR_ASSERT(protocol->heur_list == NULL); //helpers should not have a heuristic list
628 pino_protocols = g_list_remove(pino_protocols, protocol);
633 g_hash_table_destroy(proto_names);
637 if (proto_short_names) {
638 g_hash_table_destroy(proto_short_names);
639 proto_short_names = NULL;
642 if (proto_filter_names) {
643 g_hash_table_destroy(proto_filter_names);
644 proto_filter_names = NULL;
647 if (gpa_hfinfo.allocated_len) {
649 gpa_hfinfo.allocated_len = 0;
650 g_free(gpa_hfinfo.hfi);
651 gpa_hfinfo.hfi = NULL;
654 if (deregistered_fields) {
655 g_ptr_array_free(deregistered_fields, FALSE);
656 deregistered_fields = NULL;
659 if (deregistered_data) {
660 g_ptr_array_free(deregistered_data, FALSE);
661 deregistered_data = NULL;
664 g_free(tree_is_expanded);
665 tree_is_expanded = NULL;
668 g_hash_table_destroy(prefixes);
674 proto_cleanup_base();
677 if (dissector_plugins) {
678 g_slist_free_full(dissector_plugins, dissector_plugin_destroy);
679 dissector_plugins = NULL;
685 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
688 proto_node *pnode = tree;
692 if (func(pnode, data))
695 child = pnode->first_child;
696 while (child != NULL) {
698 * The routine we call might modify the child, e.g. by
699 * freeing it, so we get the child's successor before
700 * calling that routine.
703 child = current->next;
704 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
712 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
715 proto_node *pnode = tree;
719 child = pnode->first_child;
720 while (child != NULL) {
722 * The routine we call might modify the child, e.g. by
723 * freeing it, so we get the child's successor before
724 * calling that routine.
727 child = current->next;
728 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
731 if (func(pnode, data))
738 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
741 proto_node *node = tree;
747 node = node->first_child;
748 while (node != NULL) {
750 node = current->next;
751 func((proto_tree *)current, data);
756 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
758 GPtrArray *ptrs = (GPtrArray *)value;
759 gint hfid = GPOINTER_TO_UINT(key);
760 header_field_info *hfinfo;
762 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
763 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
764 /* when a field is referenced by a filter this also
765 affects the refcount for the parent protocol so we need
766 to adjust the refcount for the parent as well
768 if (hfinfo->parent != -1) {
769 header_field_info *parent_hfinfo;
770 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
771 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
773 hfinfo->ref_type = HF_REF_TYPE_NONE;
776 g_ptr_array_free(ptrs, TRUE);
780 proto_tree_free_node(proto_node *node, gpointer data _U_)
782 field_info *finfo = PNODE_FINFO(node);
784 proto_tree_children_foreach(node, proto_tree_free_node, NULL);
786 FVALUE_CLEANUP(&finfo->value);
790 proto_tree_reset(proto_tree *tree)
792 tree_data_t *tree_data = PTREE_DATA(tree);
794 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
797 if (tree_data->interesting_hfids) {
798 /* Free all the GPtrArray's in the interesting_hfids hash. */
799 g_hash_table_foreach(tree_data->interesting_hfids,
800 free_GPtrArray_value, NULL);
802 /* And then remove all values. */
803 g_hash_table_remove_all(tree_data->interesting_hfids);
806 /* Reset track of the number of children */
807 tree_data->count = 0;
809 PROTO_NODE_INIT(tree);
812 /* frees the resources that the dissection a proto_tree uses */
814 proto_tree_free(proto_tree *tree)
816 tree_data_t *tree_data = PTREE_DATA(tree);
818 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
821 if (tree_data->interesting_hfids) {
822 /* Free all the GPtrArray's in the interesting_hfids hash. */
823 g_hash_table_foreach(tree_data->interesting_hfids,
824 free_GPtrArray_value, NULL);
826 /* And then destroy the hash. */
827 g_hash_table_destroy(tree_data->interesting_hfids);
830 g_slice_free(tree_data_t, tree_data);
832 g_slice_free(proto_tree, tree);
835 /* Is the parsing being done for a visible proto_tree or an invisible one?
836 * By setting this correctly, the proto_tree creation is sped up by not
837 * having to call g_vsnprintf and copy strings around.
840 proto_tree_set_visible(proto_tree *tree, gboolean visible)
842 gboolean old_visible = PTREE_DATA(tree)->visible;
844 PTREE_DATA(tree)->visible = visible;
850 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
852 PTREE_DATA(tree)->fake_protocols = fake_protocols;
855 /* Assume dissector set only its protocol fields.
856 This function is called by dissectors and allows the speeding up of filtering
857 in wireshark; if this function returns FALSE it is safe to reset tree to NULL
858 and thus skip calling most of the expensive proto_tree_add_...()
860 If the tree is visible we implicitly assume the field is referenced.
863 proto_field_is_referenced(proto_tree *tree, int proto_id)
865 register header_field_info *hfinfo;
871 if (PTREE_DATA(tree)->visible)
874 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
875 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
878 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
885 /* Finds a record in the hfinfo array by id. */
887 proto_registrar_get_nth(guint hfindex)
889 register header_field_info *hfinfo;
891 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
896 /* Prefix initialization
897 * this allows for a dissector to register a display filter name prefix
898 * so that it can delay the initialization of the hf array as long as
902 /* compute a hash for the part before the dot of a display filter */
904 prefix_hash (gconstpointer key) {
905 /* end the string at the dot and compute its hash */
906 gchar* copy = g_strdup((const gchar *)key);
917 tmp = g_str_hash(copy);
922 /* are both strings equal up to the end or the dot? */
924 prefix_equal (gconstpointer ap, gconstpointer bp) {
925 const gchar* a = (const gchar *)ap;
926 const gchar* b = (const gchar *)bp;
932 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
934 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
935 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
937 if (ac != bc) return FALSE;
943 /* Register a new prefix for "delayed" initialization of field arrays */
945 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
947 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
950 g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
953 /* helper to call all prefix initializers */
955 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
956 ((prefix_initializer_t)v)((const char *)k);
960 /** Initialize every remaining uninitialized prefix. */
962 proto_initialize_all_prefixes(void) {
963 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
966 /* Finds a record in the hfinfo array by name.
967 * If it fails to find it in the already registered fields,
968 * it tries to find and call an initializer in the prefixes
969 * table and if so it looks again.
973 proto_registrar_get_byname(const char *field_name)
975 header_field_info *hfinfo;
976 prefix_initializer_t pi;
981 if (g_strcmp0(field_name, last_field_name) == 0) {
985 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
988 g_free(last_field_name);
989 last_field_name = g_strdup(field_name);
990 last_hfinfo = hfinfo;
997 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
999 g_hash_table_remove(prefixes, field_name);
1004 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1007 g_free(last_field_name);
1008 last_field_name = g_strdup(field_name);
1009 last_hfinfo = hfinfo;
1015 proto_registrar_get_id_byname(const char *field_name)
1017 header_field_info *hfinfo;
1019 hfinfo = proto_registrar_get_byname(field_name);
1029 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1031 subtree_lvl *pushed_tree;
1033 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
1034 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
1036 pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1037 DISSECTOR_ASSERT(pushed_tree != NULL);
1038 if (ptvc->pushed_tree)
1039 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
1040 ptvc->pushed_tree = pushed_tree;
1044 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1046 ptvc->pushed_tree = NULL;
1047 ptvc->pushed_tree_max = 0;
1048 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1049 ptvc->pushed_tree_index = 0;
1052 /* Allocates an initializes a ptvcursor_t with 3 variables:
1053 * proto_tree, tvbuff, and offset. */
1055 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
1059 ptvc = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
1062 ptvc->offset = offset;
1063 ptvc->pushed_tree = NULL;
1064 ptvc->pushed_tree_max = 0;
1065 ptvc->pushed_tree_index = 0;
1070 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1072 ptvcursor_free(ptvcursor_t *ptvc)
1074 ptvcursor_free_subtree_levels(ptvc);
1078 /* Returns tvbuff. */
1080 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1085 /* Returns current offset. */
1087 ptvcursor_current_offset(ptvcursor_t *ptvc)
1089 return ptvc->offset;
1093 ptvcursor_tree(ptvcursor_t *ptvc)
1102 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1107 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1109 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1111 subtree_lvl *subtree;
1112 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1113 ptvcursor_new_subtree_levels(ptvc);
1115 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1116 subtree->tree = ptvc->tree;
1118 ptvc->pushed_tree_index++;
1119 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1122 /* pops a subtree */
1124 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1126 subtree_lvl *subtree;
1128 if (ptvc->pushed_tree_index <= 0)
1131 ptvc->pushed_tree_index--;
1132 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1133 if (subtree->it != NULL)
1134 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1136 ptvc->tree = subtree->tree;
1139 /* saves the current tvb offset and the item in the current subtree level */
1141 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1143 subtree_lvl *subtree;
1145 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1147 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1149 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1152 /* Creates a subtree and adds it to the cursor as the working tree but does not
1153 * save the old working tree */
1155 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1157 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1162 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1164 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1165 if (length == SUBTREE_UNDEFINED_LENGTH)
1166 ptvcursor_subtree_set_item(ptvc, it);
1167 return ptvcursor_tree(ptvc);
1170 /* Add an item to the tree and create a subtree
1171 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1172 * In this case, when the subtree will be closed, the parent item length will
1173 * be equal to the advancement of the cursor since the creation of the subtree.
1176 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1177 const guint encoding, gint ett_subtree)
1181 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1182 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1186 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1188 /* Add a text node to the tree and create a subtree
1189 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1190 * In this case, when the subtree will be closed, the item length will be equal
1191 * to the advancement of the cursor since the creation of the subtree.
1194 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1195 gint ett_subtree, const char *format, ...)
1199 header_field_info *hfinfo;
1202 tree = ptvcursor_tree(ptvc);
1204 CHECK_FOR_NULL_TREE(tree);
1206 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1208 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1209 ptvcursor_current_offset(ptvc), length);
1211 TRY_TO_FAKE_THIS_REPR(pi);
1213 va_start(ap, format);
1214 proto_tree_set_representation(pi, format, ap);
1217 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1220 /* Add a text-only node, leaving it to our caller to fill the text in */
1222 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1229 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1234 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1236 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1237 const char *format, ...)
1241 header_field_info *hfinfo;
1244 /* If we're fetching until the end of the TVB, only validate
1245 * that the offset is within range.
1249 tvb_ensure_bytes_exist(tvb, start, length);
1251 CHECK_FOR_NULL_TREE(tree);
1253 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1255 pi = proto_tree_add_text_node(tree, tvb, start, length);
1257 TRY_TO_FAKE_THIS_REPR(pi);
1259 va_start(ap, format);
1260 proto_tree_set_representation(pi, format, ap);
1266 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1268 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1269 gint length, const char *format, va_list ap)
1272 header_field_info *hfinfo;
1275 /* If we're fetching until the end of the TVB, only validate
1276 * that the offset is within range.
1280 tvb_ensure_bytes_exist(tvb, start, length);
1282 CHECK_FOR_NULL_TREE(tree);
1284 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1286 pi = proto_tree_add_text_node(tree, tvb, start, length);
1288 TRY_TO_FAKE_THIS_REPR(pi);
1290 proto_tree_set_representation(pi, format, ap);
1295 /* Add a text-only node that creates a subtree underneath.
1298 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1300 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1303 /* Add a text-only node that creates a subtree underneath.
1306 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1312 va_start(ap, format);
1313 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1316 if (tree_item != NULL)
1319 pt = proto_item_add_subtree(pi, idx);
1324 /* Add a text-only node for debugging purposes. The caller doesn't need
1325 * to worry about tvbuff, start, or length. Debug message gets sent to
1328 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1333 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1336 va_start(ap, format);
1337 proto_tree_set_representation(pi, format, ap);
1340 va_start(ap, format);
1341 vprintf(format, ap);
1343 ws_debug_printf("\n");
1349 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1352 header_field_info *hfinfo;
1354 CHECK_FOR_NULL_TREE(tree);
1356 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1358 pi = proto_tree_add_text_node(tree, tvb, start, length);
1360 TRY_TO_FAKE_THIS_REPR(pi);
1362 proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1368 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1371 header_field_info *hfinfo;
1374 CHECK_FOR_NULL_TREE(tree);
1376 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1378 pi = proto_tree_add_text_node(tree, tvb, start, length);
1380 TRY_TO_FAKE_THIS_REPR(pi);
1382 str = tvb_format_text_wsp(NULL, tvb, start, length);
1383 proto_item_set_text(pi, "%s", str);
1384 wmem_free(NULL, str);
1389 void proto_report_dissector_bug(const char *message)
1391 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1394 THROW_MESSAGE(DissectorError, message);
1397 /* We could probably get away with changing is_error to a minimum length value. */
1399 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1402 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1404 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1408 THROW(ReportedBoundsError);
1413 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1416 gboolean length_error;
1421 value = tvb_get_guint8(tvb, offset);
1425 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1426 : tvb_get_ntohs(tvb, offset);
1430 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1431 : tvb_get_ntoh24(tvb, offset);
1435 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1436 : tvb_get_ntohl(tvb, offset);
1441 length_error = TRUE;
1444 length_error = FALSE;
1445 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1446 : tvb_get_ntohl(tvb, offset);
1448 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1454 static inline guint64
1455 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1458 gboolean length_error;
1463 value = tvb_get_guint8(tvb, offset);
1467 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1468 : tvb_get_ntohs(tvb, offset);
1472 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1473 : tvb_get_ntoh24(tvb, offset);
1477 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1478 : tvb_get_ntohl(tvb, offset);
1482 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1483 : tvb_get_ntoh40(tvb, offset);
1487 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1488 : tvb_get_ntoh48(tvb, offset);
1492 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1493 : tvb_get_ntoh56(tvb, offset);
1497 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1498 : tvb_get_ntoh64(tvb, offset);
1503 length_error = TRUE;
1506 length_error = FALSE;
1507 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1508 : tvb_get_ntoh64(tvb, offset);
1510 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1517 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1520 gboolean length_error;
1525 value = (gint8)tvb_get_guint8(tvb, offset);
1529 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1530 : tvb_get_ntohs(tvb, offset));
1534 value = encoding ? tvb_get_letoh24(tvb, offset)
1535 : tvb_get_ntoh24(tvb, offset);
1536 if (value & 0x00800000) {
1537 /* Sign bit is set; sign-extend it. */
1538 value |= 0xFF000000;
1543 value = encoding ? tvb_get_letohl(tvb, offset)
1544 : tvb_get_ntohl(tvb, offset);
1549 length_error = TRUE;
1552 length_error = FALSE;
1553 value = encoding ? tvb_get_letohl(tvb, offset)
1554 : tvb_get_ntohl(tvb, offset);
1556 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1562 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1563 * be cast-able as a gint64. This is weird, but what the code has always done.
1565 static inline guint64
1566 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1568 guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1573 value = ws_sign_ext64(value, 56);
1576 value = ws_sign_ext64(value, 48);
1579 value = ws_sign_ext64(value, 40);
1582 value = ws_sign_ext64(value, 32);
1585 value = ws_sign_ext64(value, 24);
1588 value = ws_sign_ext64(value, 16);
1591 value = ws_sign_ext64(value, 8);
1599 static inline const guint8 *
1600 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1601 gint length, gint *ret_length, const guint encoding)
1604 length = tvb_ensure_captured_length_remaining(tvb, start);
1606 *ret_length = length;
1607 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1610 /* For FT_STRINGZ */
1611 static inline const guint8 *
1612 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1613 gint start, gint length, gint *ret_length, const guint encoding)
1615 const guint8 *value;
1618 report_type_length_mismatch(tree, "a string", length, TRUE);
1621 /* This can throw an exception */
1622 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1623 } else if (length == 0) {
1626 /* In this case, length signifies the length of the string.
1628 * This could either be a null-padded string, which doesn't
1629 * necessarily have a '\0' at the end, or a null-terminated
1630 * string, with a trailing '\0'. (Yes, there are cases
1631 * where you have a string that's both counted and null-
1634 * In the first case, we must allocate a buffer of length
1635 * "length+1", to make room for a trailing '\0'.
1637 * In the second case, we don't assume that there is a
1638 * trailing '\0' there, as the packet might be malformed.
1639 * (XXX - should we throw an exception if there's no
1640 * trailing '\0'?) Therefore, we allocate a buffer of
1641 * length "length+1", and put in a trailing '\0', just to
1644 * (XXX - this would change if we made string values counted
1645 * rather than null-terminated.)
1647 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1649 *ret_length = length;
1653 /* For FT_UINT_STRING */
1654 static inline const guint8 *
1655 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1656 tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1657 const guint encoding)
1660 const guint8 *value;
1662 /* I believe it's ok if this is called with a NULL tree */
1663 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1664 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1666 *ret_length = length;
1670 /* For FT_STRINGZPAD */
1671 static inline const guint8 *
1672 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1673 gint length, gint *ret_length, const guint encoding)
1676 * XXX - currently, string values are null-
1677 * terminated, so a "zero-padded" string
1678 * isn't special. If we represent string
1679 * values as something that includes a counted
1680 * array of bytes, we'll need to strip
1684 length = tvb_ensure_captured_length_remaining(tvb, start);
1686 *ret_length = length;
1687 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1691 * Epochs for various non-UN*X time stamp formats.
1693 #define NTP_BASETIME G_GUINT64_CONSTANT(2208988800) /* NTP */
1694 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800) /* System/3x0 and z/Architecture TOD clock */
1696 /* this can be called when there is no tree, so tree may be null */
1698 get_time_value(proto_tree *tree, tvbuff_t *tvb, const gint start,
1699 const gint length, const guint encoding, nstime_t *time_stamp,
1700 const gboolean is_relative)
1707 case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1709 * 4-byte seconds, followed by 4-byte fractional
1710 * time in nanoseconds, both big-endian.
1711 * For absolute times, the seconds are seconds
1712 * since the UN*X epoch.
1714 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1716 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1717 else if (length == 4) {
1719 * Backwards compatibility.
1721 time_stamp->nsecs = 0;
1723 report_type_length_mismatch(tree, "a timespec", length, TRUE);
1726 case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1728 * 4-byte UNIX epoch, possibly followed by
1729 * 4-byte fractional time in nanoseconds,
1730 * both little-endian.
1731 * For absolute times, the seconds are seconds
1732 * since the UN*X epoch.
1734 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1736 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1737 else if (length == 4) {
1739 * Backwards compatibility.
1741 time_stamp->nsecs = 0;
1743 report_type_length_mismatch(tree, "a timespec", length, TRUE);
1746 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1748 * NTP time stamp, big-endian.
1749 * Only supported for absolute times.
1751 DISSECTOR_ASSERT(!is_relative);
1753 /* We need a temporary variable here so the unsigned math
1754 * works correctly (for years > 2036 according to RFC 2030
1757 tmpsecs = tvb_get_ntohl(tvb, start);
1759 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1761 time_stamp->secs = tmpsecs; /* 0 */
1765 * Convert 1/2^32s of a second to nanoseconds.
1767 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1768 } else if (length == 4) {
1770 * Backwards compatibility.
1772 time_stamp->nsecs = 0;
1774 report_type_length_mismatch(tree, "an NTP time stamp", length, TRUE);
1777 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1779 * NTP time stamp, little-endian.
1780 * Only supported for absolute times.
1782 DISSECTOR_ASSERT(!is_relative);
1784 tmpsecs = tvb_get_letohl(tvb, start);
1786 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1788 time_stamp->secs = tmpsecs; /* 0 */
1792 * Convert 1/2^32s of a second to nanoseconds.
1794 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1795 } else if (length == 4) {
1797 * Backwards compatibility.
1799 time_stamp->nsecs = 0;
1801 report_type_length_mismatch(tree, "an NTP time stamp", length, TRUE);
1804 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1806 * S/3x0 and z/Architecture TOD clock time stamp,
1808 * Only supported for absolute times.
1810 DISSECTOR_ASSERT(!is_relative);
1811 DISSECTOR_ASSERT(length == 8);
1814 todsecs = tvb_get_ntoh64(tvb, start) >> 12;
1815 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1816 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1818 report_type_length_mismatch(tree, "a TOD clock time stamp", length, TRUE);
1821 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1823 * S/3x0 and z/Architecture TOD clock time stamp,
1825 * Only supported for absolute times.
1827 DISSECTOR_ASSERT(!is_relative);
1830 todsecs = tvb_get_letoh64(tvb, start) >> 12 ;
1831 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1832 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1834 report_type_length_mismatch(tree, "a TOD clock time stamp", length, TRUE);
1837 case ENC_TIME_RTPS|ENC_BIG_ENDIAN:
1839 * Time stamp using the same seconds/fraction format
1840 * as NTP, but with the origin of the time stamp being
1841 * the UNIX epoch rather than the NTP epoch; big-
1844 * Only supported for absolute times.
1846 DISSECTOR_ASSERT(!is_relative);
1849 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1851 * Convert 1/2^32s of a second to nanoseconds.
1853 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1855 report_type_length_mismatch(tree, "an RTPS time stamp", length, TRUE);
1858 case ENC_TIME_RTPS|ENC_LITTLE_ENDIAN:
1860 * Time stamp using the same seconds/fraction format
1861 * as NTP, but with the origin of the time stamp being
1862 * the UNIX epoch rather than the NTP epoch; little-
1865 * Only supported for absolute times.
1867 DISSECTOR_ASSERT(!is_relative);
1870 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1872 * Convert 1/2^32s of a second to nanoseconds.
1874 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1876 report_type_length_mismatch(tree, "an RTPS time stamp", length, TRUE);
1879 case ENC_TIME_TIMEVAL|ENC_BIG_ENDIAN:
1881 * 4-byte seconds, followed by 4-byte fractional
1882 * time in microseconds, both big-endian.
1883 * For absolute times, the seconds are seconds
1884 * since the UN*X epoch.
1887 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1888 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
1890 report_type_length_mismatch(tree, "a timeval", length, TRUE);
1893 case ENC_TIME_TIMEVAL|ENC_LITTLE_ENDIAN:
1895 * 4-byte seconds, followed by 4-byte fractional
1896 * time in microseconds, both little-endian.
1897 * For absolute times, the seconds are seconds
1898 * since the UN*X epoch.
1901 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1902 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
1904 report_type_length_mismatch(tree, "a timeval", length, TRUE);
1907 case ENC_TIME_SECS|ENC_BIG_ENDIAN:
1908 case ENC_TIME_SECS|ENC_LITTLE_ENDIAN:
1910 * Seconds, 1 to 8 bytes.
1911 * For absolute times, it's seconds since the
1914 if (length >= 1 && length <= 8) {
1915 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
1916 time_stamp->nsecs = 0;
1918 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, TRUE);
1921 case ENC_TIME_MSECS|ENC_BIG_ENDIAN:
1923 * Milliseconds, 1 to 8 bytes.
1924 * For absolute times, it's milliseconds since the
1927 if (length >= 1 && length <= 8) {
1930 msecs = get_uint64_value(tree, tvb, start, length, encoding);
1931 time_stamp->secs = (time_t)(msecs / 1000);
1932 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
1934 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, TRUE);
1937 case ENC_TIME_RFC_3971|ENC_BIG_ENDIAN:
1939 * 1/64ths of a second since the UN*X epoch,
1942 * Only supported for absolute times.
1944 DISSECTOR_ASSERT(!is_relative);
1948 * The upper 48 bits are seconds since the
1951 time_stamp->secs = tvb_get_ntoh48(tvb, start);
1953 * The lower 16 bits are 1/2^16s of a second;
1954 * convert them to nanoseconds.
1956 * XXX - this may give the impression of higher
1957 * precision than you actually get.
1959 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
1961 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, TRUE);
1964 case ENC_TIME_RFC_3971|ENC_LITTLE_ENDIAN:
1966 * 1/64ths of a second since the UN*X epoch,
1969 * Only supported for absolute times.
1971 DISSECTOR_ASSERT(!is_relative);
1975 * XXX - this is assuming that, if anybody
1976 * were ever to use this format - RFC 3971
1977 * doesn't, because that's an Internet
1978 * protocol, and those use network byte
1979 * order, i.e. big-endian - they'd treat it
1980 * as a 64-bit count of 1/2^16s of a second,
1981 * putting the upper 48 bits at the end.
1983 * The lower 48 bits are seconds since the
1986 time_stamp->secs = tvb_get_letoh48(tvb, start+2);
1988 * The upper 16 bits are 1/2^16s of a second;
1989 * convert them to nanoseconds.
1991 * XXX - this may give the impression of higher
1992 * precision than you actually get.
1994 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
1996 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, TRUE);
1999 case ENC_TIME_SECS_NTP|ENC_BIG_ENDIAN:
2001 * NTP time stamp, with 1-second resolution (i.e.,
2002 * seconds since the NTP epoch), big-endian.
2003 * Only supported for absolute times.
2005 DISSECTOR_ASSERT(!is_relative);
2009 * We need a temporary variable here so the
2010 * unsigned math works correctly (for
2011 * years > 2036 according to RFC 2030
2014 tmpsecs = tvb_get_ntohl(tvb, start);
2016 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
2018 time_stamp->secs = tmpsecs; /* 0 */
2019 time_stamp->nsecs = 0;
2021 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, TRUE);
2024 case ENC_TIME_SECS_NTP|ENC_LITTLE_ENDIAN:
2026 * NTP time stamp, with 1-second resolution (i.e.,
2027 * seconds since the NTP epoch), little-endian.
2028 * Only supported for absolute times.
2030 DISSECTOR_ASSERT(!is_relative);
2033 tmpsecs = tvb_get_letohl(tvb, start);
2035 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
2037 time_stamp->secs = tmpsecs; /* 0 */
2038 time_stamp->nsecs = 0;
2040 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, TRUE);
2042 case ENC_TIME_MSEC_NTP | ENC_BIG_ENDIAN:
2044 * Milliseconds, 1 to 8 bytes.
2045 * For absolute times, it's milliseconds since the
2048 if (length >= 1 && length <= 8) {
2051 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2052 tmpsecs = (guint32)(msecs / 1000);
2053 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
2054 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2057 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, TRUE);
2060 DISSECTOR_ASSERT_NOT_REACHED();
2066 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2068 const header_field_info *hfinfo = fi->hfinfo;
2070 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
2071 GPtrArray *ptrs = NULL;
2073 if (tree_data->interesting_hfids == NULL) {
2074 /* Initialize the hash because we now know that it is needed */
2075 tree_data->interesting_hfids =
2076 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
2077 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2078 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2079 GINT_TO_POINTER(hfinfo->id));
2083 /* First element triggers the creation of pointer array */
2084 ptrs = g_ptr_array_new();
2085 g_hash_table_insert(tree_data->interesting_hfids,
2086 GINT_TO_POINTER(hfinfo->id), ptrs);
2089 g_ptr_array_add(ptrs, fi);
2093 /* Add an item to a proto_tree, using the text label registered to that item;
2094 the item is extracted from the tvbuff handed to it. */
2096 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2097 tvbuff_t *tvb, gint start, gint length,
2104 const char *stringval;
2105 nstime_t time_stamp;
2106 gboolean length_error;
2108 switch (new_fi->hfinfo->type) {
2110 /* no value to set for FT_NONE */
2114 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
2118 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2123 * Map all non-zero values to little-endian for
2124 * backwards compatibility.
2127 encoding = ENC_LITTLE_ENDIAN;
2128 n = get_uint_value(tree, tvb, start, length, encoding);
2129 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2131 /* Instead of calling proto_item_set_len(), since we don't yet
2132 * have a proto_item, we set the field_info's length ourselves. */
2133 new_fi->length = n + length;
2138 * Map all non-zero values to little-endian for
2139 * backwards compatibility.
2142 encoding = ENC_LITTLE_ENDIAN;
2143 proto_tree_set_boolean(new_fi,
2144 get_uint64_value(tree, tvb, start, length, encoding));
2148 /* XXX - make these just FT_UINT? */
2154 * Map all non-zero values to little-endian for
2155 * backwards compatibility.
2158 encoding = ENC_LITTLE_ENDIAN;
2159 proto_tree_set_uint(new_fi,
2160 get_uint_value(tree, tvb, start, length, encoding));
2168 * Map all non-zero values to little-endian for
2169 * backwards compatibility.
2172 encoding = ENC_LITTLE_ENDIAN;
2173 proto_tree_set_uint64(new_fi,
2174 get_uint64_value(tree, tvb, start, length, encoding));
2177 /* XXX - make these just FT_INT? */
2183 * Map all non-zero values to little-endian for
2184 * backwards compatibility.
2187 encoding = ENC_LITTLE_ENDIAN;
2188 proto_tree_set_int(new_fi,
2189 get_int_value(tree, tvb, start, length, encoding));
2197 * Map all non-zero values to little-endian for
2198 * backwards compatibility.
2201 encoding = ENC_LITTLE_ENDIAN;
2202 proto_tree_set_int64(new_fi,
2203 get_int64_value(tree, tvb, start, length, encoding));
2208 * Map all non-zero values to little-endian for
2209 * backwards compatibility.
2212 encoding = ENC_LITTLE_ENDIAN;
2213 if (length != FT_IPv4_LEN) {
2214 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
2215 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2217 value = tvb_get_ipv4(tvb, start);
2219 * NOTE: to support code written when
2220 * proto_tree_add_item() took a gboolean as its
2221 * last argument, with FALSE meaning "big-endian"
2222 * and TRUE meaning "little-endian", we treat any
2223 * non-zero value of "encoding" as meaning
2226 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
2230 if (length != FT_IPXNET_LEN) {
2231 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
2232 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2234 proto_tree_set_ipxnet(new_fi,
2235 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
2239 if (length != FT_IPv6_LEN) {
2240 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
2241 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2243 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2247 if (length != FT_FCWWN_LEN) {
2248 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2249 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2251 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2256 length_error = length < 7 ? TRUE : FALSE;
2257 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2259 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2263 if (length != VINES_ADDR_LEN) {
2264 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2265 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2267 proto_tree_set_vines_tvb(new_fi, tvb, start);
2271 if (length != FT_ETHER_LEN) {
2272 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2273 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2275 proto_tree_set_ether_tvb(new_fi, tvb, start);
2280 * Map all non-zero values to little-endian for
2281 * backwards compatibility.
2284 encoding = ENC_LITTLE_ENDIAN;
2285 if (length != FT_EUI64_LEN) {
2286 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2287 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2289 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2293 * Map all non-zero values to little-endian for
2294 * backwards compatibility.
2297 encoding = ENC_LITTLE_ENDIAN;
2298 if (length != FT_GUID_LEN) {
2299 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2300 report_type_length_mismatch(tree, "a GUID", length, length_error);
2302 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2307 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2311 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2316 * NOTE: to support code written when
2317 * proto_tree_add_item() took a gboolean as its
2318 * last argument, with FALSE meaning "big-endian"
2319 * and TRUE meaning "little-endian", we treat any
2320 * non-zero value of "encoding" as meaning
2323 * At some point in the future, we might
2324 * support non-IEEE-binary floating-point
2325 * formats in the encoding as well
2326 * (IEEE decimal, System/3x0, VAX).
2329 encoding = ENC_LITTLE_ENDIAN;
2331 length_error = length < 4 ? TRUE : FALSE;
2332 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2335 floatval = tvb_get_letohieee_float(tvb, start);
2337 floatval = tvb_get_ntohieee_float(tvb, start);
2338 proto_tree_set_float(new_fi, floatval);
2343 * NOTE: to support code written when
2344 * proto_tree_add_item() took a gboolean as its
2345 * last argument, with FALSE meaning "big-endian"
2346 * and TRUE meaning "little-endian", we treat any
2347 * non-zero value of "encoding" as meaning
2350 * At some point in the future, we might
2351 * support non-IEEE-binary floating-point
2352 * formats in the encoding as well
2353 * (IEEE decimal, System/3x0, VAX).
2355 if (encoding == TRUE)
2356 encoding = ENC_LITTLE_ENDIAN;
2358 length_error = length < 8 ? TRUE : FALSE;
2359 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2362 doubleval = tvb_get_letohieee_double(tvb, start);
2364 doubleval = tvb_get_ntohieee_double(tvb, start);
2365 proto_tree_set_double(new_fi, doubleval);
2369 stringval = get_string_value(wmem_packet_scope(),
2370 tvb, start, length, &length, encoding);
2371 proto_tree_set_string(new_fi, stringval);
2373 /* Instead of calling proto_item_set_len(), since we
2374 * don't yet have a proto_item, we set the
2375 * field_info's length ourselves.
2377 * XXX - our caller can't use that length to
2378 * advance an offset unless they arrange that
2379 * there always be a protocol tree into which
2380 * we're putting this item.
2382 new_fi->length = length;
2386 stringval = get_stringz_value(wmem_packet_scope(),
2387 tree, tvb, start, length, &length, encoding);
2388 proto_tree_set_string(new_fi, stringval);
2390 /* Instead of calling proto_item_set_len(),
2391 * since we don't yet have a proto_item, we
2392 * set the field_info's length ourselves.
2394 * XXX - our caller can't use that length to
2395 * advance an offset unless they arrange that
2396 * there always be a protocol tree into which
2397 * we're putting this item.
2399 new_fi->length = length;
2402 case FT_UINT_STRING:
2404 * NOTE: to support code written when
2405 * proto_tree_add_item() took a gboolean as its
2406 * last argument, with FALSE meaning "big-endian"
2407 * and TRUE meaning "little-endian", if the
2408 * encoding value is TRUE, treat that as
2409 * ASCII with a little-endian length.
2411 * This won't work for code that passes
2412 * arbitrary non-zero values; that code
2413 * will need to be fixed.
2415 if (encoding == TRUE)
2416 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2417 stringval = get_uint_string_value(wmem_packet_scope(),
2418 tree, tvb, start, length, &length, encoding);
2419 proto_tree_set_string(new_fi, stringval);
2421 /* Instead of calling proto_item_set_len(), since we
2422 * don't yet have a proto_item, we set the
2423 * field_info's length ourselves.
2425 * XXX - our caller can't use that length to
2426 * advance an offset unless they arrange that
2427 * there always be a protocol tree into which
2428 * we're putting this item.
2430 new_fi->length = length;
2434 stringval = get_stringzpad_value(wmem_packet_scope(),
2435 tvb, start, length, &length, encoding);
2436 proto_tree_set_string(new_fi, stringval);
2438 /* Instead of calling proto_item_set_len(), since we
2439 * don't yet have a proto_item, we set the
2440 * field_info's length ourselves.
2442 * XXX - our caller can't use that length to
2443 * advance an offset unless they arrange that
2444 * there always be a protocol tree into which
2445 * we're putting this item.
2447 new_fi->length = length;
2450 case FT_ABSOLUTE_TIME:
2452 * Absolute times can be in any of a number of
2453 * formats, and they can be big-endian or
2456 * Historically FT_TIMEs were only timespecs;
2457 * the only question was whether they were stored
2458 * in big- or little-endian format.
2460 * For backwards compatibility, we interpret an
2461 * encoding of 1 as meaning "little-endian timespec",
2462 * so that passing TRUE is interpreted as that.
2464 if (encoding == TRUE)
2465 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2467 if (length > 8 || length < 4) {
2468 length_error = length < 4 ? TRUE : FALSE;
2469 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2472 get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
2474 proto_tree_set_time(new_fi, &time_stamp);
2477 case FT_RELATIVE_TIME:
2479 * Relative times can be in any of a number of
2480 * formats, and they can be big-endian or
2483 * Historically FT_TIMEs were only timespecs;
2484 * the only question was whether they were stored
2485 * in big- or little-endian format.
2487 * For backwards compatibility, we interpret an
2488 * encoding of 1 as meaning "little-endian timespec",
2489 * so that passing TRUE is interpreted as that.
2491 if (encoding == TRUE)
2492 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2494 if (length != 8 && length != 4) {
2495 length_error = length < 4 ? TRUE : FALSE;
2496 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2499 get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
2501 proto_tree_set_time(new_fi, &time_stamp);
2503 case FT_IEEE_11073_SFLOAT:
2505 encoding = ENC_LITTLE_ENDIAN;
2507 length_error = length < 2 ? TRUE : FALSE;
2508 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2511 fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2514 case FT_IEEE_11073_FLOAT:
2516 encoding = ENC_LITTLE_ENDIAN;
2518 length_error = length < 4 ? TRUE : FALSE;
2519 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2524 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2525 new_fi->hfinfo->type,
2526 ftype_name(new_fi->hfinfo->type));
2527 DISSECTOR_ASSERT_NOT_REACHED();
2530 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2532 /* Don't add new node to proto_tree until now so that any exceptions
2533 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2534 /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2535 * to know which item caused exception? */
2536 pi = proto_tree_add_node(tree, new_fi);
2542 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2543 const gint start, gint length,
2544 const guint encoding, gint32 *retval)
2546 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2550 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2552 switch (hfinfo->type){
2559 DISSECTOR_ASSERT_NOT_REACHED();
2562 /* length validation for native number encoding caught by get_uint_value() */
2563 /* length has to be -1 or > 0 regardless of encoding */
2564 if (length < -1 || length == 0)
2565 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2566 "Invalid length %d passed to proto_tree_add_item_ret_int",
2569 if (encoding & ENC_STRING) {
2570 REPORT_DISSECTOR_BUG("wrong encoding");
2572 /* I believe it's ok if this is called with a NULL tree */
2573 value = get_int_value(tree, tvb, start, length, encoding);
2578 if (hfinfo->bitmask) {
2579 /* Mask out irrelevant portions */
2580 *retval &= (guint32)(hfinfo->bitmask);
2582 *retval >>= hfinfo_bitshift(hfinfo);
2584 no_of_bits = ws_count_ones(hfinfo->bitmask);
2585 *retval = ws_sign_ext32(*retval, no_of_bits);
2588 CHECK_FOR_NULL_TREE(tree);
2590 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2592 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2594 proto_tree_set_int(new_fi, value);
2596 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2598 return proto_tree_add_node(tree, new_fi);
2602 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2603 const gint start, gint length,
2604 const guint encoding, guint32 *retval)
2606 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2610 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2612 switch (hfinfo->type){
2620 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2621 "field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2625 /* length validation for native number encoding caught by get_uint_value() */
2626 /* length has to be -1 or > 0 regardless of encoding */
2627 if (length < -1 || length == 0)
2628 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2629 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2632 if (encoding & ENC_STRING) {
2633 REPORT_DISSECTOR_BUG("wrong encoding");
2635 /* I believe it's ok if this is called with a NULL tree */
2636 /* XXX - modify if we ever support EBCDIC FT_CHAR */
2637 value = get_uint_value(tree, tvb, start, length, encoding);
2641 if (hfinfo->bitmask) {
2642 /* Mask out irrelevant portions */
2643 *retval &= (guint32)(hfinfo->bitmask);
2645 *retval >>= hfinfo_bitshift(hfinfo);
2649 CHECK_FOR_NULL_TREE(tree);
2651 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2653 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2655 proto_tree_set_uint(new_fi, value);
2657 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2659 return proto_tree_add_node(tree, new_fi);
2663 proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2664 const gint start, gint length, const guint encoding, guint64 *retval)
2666 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2670 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2672 if (hfinfo->type != FT_UINT64) {
2673 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2674 "field %s is not of type FT_UINT64", hfinfo->abbrev));
2677 /* length validation for native number encoding caught by get_uint64_value() */
2678 /* length has to be -1 or > 0 regardless of encoding */
2679 if (length < -1 || length == 0)
2680 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2681 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2684 if (encoding & ENC_STRING) {
2685 REPORT_DISSECTOR_BUG("wrong encoding");
2687 /* I believe it's ok if this is called with a NULL tree */
2688 value = get_uint64_value(tree, tvb, start, length, encoding);
2692 if (hfinfo->bitmask) {
2693 /* Mask out irrelevant portions */
2694 *retval &= hfinfo->bitmask;
2696 *retval >>= hfinfo_bitshift(hfinfo);
2700 CHECK_FOR_NULL_TREE(tree);
2702 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2704 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2706 proto_tree_set_uint64(new_fi, value);
2708 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2710 return proto_tree_add_node(tree, new_fi);
2714 proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2715 const gint start, gint length,
2716 const guint encoding, gboolean *retval)
2718 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2720 guint64 value, bitval;
2722 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2724 if (hfinfo->type != FT_BOOLEAN) {
2725 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2726 "field %s is not of type FT_BOOLEAN", hfinfo->abbrev));
2729 /* length validation for native number encoding caught by get_uint64_value() */
2730 /* length has to be -1 or > 0 regardless of encoding */
2731 if (length < -1 || length == 0)
2732 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2733 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2736 if (encoding & ENC_STRING) {
2737 REPORT_DISSECTOR_BUG("wrong encoding");
2739 /* I believe it's ok if this is called with a NULL tree */
2740 value = get_uint64_value(tree, tvb, start, length, encoding);
2744 if (hfinfo->bitmask) {
2745 /* Mask out irrelevant portions */
2746 bitval &= hfinfo->bitmask;
2748 *retval = (bitval != 0);
2751 CHECK_FOR_NULL_TREE(tree);
2753 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2755 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2757 proto_tree_set_boolean(new_fi, value);
2759 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2761 return proto_tree_add_node(tree, new_fi);
2765 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
2767 const gint start, gint length,
2768 const guint encoding,
2769 wmem_allocator_t *scope,
2770 const guint8 **retval,
2773 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2775 const guint8 *value;
2777 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2779 switch (hfinfo->type){
2781 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
2784 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
2786 case FT_UINT_STRING:
2787 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
2790 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
2793 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2794 "field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, or FT_STRINGZPAD",
2801 CHECK_FOR_NULL_TREE(tree);
2803 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2805 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
2807 proto_tree_set_string(new_fi, value);
2809 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2811 return proto_tree_add_node(tree, new_fi);
2815 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2816 const gint start, gint length,
2817 const guint encoding, wmem_allocator_t *scope,
2818 const guint8 **retval)
2820 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
2821 tvb, start, length, encoding, scope, retval, &length);
2825 * Validates that field length bytes are available starting from
2826 * start (pos/neg). Throws an exception if they aren't.
2829 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2830 gint start, gint length)
2837 if (hfinfo->type == FT_STRINGZ) {
2838 /* If we're fetching until the end of the TVB, only validate
2839 * that the offset is within range.
2845 tvb_ensure_bytes_exist(tvb, start, size);
2848 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2849 and returns proto_item* */
2851 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
2852 const guint encoding)
2855 header_field_info *hfinfo;
2859 offset = ptvc->offset;
2860 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2861 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
2862 test_length(hfinfo, ptvc->tvb, offset, item_length);
2864 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2865 item_length, encoding);
2867 CHECK_FOR_NULL_TREE(ptvc->tree);
2869 /* Coast clear. Try and fake it */
2870 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2872 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2874 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2875 offset, length, encoding);
2878 /* Add an item to a proto_tree, using the text label registered to that item;
2879 the item is extracted from the tvbuff handed to it. */
2881 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
2882 const gint start, gint length, const guint encoding)
2887 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2889 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2890 test_length(hfinfo, tvb, start, item_length);
2892 CHECK_FOR_NULL_TREE(tree);
2894 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2896 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2898 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2902 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2903 const gint start, gint length, const guint encoding)
2905 register header_field_info *hfinfo;
2907 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2908 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
2911 /* Add an item to a proto_tree, using the text label registered to that item;
2912 the item is extracted from the tvbuff handed to it.
2914 Return the length of the item through the pointer. */
2916 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
2917 tvbuff_t *tvb, const gint start,
2918 gint length, const guint encoding,
2925 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2927 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2928 test_length(hfinfo, tvb, start, item_length);
2932 * We need to get the correct item length here.
2933 * That's normally done by proto_tree_new_item(),
2934 * but we won't be calling it.
2936 *lenretval = get_full_length(hfinfo, tvb, start, length,
2937 item_length, encoding);
2941 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
2943 * Even if the tree item is not referenced (and thus faked),
2944 * the caller must still be informed of the actual length.
2946 *lenretval = get_full_length(hfinfo, tvb, start, length,
2947 item_length, encoding);
2950 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2952 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2953 *lenretval = new_fi->length;
2958 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2959 const gint start, gint length,
2960 const guint encoding, gint *lenretval)
2962 register header_field_info *hfinfo;
2964 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2965 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
2968 /* which FT_ types can use proto_tree_add_bytes_item() */
2969 static inline gboolean
2970 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
2972 return (type == FT_BYTES ||
2973 type == FT_UINT_BYTES ||
2975 type == FT_REL_OID ||
2976 type == FT_SYSTEM_ID );
2979 /* Note: this does no validation that the byte array of an FT_OID or
2980 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
2981 so I think it's ok to continue not validating it?
2984 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2985 const gint start, gint length, const guint encoding,
2986 GByteArray *retval, gint *endoff, gint *err)
2989 GByteArray *bytes = retval;
2990 GByteArray *created_bytes = NULL;
2993 header_field_info *hfinfo;
2994 gboolean generate = (bytes || tree) ? TRUE : FALSE;
2996 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2998 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3000 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
3001 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
3003 /* length has to be -1 or > 0 regardless of encoding */
3004 /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
3005 if (length < -1 || length == 0) {
3006 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
3007 "Invalid length %d passed to proto_tree_add_bytes_item for %s",
3008 length, ftype_name(hfinfo->type)));
3011 if (encoding & ENC_STR_NUM) {
3012 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
3015 if (generate && (encoding & ENC_STR_HEX)) {
3016 if (hfinfo->type == FT_UINT_BYTES) {
3017 /* can't decode FT_UINT_BYTES from strings */
3018 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
3019 "FT_UINT_BYTES type, but as ENC_STR_HEX");
3023 /* caller doesn't care about return value, but we need it to
3024 call tvb_get_string_bytes() and set the tree later */
3025 bytes = created_bytes = g_byte_array_new();
3028 /* bytes might be NULL after this, but can't add expert error until later */
3029 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
3031 /* grab the errno now before it gets overwritten */
3034 else if (generate) {
3035 tvb_ensure_bytes_exist(tvb, start, length);
3038 /* caller doesn't care about return value, but we need it to
3039 call tvb_get_string_bytes() and set the tree later */
3040 bytes = created_bytes = g_byte_array_new();
3043 if (hfinfo->type == FT_UINT_BYTES) {
3044 n = length; /* n is now the "header" length */
3045 length = get_uint_value(tree, tvb, start, n, encoding);
3046 /* length is now the value's length; only store the value in the array */
3047 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
3049 else if (length > 0) {
3050 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
3054 *endoff = start + n + length;
3057 if (err) *err = saved_err;
3059 CHECK_FOR_NULL_TREE_AND_FREE(tree,
3062 g_byte_array_free(created_bytes, TRUE);
3063 created_bytes = NULL;
3067 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
3070 g_byte_array_free(created_bytes, TRUE);
3071 created_bytes = NULL;
3075 /* n will be zero except when it's a FT_UINT_BYTES */
3076 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
3078 if (encoding & ENC_STRING) {
3079 if (saved_err == ERANGE)
3080 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
3081 else if (!bytes || saved_err != 0)
3082 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
3085 proto_tree_set_bytes_gbytearray(new_fi, bytes);
3087 proto_tree_set_bytes(new_fi, NULL, 0);
3090 g_byte_array_free(created_bytes, TRUE);
3093 /* n will be zero except when it's a FT_UINT_BYTES */
3094 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
3097 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3100 return proto_tree_add_node(tree, new_fi);
3105 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3106 const gint start, gint length, const guint encoding,
3107 nstime_t *retval, gint *endoff, gint *err)
3110 nstime_t time_stamp;
3112 header_field_info *hfinfo;
3114 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3116 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3118 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3120 /* length has to be -1 or > 0 regardless of encoding */
3121 if (length < -1 || length == 0) {
3122 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
3123 "Invalid length %d passed to proto_tree_add_time_item", length));
3126 time_stamp.secs = 0;
3127 time_stamp.nsecs = 0;
3129 if (encoding & ENC_STR_TIME_MASK) {
3130 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
3131 /* grab the errno now before it gets overwritten */
3135 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
3136 const gboolean length_error = length < 4 ? TRUE : FALSE;
3138 if (length > 8 || length < 4) {
3140 report_type_length_mismatch(tree, "a relative time value", length, length_error);
3142 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
3145 tvb_ensure_bytes_exist(tvb, start, length);
3146 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
3147 if (endoff) *endoff = length;
3150 if (err) *err = saved_err;
3153 retval->secs = time_stamp.secs;
3154 retval->nsecs = time_stamp.nsecs;
3157 CHECK_FOR_NULL_TREE(tree);
3159 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3161 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3163 proto_tree_set_time(new_fi, &time_stamp);
3165 if (encoding & ENC_STRING) {
3166 if (saved_err == ERANGE)
3167 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
3168 else if (saved_err == EDOM)
3169 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
3173 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3176 return proto_tree_add_node(tree, new_fi);
3179 /* Add a FT_NONE to a proto_tree */
3181 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
3182 const gint start, gint length, const char *format,
3187 header_field_info *hfinfo;
3189 CHECK_FOR_NULL_TREE(tree);
3191 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3193 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
3195 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3197 TRY_TO_FAKE_THIS_REPR(pi);
3199 va_start(ap, format);
3200 proto_tree_set_representation(pi, format, ap);
3203 /* no value to set for FT_NONE */
3207 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
3208 * offset, and returns proto_item* */
3210 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
3211 const guint encoding)
3215 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
3221 /* Advance the ptvcursor's offset within its tvbuff without
3222 * adding anything to the proto_tree. */
3224 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
3226 ptvc->offset += length;
3231 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
3233 fvalue_set_protocol(&fi->value, tvb, field_data);
3236 /* Add a FT_PROTOCOL to a proto_tree */
3238 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3239 gint start, gint length, const char *format, ...)
3243 header_field_info *hfinfo;
3244 gchar* protocol_rep;
3246 CHECK_FOR_NULL_TREE(tree);
3248 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3250 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
3252 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3254 va_start(ap, format);
3255 protocol_rep = g_strdup_vprintf(format, ap);
3256 proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length)), protocol_rep);
3257 g_free(protocol_rep);
3260 TRY_TO_FAKE_THIS_REPR(pi);
3262 va_start(ap, format);
3263 proto_tree_set_representation(pi, format, ap);
3269 /* Add a FT_BYTES to a proto_tree */
3271 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3272 gint length, const guint8 *start_ptr)
3275 header_field_info *hfinfo;
3278 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3279 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
3280 test_length(hfinfo, tvb, start, item_length);
3282 CHECK_FOR_NULL_TREE(tree);
3284 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3286 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
3288 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3289 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
3294 /* Add a FT_BYTES to a proto_tree */
3296 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3297 gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
3300 header_field_info *hfinfo;
3303 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3304 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length);
3305 test_length(hfinfo, tvb, start, item_length);
3307 CHECK_FOR_NULL_TREE(tree);
3309 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3311 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
3313 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
3314 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
3320 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3321 gint start, gint length,
3322 const guint8 *start_ptr,
3323 const char *format, ...)
3328 if (start_ptr == NULL)
3329 start_ptr = tvb_get_ptr(tvb, start, length);
3331 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
3333 TRY_TO_FAKE_THIS_REPR_NESTED(pi);
3335 va_start(ap, format);
3336 proto_tree_set_representation_value(pi, format, ap);
3343 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3344 gint start, gint length, const guint8 *start_ptr,
3345 const char *format, ...)
3350 if (start_ptr == NULL)
3351 start_ptr = tvb_get_ptr(tvb, start, length);
3353 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
3355 TRY_TO_FAKE_THIS_REPR_NESTED(pi);
3357 va_start(ap, format);
3358 proto_tree_set_representation(pi, format, ap);
3365 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
3369 DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
3371 bytes = g_byte_array_new();
3373 g_byte_array_append(bytes, start_ptr, length);
3375 fvalue_set_byte_array(&fi->value, bytes);
3380 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
3382 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
3386 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
3390 DISSECTOR_ASSERT(value != NULL);
3392 bytes = byte_array_dup(value);
3394 fvalue_set_byte_array(&fi->value, bytes);
3397 /* Add a FT_*TIME to a proto_tree */
3399 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3400 gint length, const nstime_t *value_ptr)
3403 header_field_info *hfinfo;
3405 CHECK_FOR_NULL_TREE(tree);
3407 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3409 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3411 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3412 proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
3418 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3419 gint start, gint length, nstime_t *value_ptr,
3420 const char *format, ...)
3425 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3427 va_start(ap, format);
3428 proto_tree_set_representation_value(pi, format, ap);
3436 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3437 gint start, gint length, nstime_t *value_ptr,
3438 const char *format, ...)
3443 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3445 TRY_TO_FAKE_THIS_REPR(pi);
3447 va_start(ap, format);
3448 proto_tree_set_representation(pi, format, ap);
3455 /* Set the FT_*TIME value */
3457 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
3459 DISSECTOR_ASSERT(value_ptr != NULL);
3461 fvalue_set_time(&fi->value, value_ptr);
3464 /* Add a FT_IPXNET to a proto_tree */
3466 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3467 gint length, guint32 value)
3470 header_field_info *hfinfo;
3472 CHECK_FOR_NULL_TREE(tree);
3474 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3476 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
3478 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3479 proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
3485 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3486 gint start, gint length, guint32 value,
3487 const char *format, ...)
3492 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3494 va_start(ap, format);
3495 proto_tree_set_representation_value(pi, format, ap);
3503 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3504 gint start, gint length, guint32 value,
3505 const char *format, ...)
3510 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3512 TRY_TO_FAKE_THIS_REPR(pi);
3514 va_start(ap, format);
3515 proto_tree_set_representation(pi, format, ap);
3522 /* Set the FT_IPXNET value */
3524 proto_tree_set_ipxnet(field_info *fi, guint32 value)
3526 fvalue_set_uinteger(&fi->value, value);
3529 /* Add a FT_IPv4 to a proto_tree */
3531 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3532 gint length, guint32 value)
3535 header_field_info *hfinfo;
3537 CHECK_FOR_NULL_TREE(tree);
3539 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3541 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
3543 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3544 proto_tree_set_ipv4(PNODE_FINFO(pi), value);
3550 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3551 gint start, gint length, guint32 value,
3552 const char *format, ...)
3557 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3559 va_start(ap, format);
3560 proto_tree_set_representation_value(pi, format, ap);
3568 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3569 gint start, gint length, guint32 value,
3570 const char *format, ...)
3575 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3577 TRY_TO_FAKE_THIS_REPR(pi);
3579 va_start(ap, format);
3580 proto_tree_set_representation(pi, format, ap);
3587 /* Set the FT_IPv4 value */
3589 proto_tree_set_ipv4(field_info *fi, guint32 value)
3591 fvalue_set_uinteger(&fi->value, value);
3594 /* Add a FT_IPv6 to a proto_tree */
3596 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3597 gint length, const struct e_in6_addr *value_ptr)
3600 header_field_info *hfinfo;
3602 CHECK_FOR_NULL_TREE(tree);
3604 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3606 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
3608 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3609 proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
3615 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3616 gint start, gint length,
3617 const struct e_in6_addr *value_ptr,
3618 const char *format, ...)
3623 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3625 va_start(ap, format);
3626 proto_tree_set_representation_value(pi, format, ap);
3634 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3635 gint start, gint length,
3636 const struct e_in6_addr *value_ptr,
3637 const char *format, ...)
3642 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3644 TRY_TO_FAKE_THIS_REPR(pi);
3646 va_start(ap, format);
3647 proto_tree_set_representation(pi, format, ap);
3654 /* Set the FT_IPv6 value */
3656 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
3658 DISSECTOR_ASSERT(value_ptr != NULL);
3659 fvalue_set_bytes(&fi->value, value_ptr);
3663 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3665 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
3668 /* Set the FT_FCWWN value */
3670 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
3672 DISSECTOR_ASSERT(value_ptr != NULL);
3673 fvalue_set_bytes(&fi->value, value_ptr);
3677 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3679 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
3682 /* Add a FT_GUID to a proto_tree */
3684 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3685 gint length, const e_guid_t *value_ptr)
3688 header_field_info *hfinfo;
3690 CHECK_FOR_NULL_TREE(tree);
3692 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3694 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
3696 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3697 proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
3703 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3704 gint start, gint length,
3705 const e_guid_t *value_ptr,
3706 const char *format, ...)
3711 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3713 va_start(ap, format);
3714 proto_tree_set_representation_value(pi, format, ap);
3722 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3723 gint start, gint length, const e_guid_t *value_ptr,
3724 const char *format, ...)
3729 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3731 TRY_TO_FAKE_THIS_REPR(pi);
3733 va_start(ap, format);
3734 proto_tree_set_representation(pi, format, ap);
3741 /* Set the FT_GUID value */
3743 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
3745 DISSECTOR_ASSERT(value_ptr != NULL);
3746 fvalue_set_guid(&fi->value, value_ptr);
3750 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
3751 const guint encoding)
3755 tvb_get_guid(tvb, start, &guid, encoding);
3756 proto_tree_set_guid(fi, &guid);
3759 /* Add a FT_OID to a proto_tree */
3761 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3762 gint length, const guint8* value_ptr)
3765 header_field_info *hfinfo;
3767 CHECK_FOR_NULL_TREE(tree);
3769 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3771 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
3773 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3774 proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
3780 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3781 gint start, gint length,
3782 const guint8* value_ptr,
3783 const char *format, ...)
3788 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3790 va_start(ap, format);
3791 proto_tree_set_representation_value(pi, format, ap);
3799 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3800 gint start, gint length, const guint8* value_ptr,
3801 const char *format, ...)
3806 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3808 TRY_TO_FAKE_THIS_REPR(pi);
3810 va_start(ap, format);
3811 proto_tree_set_representation(pi, format, ap);
3818 /* Set the FT_OID value */
3820 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
3824 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3826 bytes = g_byte_array_new();
3828 g_byte_array_append(bytes, value_ptr, length);
3830 fvalue_set_byte_array(&fi->value, bytes);
3834 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3836 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
3839 /* Set the FT_SYSTEM_ID value */
3841 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
3845 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3847 bytes = g_byte_array_new();
3849 g_byte_array_append(bytes, value_ptr, length);
3851 fvalue_set_byte_array(&fi->value, bytes);
3855 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3857 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
3860 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
3861 * own copy of string, and frees it when the proto_tree is destroyed. */
3863 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3864 gint length, const char* value)
3867 header_field_info *hfinfo;
3869 CHECK_FOR_NULL_TREE(tree);
3871 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3873 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
3875 if (hfinfo->display == STR_UNICODE) {
3876 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
3879 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3880 DISSECTOR_ASSERT(length >= 0);
3881 proto_tree_set_string(PNODE_FINFO(pi), value);
3887 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3888 gint start, gint length, const char* value,
3895 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3897 va_start(ap, format);
3898 proto_tree_set_representation_value(pi, format, ap);
3906 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3907 gint start, gint length, const char* value,
3908 const char *format, ...)
3913 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3915 TRY_TO_FAKE_THIS_REPR(pi);
3917 va_start(ap, format);
3918 proto_tree_set_representation(pi, format, ap);
3925 /* Set the FT_STRING value */
3927 proto_tree_set_string(field_info *fi, const char* value)
3930 fvalue_set_string(&fi->value, value);
3932 fvalue_set_string(&fi->value, "[ Null ]");
3936 /* Set the FT_AX25 value */
3938 proto_tree_set_ax25(field_info *fi, const guint8* value)
3940 fvalue_set_bytes(&fi->value, value);
3944 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3946 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
3949 /* Set the FT_VINES value */
3951 proto_tree_set_vines(field_info *fi, const guint8* value)
3953 fvalue_set_bytes(&fi->value, value);
3957 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3959 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
3962 /* Add a FT_ETHER to a proto_tree */
3964 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3965 gint length, const guint8* value)
3968 header_field_info *hfinfo;
3970 CHECK_FOR_NULL_TREE(tree);
3972 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3974 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
3976 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3977 proto_tree_set_ether(PNODE_FINFO(pi), value);
3983 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3984 gint start, gint length, const guint8* value,
3985 const char *format, ...)
3990 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3992 va_start(ap, format);
3993 proto_tree_set_representation_value(pi, format, ap);
4001 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4002 gint start, gint length, const guint8* value,
4003 const char *format, ...)
4008 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
4010 TRY_TO_FAKE_THIS_REPR(pi);
4012 va_start(ap, format);
4013 proto_tree_set_representation(pi, format, ap);
4020 /* Set the FT_ETHER value */
4022 proto_tree_set_ether(field_info *fi, const guint8* value)
4024 fvalue_set_bytes(&fi->value, value);
4028 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
4030 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
4033 /* Add a FT_BOOLEAN to a proto_tree */
4035 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4036 gint length, guint32 value)
4039 header_field_info *hfinfo;
4041 CHECK_FOR_NULL_TREE(tree);
4043 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4045 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
4047 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4048 proto_tree_set_boolean(PNODE_FINFO(pi), value);
4054 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
4055 tvbuff_t *tvb, gint start, gint length,
4056 guint32 value, const char *format, ...)
4061 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
4063 va_start(ap, format);
4064 proto_tree_set_representation_value(pi, format, ap);
4072 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4073 gint start, gint length, guint32 value,
4074 const char *format, ...)
4079 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
4081 TRY_TO_FAKE_THIS_REPR(pi);
4083 va_start(ap, format);
4084 proto_tree_set_representation(pi, format, ap);
4092 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4093 gint length, guint64 value)
4096 header_field_info *hfinfo;
4098 CHECK_FOR_NULL_TREE(tree);
4100 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4102 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
4104 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4105 proto_tree_set_boolean(PNODE_FINFO(pi), value);
4110 /* Set the FT_BOOLEAN value */
4112 proto_tree_set_boolean(field_info *fi, guint64 value)
4114 proto_tree_set_uint64(fi, value);
4117 /* Generate, into "buf", a string showing the bits of a bitfield.
4118 Return a pointer to the character after that string. */
4119 /*XXX this needs a buf_len check */
4121 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
4129 bit = G_GUINT64_CONSTANT(1) << (width - 1);
4132 /* This bit is part of the field. Show its value. */
4138 /* This bit is not part of the field. */
4153 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
4157 p = other_decode_bitfield_value(buf, val, mask, width);
4158 p = g_stpcpy(p, " = ");
4163 /* Add a FT_FLOAT to a proto_tree */
4165 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4166 gint length, float value)
4169 header_field_info *hfinfo;
4171 CHECK_FOR_NULL_TREE(tree);
4173 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4175 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
4177 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4178 proto_tree_set_float(PNODE_FINFO(pi), value);
4184 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4185 gint start, gint length, float value,
4186 const char *format, ...)
4191 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
4193 va_start(ap, format);
4194 proto_tree_set_representation_value(pi, format, ap);
4202 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4203 gint start, gint length, float value,
4204 const char *format, ...)
4209 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
4211 TRY_TO_FAKE_THIS_REPR(pi);
4213 va_start(ap, format);
4214 proto_tree_set_representation(pi, format, ap);
4221 /* Set the FT_FLOAT value */
4223 proto_tree_set_float(field_info *fi, float value)
4225 fvalue_set_floating(&fi->value, value);
4228 /* Add a FT_DOUBLE to a proto_tree */
4230 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4231 gint length, double value)
4234 header_field_info *hfinfo;
4236 CHECK_FOR_NULL_TREE(tree);
4238 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4240 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
4242 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4243 proto_tree_set_double(PNODE_FINFO(pi), value);
4249 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4250 gint start, gint length, double value,
4251 const char *format, ...)
4256 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
4258 va_start(ap, format);
4259 proto_tree_set_representation_value(pi, format, ap);
4267 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4268 gint start, gint length, double value,
4269 const char *format, ...)
4274 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
4276 TRY_TO_FAKE_THIS_REPR(pi);
4278 va_start(ap, format);
4279 proto_tree_set_representation(pi, format, ap);
4286 /* Set the FT_DOUBLE value */
4288 proto_tree_set_double(field_info *fi, double value)
4290 fvalue_set_floating(&fi->value, value);
4293 /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
4295 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4296 gint length, guint32 value)
4298 proto_item *pi = NULL;
4299 header_field_info *hfinfo;
4301 CHECK_FOR_NULL_TREE(tree);
4303 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4305 switch (hfinfo->type) {
4312 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4313 proto_tree_set_uint(PNODE_FINFO(pi), value);
4317 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4318 "field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",
4326 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4327 gint start, gint length, guint32 value,
4328 const char *format, ...)
4333 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
4335 va_start(ap, format);
4336 proto_tree_set_representation_value(pi, format, ap);
4344 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4345 gint start, gint length, guint32 value,
4346 const char *format, ...)
4351 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
4353 TRY_TO_FAKE_THIS_REPR(pi);
4355 va_start(ap, format);
4356 proto_tree_set_representation(pi, format, ap);
4363 /* Set the FT_UINT{8,16,24,32} value */
4365 proto_tree_set_uint(field_info *fi, guint32 value)
4367 header_field_info *hfinfo;
4370 hfinfo = fi->hfinfo;
4373 if (hfinfo->bitmask) {
4374 /* Mask out irrelevant portions */
4375 integer &= (guint32)(hfinfo->bitmask);
4378 integer >>= hfinfo_bitshift(hfinfo);
4381 fvalue_set_uinteger(&fi->value, integer);
4384 /* Add FT_UINT{40,48,56,64} to a proto_tree */
4386 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4387 gint length, guint64 value)
4389 proto_item *pi = NULL;
4390 header_field_info *hfinfo;
4392 CHECK_FOR_NULL_TREE(tree);
4394 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4396 switch (hfinfo->type) {
4402 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4403 proto_tree_set_uint64(PNODE_FINFO(pi), value);
4407 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4408 "field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",
4416 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4417 gint start, gint length, guint64 value,
4418 const char *format, ...)
4423 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4425 va_start(ap, format);
4426 proto_tree_set_representation_value(pi, format, ap);
4434 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4435 gint start, gint length, guint64 value,
4436 const char *format, ...)
4441 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4443 TRY_TO_FAKE_THIS_REPR(pi);
4445 va_start(ap, format);
4446 proto_tree_set_representation(pi, format, ap);
4453 /* Set the FT_UINT{40,48,56,64} value */
4455 proto_tree_set_uint64(field_info *fi, guint64 value)
4457 header_field_info *hfinfo;
4460 hfinfo = fi->hfinfo;
4463 if (hfinfo->bitmask) {
4464 /* Mask out irrelevant portions */
4465 integer &= hfinfo->bitmask;
4468 integer >>= hfinfo_bitshift(hfinfo);
4471 fvalue_set_uinteger64(&fi->value, integer);
4474 /* Add FT_INT{8,16,24,32} to a proto_tree */
4476 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4477 gint length, gint32 value)
4479 proto_item *pi = NULL;
4480 header_field_info *hfinfo;
4482 CHECK_FOR_NULL_TREE(tree);
4484 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4486 switch (hfinfo->type) {
4491 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4492 proto_tree_set_int(PNODE_FINFO(pi), value);
4496 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4497 "field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
4505 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4506 gint start, gint length, gint32 value,
4507 const char *format, ...)
4512 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4514 va_start(ap, format);
4515 proto_tree_set_representation_value(pi, format, ap);
4523 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4524 gint start, gint length, gint32 value,
4525 const char *format, ...)
4530 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4532 TRY_TO_FAKE_THIS_REPR(pi);
4534 va_start(ap, format);
4535 proto_tree_set_representation(pi, format, ap);
4542 /* Set the FT_INT{8,16,24,32} value */
4544 proto_tree_set_int(field_info *fi, gint32 value)
4546 header_field_info *hfinfo;
4550 hfinfo = fi->hfinfo;
4551 integer = (guint32) value;
4553 if (hfinfo->bitmask) {
4554 /* Mask out irrelevant portions */
4555 integer &= (guint32)(hfinfo->bitmask);
4558 integer >>= hfinfo_bitshift(hfinfo);
4560 no_of_bits = ws_count_ones(hfinfo->bitmask);
4561 integer = ws_sign_ext32(integer, no_of_bits);
4564 fvalue_set_sinteger(&fi->value, integer);
4567 /* Add FT_INT{40,48,56,64} to a proto_tree */
4569 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4570 gint length, gint64 value)
4572 proto_item *pi = NULL;
4573 header_field_info *hfinfo;
4575 CHECK_FOR_NULL_TREE(tree);
4577 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4579 switch (hfinfo->type) {
4584 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4585 proto_tree_set_int64(PNODE_FINFO(pi), value);
4589 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4590 "field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
4598 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4599 gint start, gint length, gint64 value,
4600 const char *format, ...)
4605 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4607 va_start(ap, format);
4608 proto_tree_set_representation_value(pi, format, ap);
4615 /* Set the FT_INT{40,48,56,64} value */
4617 proto_tree_set_int64(field_info *fi, gint64 value)
4619 header_field_info *hfinfo;
4623 hfinfo = fi->hfinfo;
4626 if (hfinfo->bitmask) {
4627 /* Mask out irrelevant portions */
4628 integer &= hfinfo->bitmask;
4631 integer >>= hfinfo_bitshift(hfinfo);
4633 no_of_bits = ws_count_ones(hfinfo->bitmask);
4634 integer = ws_sign_ext64(integer, no_of_bits);
4637 fvalue_set_sinteger64(&fi->value, integer);
4641 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4642 gint start, gint length, gint64 value,
4643 const char *format, ...)
4648 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4650 TRY_TO_FAKE_THIS_REPR(pi);
4652 va_start(ap, format);
4653 proto_tree_set_representation(pi, format, ap);
4660 /* Add a FT_EUI64 to a proto_tree */
4662 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4663 gint length, const guint64 value)
4666 header_field_info *hfinfo;
4668 CHECK_FOR_NULL_TREE(tree);
4670 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4672 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
4674 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4675 proto_tree_set_eui64(PNODE_FINFO(pi), value);
4681 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4682 gint start, gint length, const guint64 value,
4683 const char *format, ...)
4688 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4690 va_start(ap, format);
4691 proto_tree_set_representation_value(pi, format, ap);
4699 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4700 gint start, gint length, const guint64 value,
4701 const char *format, ...)
4706 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4708 TRY_TO_FAKE_THIS_REPR(pi);
4710 va_start(ap, format);
4711 proto_tree_set_representation(pi, format, ap);
4718 /* Set the FT_EUI64 value */
4720 proto_tree_set_eui64(field_info *fi, const guint64 value)
4722 fvalue_set_uinteger64(&fi->value, value);
4725 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
4729 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
4731 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
4735 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
4737 proto_tree_add_node(proto_tree *tree, field_info *fi)
4739 proto_node *pnode, *tnode, *sibling;
4744 * Restrict our depth. proto_tree_traverse_pre_order and
4745 * proto_tree_traverse_post_order (and possibly others) are recursive
4746 * so we need to be mindful of our stack size.
4748 if (tree->first_child == NULL) {
4749 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
4751 if (G_UNLIKELY(depth > MAX_TREE_LEVELS)) {
4752 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
4753 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u)",
4755 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
4761 * Make sure "tree" is ready to have subtrees under it, by
4762 * checking whether it's been given an ett_ value.
4764 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
4765 * node of the protocol tree. That node is not displayed,
4766 * so it doesn't need an ett_ value to remember whether it
4770 tfi = PNODE_FINFO(tnode);
4771 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
4772 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4773 "\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
4774 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
4775 /* XXX - is it safe to continue here? */
4778 pnode = wmem_new(PNODE_POOL(tree), proto_node);
4779 PROTO_NODE_INIT(pnode);
4780 pnode->parent = tnode;
4781 PNODE_FINFO(pnode) = fi;
4782 pnode->tree_data = PTREE_DATA(tree);
4784 if (tnode->last_child != NULL) {
4785 sibling = tnode->last_child;
4786 DISSECTOR_ASSERT(sibling->next == NULL);
4787 sibling->next = pnode;
4789 tnode->first_child = pnode;
4790 tnode->last_child = pnode;
4792 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
4794 return (proto_item *)pnode;
4798 /* Generic way to allocate field_info and add to proto_tree.
4799 * Sets *pfi to address of newly-allocated field_info struct */
4801 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
4808 get_hfi_length(hfinfo, tvb, start, length, &item_length);
4809 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4810 pi = proto_tree_add_node(tree, fi);
4817 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
4820 gint length_remaining;
4823 * We only allow a null tvbuff if the item has a zero length,
4824 * i.e. if there's no data backing it.
4826 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
4829 * XXX - in some protocols, there are 32-bit unsigned length
4830 * fields, so lengths in protocol tree and tvbuff routines
4831 * should really be unsigned. We should have, for those
4832 * field types for which "to the end of the tvbuff" makes sense,
4833 * additional routines that take no length argument and
4834 * add fields that run to the end of the tvbuff.
4836 if (*length == -1) {
4838 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
4839 * FT_STRINGZPAD fields, a length of -1 means "set the
4840 * length to what remains in the tvbuff".
4842 * The assumption is either that
4844 * 1) the length of the item can only be determined
4845 * by dissection (typically true of items with
4846 * subitems, which are probably FT_NONE or
4851 * 2) if the tvbuff is "short" (either due to a short
4852 * snapshot length or due to lack of reassembly of
4853 * fragments/segments/whatever), we want to display
4854 * what's available in the field (probably FT_BYTES
4855 * or FT_STRING) and then throw an exception later
4859 * 3) the field is defined to be "what's left in the
4862 * so we set the length to what remains in the tvbuff so
4863 * that, if we throw an exception while dissecting, it
4864 * has what is probably the right value.
4866 * For FT_STRINGZ, it means "the string is null-terminated,
4867 * not null-padded; set the length to the actual length
4868 * of the string", and if the tvbuff if short, we just
4869 * throw an exception.
4871 * It's not valid for any other type of field. For those
4872 * fields, we treat -1 the same way we treat other
4873 * negative values - we assume the length is a Really
4874 * Big Positive Number, and throw a ReportedBoundsError
4875 * exception, under the assumption that the Really Big
4876 * Length would run past the end of the packet.
4878 switch (hfinfo->type) {
4886 * We allow FT_PROTOCOLs to be zero-length -
4887 * for example, an ONC RPC NULL procedure has
4888 * neither arguments nor reply, so the
4889 * payload for that protocol is empty.
4891 * We also allow the others to be zero-length -
4892 * because that's the way the code has been for a
4895 * However, we want to ensure that the start
4896 * offset is not *past* the byte past the end
4897 * of the tvbuff: we throw an exception in that
4900 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
4901 DISSECTOR_ASSERT(*length >= 0);
4906 * Leave the length as -1, so our caller knows
4912 THROW(ReportedBoundsError);
4913 DISSECTOR_ASSERT_NOT_REACHED();
4915 *item_length = *length;
4917 *item_length = *length;
4918 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
4920 * These types are for interior nodes of the
4921 * tree, and don't have data associated with
4922 * them; if the length is negative (XXX - see
4923 * above) or goes past the end of the tvbuff,
4924 * cut it short at the end of the tvbuff.
4925 * That way, if this field is selected in
4926 * Wireshark, we don't highlight stuff past
4927 * the end of the data.
4929 /* XXX - what to do, if we don't have a tvb? */
4931 length_remaining = tvb_captured_length_remaining(tvb, start);
4932 if (*item_length < 0 ||
4933 (*item_length > 0 &&
4934 (length_remaining < *item_length)))
4935 *item_length = length_remaining;
4938 if (*item_length < 0) {
4939 THROW(ReportedBoundsError);
4945 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
4946 gint length, guint item_length, const gint encoding)
4951 * We need to get the correct item length here.
4952 * That's normally done by proto_tree_new_item(),
4953 * but we won't be calling it.
4955 switch (hfinfo->type) {
4961 * The length is the specified length.
4967 * Map all non-zero values to little-endian for
4968 * backwards compatibility.
4970 n = get_uint_value(NULL, tvb, start, length,
4971 encoding ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
4977 /* XXX - make these just FT_UINT? */
4986 /* XXX - make these just FT_INT? */
5011 * The length is the specified length.
5017 report_type_length_mismatch(NULL, "a string", length, TRUE);
5020 /* This can throw an exception */
5021 /* XXX - do this without fetching the string? */
5022 tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
5024 item_length = length;
5027 case FT_UINT_STRING:
5028 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
5033 case FT_ABSOLUTE_TIME:
5034 case FT_RELATIVE_TIME:
5035 case FT_IEEE_11073_SFLOAT:
5036 case FT_IEEE_11073_FLOAT:
5038 * The length is the specified length.
5043 g_error("hfinfo->type %d (%s) not handled\n",
5045 ftype_name(hfinfo->type));
5046 DISSECTOR_ASSERT_NOT_REACHED();
5053 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
5054 const gint start, const gint item_length)
5058 FIELD_INFO_NEW(PNODE_POOL(tree), fi);
5060 fi->hfinfo = hfinfo;
5062 fi->start += (tvb)?tvb_raw_offset(tvb):0;
5063 fi->length = item_length;
5066 if (!PTREE_DATA(tree)->visible)
5067 FI_SET_FLAG(fi, FI_HIDDEN);
5068 fvalue_init(&fi->value, fi->hfinfo->type);
5071 /* add the data source tvbuff */
5072 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
5074 fi->appendix_start = 0;
5075 fi->appendix_length = 0;
5080 /* If the protocol tree is to be visible, set the representation of a
5081 proto_tree entry with the name of the field for the item and with
5082 the value formatted with the supplied printf-style format and
5085 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
5089 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
5090 * items string representation */
5091 if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
5093 field_info *fi = PITEM_FINFO(pi);
5094 header_field_info *hf;
5096 DISSECTOR_ASSERT(fi);
5100 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5101 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
5105 if (IS_FT_UINT(hf->type))
5106 val = fvalue_get_uinteger(&fi->value);
5108 val = fvalue_get_uinteger64(&fi->value);
5110 val <<= hfinfo_bitshift(hf);
5112 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
5113 ret = (int) (p - fi->rep->representation);
5116 /* put in the hf name */
5117 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
5119 /* If possible, Put in the value of the string */
5120 if (ret < ITEM_LABEL_LENGTH) {
5121 ret += g_vsnprintf(fi->rep->representation + ret,
5122 ITEM_LABEL_LENGTH - ret, format, ap);
5124 if (ret >= ITEM_LABEL_LENGTH) {
5125 /* Uh oh, we don't have enough room. Tell the user
5126 * that the field is truncated.
5128 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
5133 /* If the protocol tree is to be visible, set the representation of a
5134 proto_tree entry with the representation formatted with the supplied
5135 printf-style format and argument list. */
5137 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
5139 int ret; /*tmp return value */
5140 field_info *fi = PITEM_FINFO(pi);
5142 DISSECTOR_ASSERT(fi);
5144 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5145 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5146 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
5148 if (ret >= ITEM_LABEL_LENGTH) {
5149 /* Uh oh, we don't have enough room. Tell the user
5150 * that the field is truncated.
5152 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
5158 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
5160 switch (hfinfo->display) {
5162 return format_text(NULL, string, strlen(string));
5165 return format_text_wsp(string, strlen(string));
5168 /* XXX, format_unicode_text() */
5169 return wmem_strdup(NULL, string);
5172 return format_text(NULL, string, strlen(string));
5176 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
5178 gsize res = g_strlcpy(dest, src, dest_size);
5180 if (res > dest_size)
5185 static header_field_info *
5186 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
5188 header_field_info *dup_hfinfo;
5190 if (hfinfo->same_name_prev_id == -1)
5192 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
5197 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
5199 g_free(last_field_name);
5200 last_field_name = NULL;
5202 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
5203 /* No hfinfo with the same name */
5204 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
5208 if (hfinfo->same_name_next) {
5209 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
5212 if (hfinfo->same_name_prev_id != -1) {
5213 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
5214 same_name_prev->same_name_next = hfinfo->same_name_next;
5215 if (!hfinfo->same_name_next) {
5216 /* It's always the latest added hfinfo which is stored in gpa_name_map */
5217 g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
5222 /* -------------------------- */
5224 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
5225 gchar *result, gchar *expr, const int size)
5230 ipv4_addr_and_mask *ipv4;
5231 struct e_in6_addr *ipv6;
5233 guint32 n_addr; /* network-order IPv4 address */
5235 const true_false_string *tfstring;
5237 int len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
5239 field_info *finfo = NULL;
5240 header_field_info* hfinfo;
5241 const gchar *abbrev = NULL;
5243 const char *hf_str_val;
5244 char number_buf[48];
5245 const char *number_out;
5251 g_assert(field_ids != NULL);
5252 while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
5253 field_id = *field_idx;
5254 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
5256 /* do we need to rewind ? */
5260 if (occurrence < 0) {
5261 /* Search other direction */
5262 while (hfinfo->same_name_prev_id != -1) {
5263 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
5268 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
5270 if (!finfos || !(len = g_ptr_array_len(finfos))) {
5271 if (occurrence < 0) {
5272 hfinfo = hfinfo->same_name_next;
5274 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5279 /* Are there enough occurrences of the field? */
5280 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
5281 if (occurrence < 0) {
5282 hfinfo = hfinfo->same_name_next;
5284 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5290 /* Calculate single index or set outer bounderies */
5291 if (occurrence < 0) {
5292 i = occurrence + len + prev_len;
5294 } else if (occurrence > 0) {
5295 i = occurrence - 1 - prev_len;
5302 prev_len += len; /* Count handled occurrences */
5305 finfo = (field_info *)g_ptr_array_index(finfos, i);
5307 if (offset_r && (offset_r < (size - 2)))
5308 result[offset_r++] = ',';
5310 if (offset_e && (offset_e < (size - 2)))
5311 expr[offset_e++] = ',';
5313 switch (hfinfo->type) {
5315 case FT_NONE: /* Nothing to add */
5316 if (offset_r == 0) {
5318 } else if (result[offset_r-1] == ',') {
5319 result[offset_r-1] = '\0';
5324 /* prevent multiple "yes" entries by setting result directly */
5325 g_strlcpy(result, "Yes", size);
5330 bytes = (guint8 *)fvalue_get(&finfo->value);
5332 switch(hfinfo->display)
5335 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
5338 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
5341 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
5344 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5348 if (prefs.display_byte_fields_with_spaces)
5350 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5354 str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
5358 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5359 wmem_free(NULL, str);
5362 if (hfinfo->display & BASE_ALLOW_ZERO) {
5363 offset_r += protoo_strlcpy(result+offset_r, "<none>", size-offset_r);
5365 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
5370 case FT_ABSOLUTE_TIME:
5371 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
5372 offset_r += protoo_strlcpy(result+offset_r,
5375 wmem_free(NULL, tmpbuf);
5378 case FT_RELATIVE_TIME:
5379 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
5380 offset_r += protoo_strlcpy(result+offset_r,
5383 wmem_free(NULL, tmpbuf);
5387 number64 = fvalue_get_uinteger64(&finfo->value);
5388 tfstring = (const true_false_string *)&tfs_true_false;
5389 if (hfinfo->strings) {
5390 tfstring = (const struct true_false_string*) hfinfo->strings;
5392 offset_r += protoo_strlcpy(result+offset_r,
5394 tfstring->true_string :
5395 tfstring->false_string, size-offset_r);
5397 offset_e += protoo_strlcpy(expr+offset_e,
5398 number64 ? "1" : "0", size-offset_e);
5403 number = fvalue_get_uinteger(&finfo->value);
5405 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5406 gchar tmp[ITEM_LABEL_LENGTH];
5407 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5409 DISSECTOR_ASSERT(fmtfunc);
5410 fmtfunc(tmp, number);
5412 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5414 } else if (hfinfo->strings) {
5415 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5418 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
5420 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5423 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5425 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5428 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5429 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5431 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5433 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5436 offset_e = (int)strlen(expr);
5439 /* XXX - make these just FT_NUMBER? */
5450 number = IS_FT_INT(hfinfo->type) ?
5451 (guint32) fvalue_get_sinteger(&finfo->value) :
5452 fvalue_get_uinteger(&finfo->value);
5454 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5455 gchar tmp[ITEM_LABEL_LENGTH];
5456 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5458 DISSECTOR_ASSERT(fmtfunc);
5459 fmtfunc(tmp, number);
5461 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5463 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
5464 if (hfinfo->display & BASE_UNIT_STRING) {
5465 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5466 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5467 hf_str_val = hf_try_val_to_str(number, hfinfo);
5468 offset_r += protoo_strlcpy(result+offset_r, hf_str_val, size-offset_r);
5470 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5473 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
5475 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5478 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
5480 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5483 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5484 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5486 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5488 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5491 offset_e = (int)strlen(expr);
5503 number64 = IS_FT_INT(hfinfo->type) ?
5504 (guint64) fvalue_get_sinteger64(&finfo->value) :
5505 fvalue_get_uinteger64(&finfo->value);
5507 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5508 gchar tmp[ITEM_LABEL_LENGTH];
5509 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
5511 DISSECTOR_ASSERT(fmtfunc64);
5512 fmtfunc64(tmp, number64);
5513 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5514 } else if (hfinfo->strings) {
5515 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
5518 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
5520 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5523 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
5525 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5528 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5529 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5531 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
5533 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5536 offset_e = (int)strlen(expr);
5540 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
5541 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5542 wmem_free(NULL, str);
5546 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&finfo->value);
5547 n_addr = ipv4_get_net_order_addr(ipv4);
5548 set_address (&addr, AT_IPv4, 4, &n_addr);
5549 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5550 offset_r = (int)strlen(result);
5554 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
5555 set_address (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
5556 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5557 offset_r = (int)strlen(result);
5561 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
5562 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5563 offset_r = (int)strlen(result);
5567 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
5568 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5569 offset_r = (int)strlen(result);
5573 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
5574 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5575 wmem_free(NULL, str);
5579 bytes = (guint8 *)fvalue_get(&finfo->value);
5580 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5581 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5582 wmem_free(NULL, str);
5584 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5585 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5586 wmem_free(NULL, str);
5590 bytes = (guint8 *)fvalue_get(&finfo->value);
5591 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5592 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5593 wmem_free(NULL, str);
5595 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5596 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5597 wmem_free(NULL, str);
5601 bytes = (guint8 *)fvalue_get(&finfo->value);
5602 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
5603 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5604 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5605 wmem_free(NULL, str);
5609 if (hfinfo->display & BASE_UNIT_STRING) {
5610 double d_value = fvalue_get_floating(&finfo->value);
5611 g_snprintf(result+offset_r, size-offset_r,
5612 "%." G_STRINGIFY(FLT_DIG) "g%s", d_value,
5613 unit_name_string_get_double(d_value, (unit_name_string*)hfinfo->strings));
5615 g_snprintf(result+offset_r, size-offset_r,
5616 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
5618 offset_r = (int)strlen(result);
5622 if (hfinfo->display & BASE_UNIT_STRING) {
5623 double d_value = fvalue_get_floating(&finfo->value);
5624 g_snprintf(result+offset_r, size-offset_r,
5625 "%." G_STRINGIFY(DBL_DIG) "g%s", d_value,
5626 unit_name_string_get_double(d_value, (unit_name_string*)hfinfo->strings));
5628 g_snprintf(result+offset_r, size-offset_r,
5629 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
5631 offset_r = (int)strlen(result);
5636 case FT_UINT_STRING:
5638 bytes = (guint8 *)fvalue_get(&finfo->value);
5639 str = hfinfo_format_text(hfinfo, bytes);
5640 offset_r += protoo_strlcpy(result+offset_r,
5641 str, size-offset_r);
5642 wmem_free(NULL, str);
5645 case FT_IEEE_11073_SFLOAT:
5646 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5647 g_snprintf(result+offset_r, size-offset_r,
5650 wmem_free(NULL, str);
5651 offset_r = (int)strlen(result);
5654 case FT_IEEE_11073_FLOAT:
5655 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5656 g_snprintf(result+offset_r, size-offset_r,
5659 offset_r = (int)strlen(result);
5660 wmem_free(NULL, str);
5663 case FT_IPXNET: /*XXX really No column custom ?*/
5666 g_error("hfinfo->type %d (%s) not handled\n",
5668 ftype_name(hfinfo->type));
5669 DISSECTOR_ASSERT_NOT_REACHED();
5675 switch (hfinfo->type) {
5699 /* for these types, "expr" is filled in the loop above */
5703 /* for all others, just copy "result" to "expr" */
5704 g_strlcpy(expr, result, size);
5709 /* Store abbrev for return value */
5710 abbrev = hfinfo->abbrev;
5713 if (occurrence == 0) {
5714 /* Fetch next hfinfo with same name (abbrev) */
5715 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5722 return abbrev ? abbrev : "";
5726 /* Set text of proto_item after having already been created. */
5728 proto_item_set_text(proto_item *pi, const char *format, ...)
5730 field_info *fi = NULL;
5733 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5735 fi = PITEM_FINFO(pi);
5740 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
5744 va_start(ap, format);
5745 proto_tree_set_representation(pi, format, ap);
5749 /* Append to text of proto_item after having already been created. */
5751 proto_item_append_text(proto_item *pi, const char *format, ...)
5753 field_info *fi = NULL;
5757 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5759 fi = PITEM_FINFO(pi);
5764 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5766 * If we don't already have a representation,
5767 * generate the default representation.
5769 if (fi->rep == NULL) {
5770 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5771 proto_item_fill_label(fi, fi->rep->representation);
5774 curlen = strlen(fi->rep->representation);
5775 if (ITEM_LABEL_LENGTH > curlen) {
5776 va_start(ap, format);
5777 g_vsnprintf(fi->rep->representation + curlen,
5778 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
5784 /* Prepend to text of proto_item after having already been created. */
5786 proto_item_prepend_text(proto_item *pi, const char *format, ...)
5788 field_info *fi = NULL;
5789 char representation[ITEM_LABEL_LENGTH];
5792 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5794 fi = PITEM_FINFO(pi);
5799 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5801 * If we don't already have a representation,
5802 * generate the default representation.
5804 if (fi->rep == NULL) {
5805 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5806 proto_item_fill_label(fi, representation);
5808 g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
5810 va_start(ap, format);
5811 g_vsnprintf(fi->rep->representation,
5812 ITEM_LABEL_LENGTH, format, ap);
5814 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
5819 finfo_set_len(field_info *fi, const gint length)
5821 DISSECTOR_ASSERT(length >= 0);
5822 fi->length = length;
5825 * You cannot just make the "len" field of a GByteArray
5826 * larger, if there's no data to back that length;
5827 * you can only make it smaller.
5829 if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
5830 fi->value.value.bytes->len = length;
5834 proto_item_set_len(proto_item *pi, const gint length)
5838 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5840 fi = PITEM_FINFO(pi);
5844 finfo_set_len(fi, length);
5848 * Sets the length of the item based on its start and on the specified
5849 * offset, which is the offset past the end of the item; as the start
5850 * in the item is relative to the beginning of the data source tvbuff,
5851 * we need to pass in a tvbuff - the end offset is relative to the beginning
5855 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
5860 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5862 fi = PITEM_FINFO(pi);
5866 end += tvb_raw_offset(tvb);
5867 DISSECTOR_ASSERT(end >= fi->start);
5868 length = end - fi->start;
5870 finfo_set_len(fi, length);
5874 proto_item_get_len(const proto_item *pi)
5876 field_info *fi = PITEM_FINFO(pi);
5877 return fi ? fi->length : -1;
5881 proto_tree_create_root(packet_info *pinfo)
5885 /* Initialize the proto_node */
5886 pnode = g_slice_new(proto_tree);
5887 PROTO_NODE_INIT(pnode);
5888 pnode->parent = NULL;
5889 PNODE_FINFO(pnode) = NULL;
5890 pnode->tree_data = g_slice_new(tree_data_t);
5892 /* Make sure we can access pinfo everywhere */
5893 pnode->tree_data->pinfo = pinfo;
5895 /* Don't initialize the tree_data_t. Wait until we know we need it */
5896 pnode->tree_data->interesting_hfids = NULL;
5898 /* Set the default to FALSE so it's easier to
5899 * find errors; if we expect to see the protocol tree
5900 * but for some reason the default 'visible' is not
5901 * changed, then we'll find out very quickly. */
5902 pnode->tree_data->visible = FALSE;
5904 /* Make sure that we fake protocols (if possible) */
5905 pnode->tree_data->fake_protocols = TRUE;
5907 /* Keep track of the number of children */
5908 pnode->tree_data->count = 0;
5910 return (proto_tree *)pnode;
5914 /* "prime" a proto_tree with a single hfid that a dfilter
5915 * is interested in. */
5917 proto_tree_prime_with_hfid(proto_tree *tree _U_, const gint hfid)
5919 header_field_info *hfinfo;
5921 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
5922 /* this field is referenced by a filter so increase the refcount.
5923 also increase the refcount for the parent, i.e the protocol.
5925 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
5926 /* only increase the refcount if there is a parent.
5927 if this is a protocol and not a field then parent will be -1
5928 and there is no parent to add any refcounting for.
5930 if (hfinfo->parent != -1) {
5931 header_field_info *parent_hfinfo;
5932 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
5934 /* Mark parent as indirectly referenced unless it is already directly
5935 * referenced, i.e. the user has specified the parent in a filter.
5937 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
5938 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
5943 proto_item_add_subtree(proto_item *pi, const gint idx) {
5949 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
5951 fi = PITEM_FINFO(pi);
5953 return (proto_tree *)pi;
5955 fi->tree_type = idx;
5957 return (proto_tree *)pi;
5961 proto_item_get_subtree(proto_item *pi) {
5966 fi = PITEM_FINFO(pi);
5967 if ( (!fi) || (fi->tree_type == -1) )
5969 return (proto_tree *)pi;
5973 proto_item_get_parent(const proto_item *ti) {
5980 proto_item_get_parent_nth(proto_item *ti, int gen) {
5993 proto_tree_get_parent(proto_tree *tree) {
5996 return (proto_item *)tree;
6000 proto_tree_get_parent_tree(proto_tree *tree) {
6004 /* we're the root tree, there's no parent
6005 return ourselves so the caller has at least a tree to attach to */
6009 return (proto_tree *)tree->parent;
6013 proto_tree_get_root(proto_tree *tree) {
6016 while (tree->parent) {
6017 tree = tree->parent;
6023 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
6024 proto_item *item_to_move)
6027 /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
6028 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
6030 /* This function doesn't generate any values. It only reorganizes the prococol tree
6031 * so we can bail out immediately if it isn't visible. */
6032 if (!tree || !PTREE_DATA(tree)->visible)
6035 DISSECTOR_ASSERT(item_to_move->parent == tree);
6036 DISSECTOR_ASSERT(fixed_item->parent == tree);
6038 /*** cut item_to_move out ***/
6040 /* is item_to_move the first? */
6041 if (tree->first_child == item_to_move) {
6042 /* simply change first child to next */
6043 tree->first_child = item_to_move->next;
6045 DISSECTOR_ASSERT(tree->last_child != item_to_move);
6047 proto_item *curr_item;
6048 /* find previous and change it's next */
6049 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
6050 if (curr_item->next == item_to_move) {
6055 DISSECTOR_ASSERT(curr_item);
6057 curr_item->next = item_to_move->next;
6059 /* fix last_child if required */
6060 if (tree->last_child == item_to_move) {
6061 tree->last_child = curr_item;
6065 /*** insert to_move after fixed ***/
6066 item_to_move->next = fixed_item->next;
6067 fixed_item->next = item_to_move;
6068 if (tree->last_child == fixed_item) {
6069 tree->last_child = item_to_move;
6074 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
6082 fi = PTREE_FINFO(tree);
6086 start += tvb_raw_offset(tvb);
6087 DISSECTOR_ASSERT(start >= 0);
6088 DISSECTOR_ASSERT(length >= 0);
6090 fi->appendix_start = start;
6091 fi->appendix_length = length;
6095 proto_register_protocol(const char *name, const char *short_name,
6096 const char *filter_name)
6098 protocol_t *protocol;
6099 const protocol_t *existing_protocol = NULL;
6100 header_field_info *hfinfo;
6102 const char *existing_name;
6106 gboolean found_invalid;
6109 * Make sure there's not already a protocol with any of those
6110 * names. Crash if there is, as that's an error in the code
6111 * or an inappropriate plugin.
6112 * This situation has to be fixed to not register more than one
6113 * protocol with the same name.
6115 * This is done by reducing the number of strcmp (and alike) calls
6116 * as much as possible, as this significally slows down startup time.
6118 * Drawback: As a hash value is used to reduce insert time,
6119 * this might lead to a hash collision.
6120 * However, although we have somewhat over 1000 protocols, we're using
6121 * a 32 bit int so this is very, very unlikely.
6124 key = (gint *)g_malloc (sizeof(gint));
6125 *key = wrs_str_hash(name);
6127 existing_name = (const char *)g_hash_table_lookup(proto_names, key);
6128 if (existing_name != NULL) {
6129 /* g_error will terminate the program */
6130 g_error("Duplicate protocol name \"%s\"!"
6131 " This might be caused by an inappropriate plugin or a development error.", name);
6133 g_hash_table_insert(proto_names, key, (gpointer)name);
6135 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
6136 if (existing_protocol != NULL) {
6137 g_error("Duplicate protocol short_name \"%s\"!"
6138 " This might be caused by an inappropriate plugin or a development error.", short_name);
6141 found_invalid = FALSE;
6142 for (i = 0; filter_name[i]; i++) {
6144 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
6145 found_invalid = TRUE;
6148 if (found_invalid) {
6149 g_error("Protocol filter name \"%s\" has one or more invalid characters."
6150 " Allowed are lower characters, digits, '-', '_' and '.'."
6151 " This might be caused by an inappropriate plugin or a development error.", filter_name);
6153 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
6154 if (existing_protocol != NULL) {
6155 g_error("Duplicate protocol filter_name \"%s\"!"
6156 " This might be caused by an inappropriate plugin or a development error.", filter_name);
6159 /* Add this protocol to the list of known protocols; the list
6160 is sorted by protocol short name. */
6161 protocol = g_new(protocol_t, 1);
6162 protocol->name = name;
6163 protocol->short_name = short_name;
6164 protocol->filter_name = filter_name;
6165 /*protocol->fields = g_ptr_array_new();*/
6166 /* Delegate until actually needed and use g_ptr_array_sized_new*/
6167 protocol->fields = NULL;
6168 protocol->is_enabled = TRUE; /* protocol is enabled by default */
6169 protocol->enabled_by_default = TRUE; /* see previous comment */
6170 protocol->can_toggle = TRUE;
6171 protocol->parent_proto_id = -1;
6172 protocol->heur_list = NULL;
6173 /* list will be sorted later by name, when all protocols completed registering */
6174 protocols = g_list_prepend(protocols, protocol);
6175 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
6176 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
6178 /* Here we allocate a new header_field_info struct */
6179 hfinfo = g_slice_new(header_field_info);
6180 hfinfo->name = name;
6181 hfinfo->abbrev = filter_name;
6182 hfinfo->type = FT_PROTOCOL;
6183 hfinfo->display = BASE_NONE;
6184 hfinfo->strings = protocol;
6185 hfinfo->bitmask = 0;
6186 hfinfo->ref_type = HF_REF_TYPE_NONE;
6187 hfinfo->blurb = NULL;
6188 hfinfo->parent = -1; /* this field differentiates protos and fields */
6190 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
6191 protocol->proto_id = proto_id;
6196 proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
6198 protocol_t *protocol;
6199 header_field_info *hfinfo;
6202 gboolean found_invalid = FALSE;
6205 * Helper protocols don't need the strict rules as a "regular" protocol
6206 * Just register it in a list and make a hf_ field from it
6208 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
6209 g_error("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name);
6212 if (parent_proto < 0) {
6213 g_error("Must have a valid parent protocol for helper protocol \"%s\"!"
6214 " This might be caused by an inappropriate plugin or a development error.", name);
6217 for (i = 0; filter_name[i]; i++) {
6219 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
6220 found_invalid = TRUE;
6223 if (found_invalid) {
6224 g_error("Protocol filter name \"%s\" has one or more invalid characters."
6225 " Allowed are lower characters, digits, '-', '_' and '.'."
6226 " This might be caused by an inappropriate plugin or a development error.", filter_name);
6229 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
6230 protocol = g_new(protocol_t, 1);
6231 protocol->name = name;
6232 protocol->short_name = short_name;
6233 protocol->filter_name = filter_name;
6234 protocol->fields = NULL;
6236 /* Enabling and toggling is really determined by parent protocol,
6237 but provide default values here */
6238 protocol->is_enabled = TRUE;
6239 protocol->enabled_by_default = TRUE;
6240 protocol->can_toggle = TRUE;
6242 protocol->parent_proto_id = parent_proto;
6243 protocol->heur_list = NULL;
6244 /* list will be sorted later by name, when all protocols completed registering */
6245 pino_protocols = g_list_prepend(pino_protocols, protocol);
6247 /* Here we allocate a new header_field_info struct */
6248 hfinfo = g_slice_new(header_field_info);
6249 hfinfo->name = name;
6250 hfinfo->abbrev = filter_name;
6251 hfinfo->type = field_type;
6252 hfinfo->display = BASE_NONE;
6253 if (field_type == FT_BYTES) {
6254 hfinfo->display |= (BASE_NO_DISPLAY_VALUE|BASE_PROTOCOL_INFO);
6256 hfinfo->strings = protocol;
6257 hfinfo->bitmask = 0;
6258 hfinfo->ref_type = HF_REF_TYPE_NONE;
6259 hfinfo->blurb = NULL;
6260 hfinfo->parent = -1; /* this field differentiates protos and fields */
6262 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
6263 return protocol->proto_id;
6267 proto_deregister_protocol(const char *short_name)
6269 protocol_t *protocol;
6270 header_field_info *hfinfo;
6275 proto_id = proto_get_id_by_short_name(short_name);
6276 protocol = find_protocol_by_id(proto_id);
6277 if (protocol == NULL)
6280 key = wrs_str_hash(protocol->name);
6281 g_hash_table_remove(proto_names, &key);
6283 g_hash_table_remove(proto_short_names, (gpointer)short_name);
6284 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
6286 if (protocol->fields) {
6287 for (i = 0; i < protocol->fields->len; i++) {
6288 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
6289 hfinfo_remove_from_gpa_name_map(hfinfo);
6290 expert_deregister_expertinfo(hfinfo->abbrev);
6291 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
6293 g_ptr_array_free(protocol->fields, TRUE);
6294 protocol->fields = NULL;
6297 /* Remove this protocol from the list of known protocols */
6298 protocols = g_list_remove(protocols, protocol);
6300 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
6301 g_hash_table_steal(gpa_name_map, protocol->filter_name);
6303 g_free(last_field_name);
6304 last_field_name = NULL;
6310 * Routines to use to iterate over the protocols.
6311 * The argument passed to the iterator routines is an opaque cookie to
6312 * their callers; it's the GList pointer for the current element in
6314 * The ID of the protocol is returned, or -1 if there is no protocol.
6317 proto_get_first_protocol(void **cookie)
6319 protocol_t *protocol;
6321 if (protocols == NULL)
6323 *cookie = protocols;
6324 protocol = (protocol_t *)protocols->data;
6325 return protocol->proto_id;
6329 proto_get_data_protocol(void *cookie)
6331 GList *list_item = (GList *)cookie;
6333 protocol_t *protocol = (protocol_t *)list_item->data;
6334 return protocol->proto_id;
6338 proto_get_next_protocol(void **cookie)
6340 GList *list_item = (GList *)*cookie;
6341 protocol_t *protocol;
6343 list_item = g_list_next(list_item);
6344 if (list_item == NULL)
6346 *cookie = list_item;
6347 protocol = (protocol_t *)list_item->data;
6348 return protocol->proto_id;
6351 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
6352 assume that the cookie stored by
6353 proto_get_(first|next)_protocol_field() will never have a
6354 value of NULL. So, to preserve this semantic, the cookie value
6355 below is adjusted so that the cookie value stored is 1 + the
6356 current (zero-based) array index.
6359 proto_get_first_protocol_field(const int proto_id, void **cookie)
6361 protocol_t *protocol = find_protocol_by_id(proto_id);
6363 if ((protocol == NULL) || (protocol->fields == NULL) || (protocol->fields->len == 0))
6366 *cookie = GUINT_TO_POINTER(0 + 1);
6367 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
6371 proto_get_next_protocol_field(const int proto_id, void **cookie)
6373 protocol_t *protocol = find_protocol_by_id(proto_id);
6374 guint i = GPOINTER_TO_UINT(*cookie) - 1;
6378 if ((protocol->fields == NULL) || (i >= protocol->fields->len))
6381 *cookie = GUINT_TO_POINTER(i + 1);
6382 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
6386 find_protocol_by_id(const int proto_id)
6388 header_field_info *hfinfo;
6393 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
6394 if (hfinfo->type != FT_PROTOCOL) {
6395 DISSECTOR_ASSERT(hfinfo->display & BASE_PROTOCOL_INFO);
6397 return (protocol_t *)hfinfo->strings;
6401 proto_get_id(const protocol_t *protocol)
6403 return protocol->proto_id;
6407 proto_name_already_registered(const gchar *name)
6411 DISSECTOR_ASSERT_HINT(name, "No name present");
6413 key = wrs_str_hash(name);
6414 if (g_hash_table_lookup(proto_names, &key) != NULL)
6420 proto_get_id_by_filter_name(const gchar *filter_name)
6422 const protocol_t *protocol = NULL;
6424 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
6426 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
6428 if (protocol == NULL)
6430 return protocol->proto_id;
6434 proto_get_id_by_short_name(const gchar *short_name)
6436 const protocol_t *protocol = NULL;
6438 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
6440 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
6442 if (protocol == NULL)
6444 return protocol->proto_id;
6448 proto_get_protocol_name(const int proto_id)
6450 protocol_t *protocol;
6452 protocol = find_protocol_by_id(proto_id);
6454 if (protocol == NULL)
6456 return protocol->name;
6460 proto_get_protocol_short_name(const protocol_t *protocol)
6462 if (protocol == NULL)
6464 return protocol->short_name;
6468 proto_get_protocol_long_name(const protocol_t *protocol)
6470 if (protocol == NULL)
6472 return protocol->name;
6476 proto_get_protocol_filter_name(const int proto_id)
6478 protocol_t *protocol;
6480 protocol = find_protocol_by_id(proto_id);
6481 if (protocol == NULL)
6483 return protocol->filter_name;
6486 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
6488 heur_dtbl_entry_t* heuristic_dissector;
6490 if (protocol == NULL)
6493 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
6494 if (heuristic_dissector != NULL)
6496 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
6500 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
6502 if (protocol == NULL)
6505 g_list_foreach(protocol->heur_list, func, user_data);
6509 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
6510 gboolean *is_tcp, gboolean *is_udp,
6511 gboolean *is_sctp, gboolean *is_ssl,
6513 gboolean *is_lte_rlc)
6515 wmem_list_frame_t *protos = wmem_list_head(layers);
6517 const char *proto_name;
6519 /* Walk the list of a available protocols in the packet and
6520 find "major" ones. */
6521 /* It might make more sense to assemble and return a bitfield. */
6522 while (protos != NULL)
6524 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6525 proto_name = proto_get_protocol_filter_name(proto_id);
6527 if (is_ip && ((!strcmp(proto_name, "ip")) ||
6528 (!strcmp(proto_name, "ipv6")))) {
6530 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
6532 } else if (is_udp && !strcmp(proto_name, "udp")) {
6534 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
6536 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
6538 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
6540 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
6544 protos = wmem_list_frame_next(protos);
6549 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
6551 wmem_list_frame_t *protos = wmem_list_head(layers);
6555 /* Walk the list of a available protocols in the packet and
6556 find "major" ones. */
6557 /* It might make more sense to assemble and return a bitfield. */
6558 while (protos != NULL)
6560 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6561 name = proto_get_protocol_filter_name(proto_id);
6563 if (!strcmp(name, proto_name))
6568 protos = wmem_list_frame_next(protos);
6575 proto_is_pino(const protocol_t *protocol)
6577 return (protocol->parent_proto_id != -1);
6581 proto_is_protocol_enabled(const protocol_t *protocol)
6583 //parent protocol determines enable/disable for helper dissectors
6584 if (proto_is_pino(protocol))
6585 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
6587 return protocol->is_enabled;
6591 proto_is_protocol_enabled_by_default(const protocol_t *protocol)
6593 //parent protocol determines enable/disable for helper dissectors
6594 if (proto_is_pino(protocol))
6595 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
6597 return protocol->enabled_by_default;
6601 proto_can_toggle_protocol(const int proto_id)
6603 protocol_t *protocol;
6605 protocol = find_protocol_by_id(proto_id);
6606 //parent protocol determines toggling for helper dissectors
6607 if (proto_is_pino(protocol))
6608 return proto_can_toggle_protocol(protocol->parent_proto_id);
6610 return protocol->can_toggle;
6614 proto_disable_by_default(const int proto_id)
6616 protocol_t *protocol;
6618 protocol = find_protocol_by_id(proto_id);
6619 DISSECTOR_ASSERT(protocol->can_toggle);
6620 DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
6621 protocol->is_enabled = FALSE;
6622 protocol->enabled_by_default = FALSE;
6626 proto_set_decoding(const int proto_id, const gboolean enabled)
6628 protocol_t *protocol;
6630 protocol = find_protocol_by_id(proto_id);
6631 DISSECTOR_ASSERT(protocol->can_toggle);
6632 DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
6633 protocol->is_enabled = enabled;
6637 proto_reenable_all(void)
6639 protocol_t *protocol;
6640 GList *list_item = protocols;
6642 if (protocols == NULL)
6646 protocol = (protocol_t *)list_item->data;
6647 if (protocol->can_toggle && protocol->enabled_by_default)
6648 protocol->is_enabled = TRUE;
6649 list_item = g_list_next(list_item);
6654 proto_set_cant_toggle(const int proto_id)
6656 protocol_t *protocol;
6658 protocol = find_protocol_by_id(proto_id);
6659 protocol->can_toggle = FALSE;
6663 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
6665 if (proto != NULL) {
6666 g_ptr_array_add(proto->fields, hfi);
6669 return proto_register_field_init(hfi, parent);
6672 /* for use with static arrays only, since we don't allocate our own copies
6673 of the header_field_info struct contained within the hf_register_info struct */
6675 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
6677 hf_register_info *ptr = hf;
6681 proto = find_protocol_by_id(parent);
6683 if (proto->fields == NULL) {
6684 proto->fields = g_ptr_array_sized_new(num_records);
6687 for (i = 0; i < num_records; i++, ptr++) {
6689 * Make sure we haven't registered this yet.
6690 * Most fields have variables associated with them
6691 * that are initialized to -1; some have array elements,
6692 * or possibly uninitialized variables, so we also allow
6693 * 0 (which is unlikely to be the field ID we get back
6694 * from "proto_register_field_init()").
6696 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
6698 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
6699 ptr->hfinfo.abbrev);
6703 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
6708 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
6713 proto = find_protocol_by_id(parent);
6715 if (proto->fields == NULL) {
6716 proto->fields = g_ptr_array_sized_new(num_records);
6719 for (i = 0; i < num_records; i++) {
6721 * Make sure we haven't registered this yet.
6723 if (hfi[i].id != -1) {
6725 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6730 proto_register_field_common(proto, &hfi[i], parent);
6735 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
6740 proto = find_protocol_by_id(parent);
6742 if (proto->fields == NULL) {
6743 proto->fields = g_ptr_array_sized_new(num_records);
6747 for (i = 0; i < num_records; i++) {
6749 * Make sure we haven't registered this yet.
6751 if (hfi[i]->id != -1) {
6753 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6758 proto_register_field_common(proto, hfi[i], parent);
6762 /* deregister already registered fields */
6764 proto_deregister_field (const int parent, gint hf_id)
6766 header_field_info *hfi;
6770 g_free(last_field_name);
6771 last_field_name = NULL;
6773 if (hf_id == -1 || hf_id == 0)
6776 proto = find_protocol_by_id (parent);
6777 if (!proto || proto->fields == NULL) {
6781 for (i = 0; i < proto->fields->len; i++) {
6782 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
6783 if (hfi->id == hf_id) {
6784 /* Found the hf_id in this protocol */
6785 g_hash_table_steal(gpa_name_map, hfi->abbrev);
6786 g_ptr_array_remove_index_fast(proto->fields, i);
6787 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
6794 proto_add_deregistered_data (void *data)
6796 g_ptr_array_add(deregistered_data, data);
6800 free_deregistered_field (gpointer data, gpointer user_data _U_)
6802 header_field_info *hfi = (header_field_info *) data;
6803 gint hf_id = hfi->id;
6805 g_free((char *)hfi->name);
6806 g_free((char *)hfi->abbrev);
6807 g_free((char *)hfi->blurb);
6810 switch (hfi->type) {
6812 /* This is just an integer represented as a pointer */
6815 protocol_t *protocol = (protocol_t *)hfi->strings;
6816 g_free((gchar *)protocol->short_name);
6820 true_false_string *tf = (true_false_string *)hfi->strings;
6821 g_free ((gchar *)tf->true_string);
6822 g_free ((gchar *)tf->false_string);
6827 if (hfi->display & BASE_UNIT_STRING) {
6828 unit_name_string *unit = (unit_name_string*)hfi->strings;
6829 g_free ((gchar *)unit->singular);
6830 g_free ((gchar *)unit->plural);
6832 val64_string *vs64 = (val64_string *)hfi->strings;
6833 while (vs64->strptr) {
6834 g_free((gchar *)vs64->strptr);
6841 /* Other Integer types */
6842 if (hfi->display & BASE_UNIT_STRING) {
6843 unit_name_string *unit = (unit_name_string*)hfi->strings;
6844 g_free ((gchar *)unit->singular);
6845 g_free ((gchar *)unit->plural);
6847 value_string *vs = (value_string *)hfi->strings;
6848 while (vs->strptr) {
6849 g_free((gchar *)vs->strptr);
6856 if (hfi->type != FT_FRAMENUM) {
6857 g_free((void *)hfi->strings);
6861 if (hfi->parent == -1)
6862 g_slice_free(header_field_info, hfi);
6864 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
6868 free_deregistered_data (gpointer data, gpointer user_data _U_)
6873 /* free deregistered fields and data */
6875 proto_free_deregistered_fields (void)
6877 expert_free_deregistered_expertinfos();
6879 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
6880 g_ptr_array_free(deregistered_fields, TRUE);
6881 deregistered_fields = g_ptr_array_new();
6883 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
6884 g_ptr_array_free(deregistered_data, TRUE);
6885 deregistered_data = g_ptr_array_new();
6888 /* chars allowed in field abbrev */
6890 const guint8 fld_abbrev_chars[256] = {
6891 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
6892 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
6893 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
6894 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
6895 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
6896 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
6897 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
6898 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
6899 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
6900 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
6901 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
6902 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
6903 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
6904 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
6905 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
6906 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
6909 static const value_string hf_display[] = {
6910 { BASE_NONE, "BASE_NONE" },
6911 { BASE_DEC, "BASE_DEC" },
6912 { BASE_HEX, "BASE_HEX" },
6913 { BASE_OCT, "BASE_OCT" },
6914 { BASE_DEC_HEX, "BASE_DEC_HEX" },
6915 { BASE_HEX_DEC, "BASE_HEX_DEC" },
6916 { BASE_CUSTOM, "BASE_CUSTOM" },
6917 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
6918 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
6919 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
6920 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
6921 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
6922 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
6923 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
6924 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
6925 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
6926 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
6927 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
6928 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
6929 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
6930 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
6931 /* Alias: BASE_NONE { BASE_FLOAT, "BASE_FLOAT" }, */
6932 /* Alias: BASE_NONE { STR_ASCII, "STR_ASCII" }, */
6933 { STR_UNICODE, "STR_UNICODE" },
6934 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
6935 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
6936 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
6937 { BASE_PT_UDP, "BASE_PT_UDP" },
6938 { BASE_PT_TCP, "BASE_PT_TCP" },
6939 { BASE_PT_DCCP, "BASE_PT_DCCP" },
6940 { BASE_PT_SCTP, "BASE_PT_SCTP" },
6943 const char* proto_field_display_to_string(int field_display)
6945 return val_to_str_const(field_display, hf_display, "Unknown");
6948 static inline port_type
6949 display_to_port_type(field_display_e e)
6966 /* temporary function containing assert part for easier profiling */
6968 tmp_fld_check_assert(header_field_info *hfinfo)
6972 /* The field must have a name (with length > 0) */
6973 if (!hfinfo->name || !hfinfo->name[0]) {
6975 /* Try to identify the field */
6976 g_error("Field (abbrev='%s') does not have a name\n",
6980 g_error("Field does not have a name (nor an abbreviation)\n");
6983 /* fields with an empty string for an abbreviation aren't filterable */
6984 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
6985 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
6987 /* These types of fields are allowed to have value_strings,
6988 * true_false_strings or a protocol_t struct
6990 if (hfinfo->strings != NULL) {
6991 switch(hfinfo->type) {
7015 //allowed to support string if its a unit decsription
7016 if (hfinfo->display & BASE_UNIT_STRING)
7021 //allowed to support string if its a protocol (for pinos)
7022 if (hfinfo->display & BASE_PROTOCOL_INFO)
7027 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
7028 " (which is not allowed to have strings)\n",
7029 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
7033 /* TODO: This check may slow down startup, and output quite a few warnings.
7034 It would be good to be able to enable this (and possibly other checks?)
7035 in non-release builds. */
7037 /* Check for duplicate value_string values.
7038 There are lots that have the same value *and* string, so for now only
7039 report those that have same value but different string. */
7040 if ((hfinfo->strings != NULL) &&
7041 !(hfinfo->display & BASE_RANGE_STRING) &&
7042 !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
7044 (hfinfo->type == FT_CHAR) ||
7045 (hfinfo->type == FT_UINT8) ||
7046 (hfinfo->type == FT_UINT16) ||
7047 (hfinfo->type == FT_UINT24) ||
7048 (hfinfo->type == FT_UINT32) ||
7049 (hfinfo->type == FT_INT8) ||
7050 (hfinfo->type == FT_INT16) ||
7051 (hfinfo->type == FT_INT24) ||
7052 (hfinfo->type == FT_INT32) ||
7053 (hfinfo->type == FT_FRAMENUM) )) {
7056 const value_string *start_values;
7057 const value_string *current;
7059 if (hfinfo->display & BASE_EXT_STRING)
7060 start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
7062 start_values = (const value_string*)hfinfo->strings;
7063 current = start_values;
7065 for (n=0; current; n++, current++) {
7066 /* Drop out if we reached the end. */
7067 if ((current->value == 0) && (current->strptr == NULL)) {
7071 /* Check value against all previous */
7072 for (m=0; m < n; m++) {
7073 /* There are lots of duplicates with the same string,
7074 so only report if different... */
7075 if ((start_values[m].value == current->value) &&
7076 (strcmp(start_values[m].strptr, current->strptr) != 0)) {
7077 ws_g_warning("Field '%s' (%s) has a conflicting entry in its"
7078 " value_string: %u is at indices %u (%s) and %u (%s))\n",
7079 hfinfo->name, hfinfo->abbrev,
7080 current->value, m, start_values[m].strptr, n, current->strptr);
7088 switch (hfinfo->type) {
7091 /* Require the char type to have BASE_HEX, BASE_OCT,
7092 * BASE_CUSTOM, or BASE_NONE as its base.
7094 * If the display value is BASE_NONE and there is a
7095 * strings conversion then the dissector writer is
7096 * telling us that the field's numerical value is
7097 * meaningless; we'll avoid showing the value to the
7100 switch (FIELD_DISPLAY(hfinfo->display)) {
7103 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
7106 if (hfinfo->strings == NULL)
7107 g_error("Field '%s' (%s) is an integral value (%s)"
7108 " but is being displayed as BASE_NONE but"
7109 " without a strings conversion",
7110 hfinfo->name, hfinfo->abbrev,
7111 ftype_name(hfinfo->type));
7114 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7115 g_error("Field '%s' (%s) is a character value (%s)"
7116 " but is being displayed as %s\n",
7117 hfinfo->name, hfinfo->abbrev,
7118 ftype_name(hfinfo->type), tmp_str);
7119 wmem_free(NULL, tmp_str);
7121 if (hfinfo->display & BASE_UNIT_STRING) {
7122 g_error("Field '%s' (%s) is a character value (%s) but has a unit string\n",
7123 hfinfo->name, hfinfo->abbrev,
7124 ftype_name(hfinfo->type));
7135 /* Hexadecimal and octal are, in printf() and everywhere
7136 * else, unsigned so don't allow dissectors to register a
7137 * signed field to be displayed unsigned. (Else how would
7138 * we display negative values?)
7140 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
7145 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7146 g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
7147 hfinfo->name, hfinfo->abbrev,
7148 ftype_name(hfinfo->type), tmp_str);
7149 wmem_free(NULL, tmp_str);
7160 if (IS_BASE_PORT(hfinfo->display)) {
7161 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7162 if (hfinfo->type != FT_UINT16) {
7163 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
7164 hfinfo->name, hfinfo->abbrev,
7165 tmp_str, ftype_name(hfinfo->type));
7167 if (hfinfo->strings != NULL) {
7168 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
7169 hfinfo->name, hfinfo->abbrev,
7170 ftype_name(hfinfo->type), tmp_str);
7172 if (hfinfo->bitmask != 0) {
7173 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
7174 hfinfo->name, hfinfo->abbrev,
7175 ftype_name(hfinfo->type), tmp_str);
7177 wmem_free(NULL, tmp_str);
7181 /* Require integral types (other than frame number,
7182 * which is always displayed in decimal) to have a
7185 * If the display value is BASE_NONE and there is a
7186 * strings conversion then the dissector writer is
7187 * telling us that the field's numerical value is
7188 * meaningless; we'll avoid showing the value to the
7191 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
7197 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
7200 if (hfinfo->strings == NULL) {
7201 g_error("Field '%s' (%s) is an integral value (%s)"
7202 " but is being displayed as BASE_NONE but"
7203 " without a strings conversion",
7204 hfinfo->name, hfinfo->abbrev,
7205 ftype_name(hfinfo->type));
7207 if (hfinfo->display & BASE_SPECIAL_VALS) {
7208 g_error("Field '%s' (%s) is an integral value (%s)"
7209 " that is being displayed as BASE_NONE but"
7210 " with BASE_SPECIAL_VALS",
7211 hfinfo->name, hfinfo->abbrev,
7212 ftype_name(hfinfo->type));
7217 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7218 g_error("Field '%s' (%s) is an integral value (%s)"
7219 " but is being displayed as %s\n",
7220 hfinfo->name, hfinfo->abbrev,
7221 ftype_name(hfinfo->type), tmp_str);
7222 wmem_free(NULL, tmp_str);
7227 /* Require bytes to have a "display type" that could
7228 * add a character between displayed bytes.
7230 switch (FIELD_DISPLAY(hfinfo->display)) {
7238 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7239 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",
7240 hfinfo->name, hfinfo->abbrev, tmp_str);
7241 wmem_free(NULL, tmp_str);
7243 if (hfinfo->bitmask != 0)
7244 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7245 hfinfo->name, hfinfo->abbrev,
7246 ftype_name(hfinfo->type));
7247 //allowed to support string if its a protocol (for pinos)
7248 if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_PROTOCOL_INFO)))
7249 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7250 hfinfo->name, hfinfo->abbrev,
7251 ftype_name(hfinfo->type));
7256 if (hfinfo->display != BASE_NONE) {
7257 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7258 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7259 hfinfo->name, hfinfo->abbrev,
7260 ftype_name(hfinfo->type), tmp_str);
7261 wmem_free(NULL, tmp_str);
7263 if (hfinfo->bitmask != 0)
7264 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7265 hfinfo->name, hfinfo->abbrev,
7266 ftype_name(hfinfo->type));
7272 case FT_ABSOLUTE_TIME:
7273 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
7274 hfinfo->display == ABSOLUTE_TIME_UTC ||
7275 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
7276 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7277 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
7278 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
7279 wmem_free(NULL, tmp_str);
7281 if (hfinfo->bitmask != 0)
7282 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7283 hfinfo->name, hfinfo->abbrev,
7284 ftype_name(hfinfo->type));
7289 case FT_UINT_STRING:
7291 switch (hfinfo->display) {
7297 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7298 g_error("Field '%s' (%s) is an string value (%s)"
7299 " but is being displayed as %s\n",
7300 hfinfo->name, hfinfo->abbrev,
7301 ftype_name(hfinfo->type), tmp_str);
7302 wmem_free(NULL, tmp_str);
7305 if (hfinfo->bitmask != 0)
7306 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7307 hfinfo->name, hfinfo->abbrev,
7308 ftype_name(hfinfo->type));
7309 if (hfinfo->strings != NULL)
7310 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7311 hfinfo->name, hfinfo->abbrev,
7312 ftype_name(hfinfo->type));
7316 switch (hfinfo->display) {
7322 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7323 g_error("Field '%s' (%s) is an IPv4 value (%s)"
7324 " but is being displayed as %s\n",
7325 hfinfo->name, hfinfo->abbrev,
7326 ftype_name(hfinfo->type), tmp_str);
7327 wmem_free(NULL, tmp_str);
7333 if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
7334 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7335 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7336 hfinfo->name, hfinfo->abbrev,
7337 ftype_name(hfinfo->type),
7339 wmem_free(NULL, tmp_str);
7341 if (hfinfo->bitmask != 0)
7342 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7343 hfinfo->name, hfinfo->abbrev,
7344 ftype_name(hfinfo->type));
7345 if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_UNIT_STRING)))
7346 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7347 hfinfo->name, hfinfo->abbrev,
7348 ftype_name(hfinfo->type));
7351 if (hfinfo->display != BASE_NONE) {
7352 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7353 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7354 hfinfo->name, hfinfo->abbrev,
7355 ftype_name(hfinfo->type),
7357 wmem_free(NULL, tmp_str);
7359 if (hfinfo->bitmask != 0)
7360 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7361 hfinfo->name, hfinfo->abbrev,
7362 ftype_name(hfinfo->type));
7363 if (hfinfo->strings != NULL)
7364 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7365 hfinfo->name, hfinfo->abbrev,
7366 ftype_name(hfinfo->type));
7371 #ifdef ENABLE_CHECK_FILTER
7373 _ftype_common(enum ftenum type)
7397 case FT_UINT_STRING:
7410 case FT_ABSOLUTE_TIME:
7411 case FT_RELATIVE_TIME:
7412 return FT_ABSOLUTE_TIME;
7421 register_type_length_mismatch(void)
7423 static ei_register_info ei[] = {
7424 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
7425 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
7428 expert_module_t* expert_type_length_mismatch;
7430 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
7432 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
7433 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
7435 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
7436 disabling them makes no sense. */
7437 proto_set_cant_toggle(proto_type_length_mismatch);
7441 register_number_string_decoding_error(void)
7443 static ei_register_info ei[] = {
7444 { &ei_number_string_decoding_failed_error,
7445 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
7446 "Failed to decode number from string", EXPFILL
7449 { &ei_number_string_decoding_erange_error,
7450 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
7451 "Decoded number from string is out of valid range", EXPFILL
7456 expert_module_t* expert_number_string_decoding_error;
7458 proto_number_string_decoding_error =
7459 proto_register_protocol("Number-String Decoding Error",
7460 "Number-string decoding error",
7461 "_ws.number_string.decoding_error");
7463 expert_number_string_decoding_error =
7464 expert_register_protocol(proto_number_string_decoding_error);
7465 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
7467 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
7468 disabling them makes no sense. */
7469 proto_set_cant_toggle(proto_number_string_decoding_error);
7472 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (188000+PRE_ALLOC_EXPERT_FIELDS_MEM)
7474 proto_register_field_init(header_field_info *hfinfo, const int parent)
7477 tmp_fld_check_assert(hfinfo);
7479 hfinfo->parent = parent;
7480 hfinfo->same_name_next = NULL;
7481 hfinfo->same_name_prev_id = -1;
7483 /* if we always add and never delete, then id == len - 1 is correct */
7484 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
7485 if (!gpa_hfinfo.hfi) {
7486 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
7487 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
7489 gpa_hfinfo.allocated_len += 1000;
7490 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
7491 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
7492 /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
7495 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
7497 hfinfo->id = gpa_hfinfo.len - 1;
7499 /* if we have real names, enter this field in the name tree */
7500 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
7502 header_field_info *same_name_next_hfinfo;
7505 /* Check that the filter name (abbreviation) is legal;
7506 * it must contain only alphanumerics, '-', "_", and ".". */
7507 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
7509 if (g_ascii_isprint(c))
7510 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
7512 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
7513 DISSECTOR_ASSERT_NOT_REACHED();
7516 /* We allow multiple hfinfo's to be registered under the same
7517 * abbreviation. This was done for X.25, as, depending
7518 * on whether it's modulo-8 or modulo-128 operation,
7519 * some bitfield fields may be in different bits of
7520 * a byte, and we want to be able to refer to that field
7521 * with one name regardless of whether the packets
7522 * are modulo-8 or modulo-128 packets. */
7524 same_name_hfinfo = NULL;
7526 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
7527 /* GLIB 2.x - if it is already present
7528 * the previous hfinfo with the same name is saved
7529 * to same_name_hfinfo by value destroy callback */
7530 if (same_name_hfinfo) {
7531 /* There's already a field with this name.
7532 * Put the current field *before* that field
7533 * in the list of fields with this name, Thus,
7534 * we end up with an effectively
7535 * doubly-linked-list of same-named hfinfo's,
7536 * with the head of the list (stored in the
7537 * hash) being the last seen hfinfo.
7539 same_name_next_hfinfo =
7540 same_name_hfinfo->same_name_next;
7542 hfinfo->same_name_next = same_name_next_hfinfo;
7543 if (same_name_next_hfinfo)
7544 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
7546 same_name_hfinfo->same_name_next = hfinfo;
7547 hfinfo->same_name_prev_id = same_name_hfinfo->id;
7548 #ifdef ENABLE_CHECK_FILTER
7549 while (same_name_hfinfo) {
7550 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
7551 fprintf(stderr, "'%s' exists multiple times with NOT compatible types: %s and %s\n", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type));
7552 same_name_hfinfo = same_name_hfinfo->same_name_next;
7562 proto_register_subtree_array(gint *const *indices, const int num_indices)
7565 gint *const *ptr = indices;
7568 * If we've already allocated the array of tree types, expand
7569 * it; this lets plugins such as mate add tree types after
7570 * the initial startup. (If we haven't already allocated it,
7571 * we don't allocate it; on the first pass, we just assign
7572 * ett values and keep track of how many we've assigned, and
7573 * when we're finished registering all dissectors we allocate
7574 * the array, so that we do only one allocation rather than
7575 * wasting CPU time and memory by growing the array for each
7576 * dissector that registers ett values.)
7578 if (tree_is_expanded != NULL) {
7579 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
7581 /* set new items to 0 */
7582 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
7583 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
7584 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
7588 * Assign "num_indices" subtree numbers starting at "num_tree_types",
7589 * returning the indices through the pointers in the array whose
7590 * first element is pointed to by "indices", and update
7591 * "num_tree_types" appropriately.
7593 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
7595 /* g_error will terminate the program */
7596 g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
7597 " This is a development error:"
7598 " Either the subtree item type has already been assigned or"
7599 " was not initialized to -1.");
7601 **ptr = num_tree_types;
7606 label_concat(char *label_str, gsize pos, const char *str)
7608 if (pos < ITEM_LABEL_LENGTH)
7609 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
7615 label_mark_truncated(char *label_str, gsize name_pos)
7617 static const char trunc_str[] = " [truncated]";
7618 const size_t trunc_len = sizeof(trunc_str)-1;
7621 /* ..... field_name: dataaaaaaaaaaaaa
7625 * ..... field_name [truncated]: dataaaaaaaaaaaaa
7627 * name_pos==0 means that we have only data or only a field_name
7630 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
7631 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
7632 memcpy(label_str + name_pos, trunc_str, trunc_len);
7634 /* in general, label_str is UTF-8
7635 we can truncate it only at the beginning of a new character
7636 we go backwards from the byte right after our buffer and
7637 find the next starting byte of a UTF-8 character, this is
7639 there's no need to use g_utf8_find_prev_char(), the search
7640 will always succeed since we copied trunc_str into the
7642 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH]);
7645 } else if (name_pos < ITEM_LABEL_LENGTH)
7646 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
7650 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
7654 /* "%s: %s", hfinfo->name, text */
7655 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
7656 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
7657 pos = label_concat(label_str, pos, ": ");
7658 pos = label_concat(label_str, pos, text ? text : "(null)");
7661 if (pos >= ITEM_LABEL_LENGTH) {
7662 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7663 label_mark_truncated(label_str, name_pos);
7670 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
7674 /* "%s: %s (%s)", hfinfo->name, text, descr */
7675 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
7676 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
7677 pos = label_concat(label_str, pos, ": ");
7678 if (hfinfo->display & BASE_UNIT_STRING) {
7679 pos = label_concat(label_str, pos, descr ? descr : "(null)");
7680 pos = label_concat(label_str, pos, text ? text : "(null)");
7682 pos = label_concat(label_str, pos, text ? text : "(null)");
7683 pos = label_concat(label_str, pos, " (");
7684 pos = label_concat(label_str, pos, descr ? descr : "(null)");
7685 pos = label_concat(label_str, pos, ")");
7689 if (pos >= ITEM_LABEL_LENGTH) {
7690 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7691 label_mark_truncated(label_str, name_pos);
7698 proto_item_fill_label(field_info *fi, gchar *label_str)
7700 header_field_info *hfinfo;
7704 ipv4_addr_and_mask *ipv4;
7706 guint32 n_addr; /* network-order IPv4 address */
7715 /* XXX: Check validity of hfinfo->type */
7719 hfinfo = fi->hfinfo;
7721 switch (hfinfo->type) {
7724 g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
7728 fill_label_boolean(fi, label_str);
7733 bytes = (guint8 *)fvalue_get(&fi->value);
7736 switch(hfinfo->display)
7739 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
7742 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
7745 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
7748 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7752 if (prefs.display_byte_fields_with_spaces)
7754 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7758 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
7762 label_fill(label_str, 0, hfinfo, str);
7763 wmem_free(NULL, str);
7765 if (hfinfo->display & BASE_ALLOW_ZERO) {
7766 label_fill(label_str, 0, hfinfo, "<none>");
7768 label_fill(label_str, 0, hfinfo, "<MISSING>");
7774 if (hfinfo->bitmask) {
7775 fill_label_bitfield_char(fi, label_str);
7777 fill_label_char(fi, label_str);
7781 /* Four types of integers to take care of:
7782 * Bitfield, with val_string
7783 * Bitfield, w/o val_string
7784 * Non-bitfield, with val_string
7785 * Non-bitfield, w/o val_string
7791 if (hfinfo->bitmask) {
7792 fill_label_bitfield(fi, label_str, FALSE);
7794 fill_label_number(fi, label_str, FALSE);
7799 fill_label_number(fi, label_str, FALSE);
7806 if (hfinfo->bitmask) {
7807 fill_label_bitfield64(fi, label_str, FALSE);
7809 fill_label_number64(fi, label_str, FALSE);
7817 if (hfinfo->bitmask) {
7818 fill_label_bitfield(fi, label_str, TRUE);
7820 fill_label_number(fi, label_str, TRUE);
7828 if (hfinfo->bitmask) {
7829 fill_label_bitfield64(fi, label_str, TRUE);
7831 fill_label_number64(fi, label_str, TRUE);
7836 double d_value = fvalue_get_floating(&fi->value);
7837 if (hfinfo->display & BASE_UNIT_STRING) {
7838 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7839 "%s: %." G_STRINGIFY(FLT_DIG) "g%s",
7840 hfinfo->name, d_value,
7841 unit_name_string_get_double(d_value, (unit_name_string*)hfinfo->strings));
7843 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7844 "%s: %." G_STRINGIFY(FLT_DIG) "g",
7845 hfinfo->name, d_value);
7851 double d_value = fvalue_get_floating(&fi->value);
7852 if (hfinfo->display & BASE_UNIT_STRING) {
7853 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7854 "%s: %." G_STRINGIFY(DBL_DIG) "g%s",
7855 hfinfo->name, d_value,
7856 unit_name_string_get_double(d_value, (unit_name_string*)hfinfo->strings));
7858 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7859 "%s: %." G_STRINGIFY(DBL_DIG) "g",
7860 hfinfo->name, d_value);
7865 case FT_ABSOLUTE_TIME:
7866 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
7867 label_fill(label_str, 0, hfinfo, tmp);
7868 wmem_free(NULL, tmp);
7871 case FT_RELATIVE_TIME:
7872 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
7873 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7874 "%s: %s seconds", hfinfo->name, tmp);
7875 wmem_free(NULL, tmp);
7879 integer = fvalue_get_uinteger(&fi->value);
7880 tmp = get_ipxnet_name(NULL, integer);
7881 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7882 "%s: %s (0x%08X)", hfinfo->name,
7884 wmem_free(NULL, tmp);
7888 addr.type = AT_AX25;
7889 addr.len = AX25_ADDR_LEN;
7890 addr.data = (guint8 *)fvalue_get(&fi->value);
7892 addr_str = (char*)address_to_str(NULL, &addr);
7893 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7894 "%s: %s", hfinfo->name, addr_str);
7895 wmem_free(NULL, addr_str);
7899 addr.type = vines_address_type;
7900 addr.len = VINES_ADDR_LEN;
7901 addr.data = (guint8 *)fvalue_get(&fi->value);
7903 addr_str = (char*)address_to_str(NULL, &addr);
7904 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7905 "%s: %s", hfinfo->name, addr_str);
7906 wmem_free(NULL, addr_str);
7910 bytes = (guint8 *)fvalue_get(&fi->value);
7912 addr.type = AT_ETHER;
7916 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7917 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7918 "%s: %s", hfinfo->name, addr_str);
7919 wmem_free(NULL, addr_str);
7923 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&fi->value);
7924 n_addr = ipv4_get_net_order_addr(ipv4);
7926 addr.type = AT_IPv4;
7928 addr.data = &n_addr;
7930 if (hfinfo->display == BASE_NETMASK)
7932 addr_str = (char*)address_to_str(NULL, &addr);
7936 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7938 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7939 "%s: %s", hfinfo->name, addr_str);
7940 wmem_free(NULL, addr_str);
7944 bytes = (guint8 *)fvalue_get(&fi->value);
7946 addr.type = AT_IPv6;
7950 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7951 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7952 "%s: %s", hfinfo->name, addr_str);
7953 wmem_free(NULL, addr_str);
7957 addr.type = AT_FCWWN;
7958 addr.len = FCWWN_ADDR_LEN;
7959 addr.data = (guint8 *)fvalue_get(&fi->value);
7961 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7962 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7963 "%s: %s", hfinfo->name, addr_str);
7964 wmem_free(NULL, addr_str);
7968 guid = (e_guid_t *)fvalue_get(&fi->value);
7969 tmp = guid_to_str(NULL, guid);
7970 label_fill(label_str, 0, hfinfo, tmp);
7971 wmem_free(NULL, tmp);
7975 bytes = (guint8 *)fvalue_get(&fi->value);
7976 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7977 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7979 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7980 wmem_free(NULL, name);
7982 label_fill(label_str, 0, hfinfo, tmp);
7984 wmem_free(NULL, tmp);
7988 bytes = (guint8 *)fvalue_get(&fi->value);
7989 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7990 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7992 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7993 wmem_free(NULL, name);
7995 label_fill(label_str, 0, hfinfo, tmp);
7997 wmem_free(NULL, tmp);
8001 bytes = (guint8 *)fvalue_get(&fi->value);
8002 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
8003 label_fill(label_str, 0, hfinfo, tmp);
8004 wmem_free(NULL, tmp);
8008 integer64 = fvalue_get_uinteger64(&fi->value);
8009 addr_str = eui64_to_str(NULL, integer64);
8010 tmp = (char*)eui64_to_display(NULL, integer64);
8011 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
8012 wmem_free(NULL, tmp);
8013 wmem_free(NULL, addr_str);
8017 case FT_UINT_STRING:
8019 bytes = (guint8 *)fvalue_get(&fi->value);
8020 tmp = hfinfo_format_text(hfinfo, bytes);
8021 label_fill(label_str, 0, hfinfo, tmp);
8022 wmem_free(NULL, tmp);
8025 case FT_IEEE_11073_SFLOAT:
8026 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
8027 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8030 wmem_free(NULL, tmp);
8032 case FT_IEEE_11073_FLOAT:
8033 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
8034 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8037 wmem_free(NULL, tmp);
8041 g_error("hfinfo->type %d (%s) not handled\n",
8042 hfinfo->type, ftype_name(hfinfo->type));
8043 DISSECTOR_ASSERT_NOT_REACHED();
8049 fill_label_boolean(field_info *fi, gchar *label_str)
8051 char *p = label_str;
8052 int bitfield_byte_length = 0, bitwidth;
8053 guint64 unshifted_value;
8056 header_field_info *hfinfo = fi->hfinfo;
8057 const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
8059 if (hfinfo->strings) {
8060 tfstring = (const struct true_false_string*) hfinfo->strings;
8063 value = fvalue_get_uinteger64(&fi->value);
8064 if (hfinfo->bitmask) {
8065 /* Figure out the bit width */
8066 bitwidth = hfinfo_container_bitwidth(hfinfo);
8069 unshifted_value = value;
8070 unshifted_value <<= hfinfo_bitshift(hfinfo);
8072 /* Create the bitfield first */
8073 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8074 bitfield_byte_length = (int) (p - label_str);
8077 /* Fill in the textual info */
8078 label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
8082 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
8084 if (hfinfo->display & BASE_RANGE_STRING)
8085 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
8087 if (hfinfo->display & BASE_EXT_STRING)
8088 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
8090 if (hfinfo->display & BASE_VAL64_STRING)
8091 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
8093 if (hfinfo->display & BASE_UNIT_STRING)
8094 return unit_name_string_get_value(value, (struct unit_name_string*) hfinfo->strings);
8096 return try_val_to_str(value, (const value_string *) hfinfo->strings);
8100 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
8102 if (hfinfo->display & BASE_VAL64_STRING)
8103 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
8105 if (hfinfo->display & BASE_RANGE_STRING)
8106 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
8108 if (hfinfo->display & BASE_UNIT_STRING)
8109 return unit_name_string_get_value64(value, (struct unit_name_string*) hfinfo->strings);
8111 /* If this is reached somebody registered a 64-bit field with a 32-bit
8112 * value-string, which isn't right. */
8113 DISSECTOR_ASSERT_NOT_REACHED();
8115 /* This is necessary to squelch MSVC errors; is there
8116 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
8122 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
8124 const char *str = hf_try_val_to_str(value, hfinfo);
8126 return (str) ? str : unknown_str;
8130 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
8132 const char *str = hf_try_val64_to_str(value, hfinfo);
8134 return (str) ? str : unknown_str;
8137 /* Fills data for bitfield chars with val_strings */
8139 fill_label_bitfield_char(field_info *fi, gchar *label_str)
8142 int bitfield_byte_length, bitwidth;
8143 guint32 unshifted_value;
8149 header_field_info *hfinfo = fi->hfinfo;
8151 /* Figure out the bit width */
8152 bitwidth = hfinfo_container_bitwidth(hfinfo);
8155 value = fvalue_get_uinteger(&fi->value);
8157 unshifted_value = value;
8158 if (hfinfo->bitmask) {
8159 unshifted_value <<= hfinfo_bitshift(hfinfo);
8162 /* Create the bitfield first */
8163 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8164 bitfield_byte_length = (int) (p - label_str);
8166 /* Fill in the textual info using stored (shifted) value */
8167 if (hfinfo->display == BASE_CUSTOM) {
8168 gchar tmp[ITEM_LABEL_LENGTH];
8169 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8171 DISSECTOR_ASSERT(fmtfunc);
8172 fmtfunc(tmp, value);
8173 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8175 else if (hfinfo->strings) {
8176 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8178 out = hfinfo_char_vals_format(hfinfo, buf, value);
8179 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8180 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8182 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8185 out = hfinfo_char_value_format(hfinfo, buf, value);
8187 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8191 /* Fills data for bitfield ints with val_strings */
8193 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
8196 int bitfield_byte_length, bitwidth;
8197 guint32 unshifted_value;
8203 header_field_info *hfinfo = fi->hfinfo;
8205 /* Figure out the bit width */
8206 bitwidth = hfinfo_container_bitwidth(hfinfo);
8210 value = fvalue_get_sinteger(&fi->value);
8212 value = fvalue_get_uinteger(&fi->value);
8214 unshifted_value = value;
8215 if (hfinfo->bitmask) {
8216 unshifted_value <<= hfinfo_bitshift(hfinfo);
8219 /* Create the bitfield first */
8220 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8221 bitfield_byte_length = (int) (p - label_str);
8223 /* Fill in the textual info using stored (shifted) value */
8224 if (hfinfo->display == BASE_CUSTOM) {
8225 gchar tmp[ITEM_LABEL_LENGTH];
8226 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8228 DISSECTOR_ASSERT(fmtfunc);
8229 fmtfunc(tmp, value);
8230 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8232 else if (hfinfo->strings) {
8233 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8235 out = hfinfo_number_vals_format(hfinfo, buf, value);
8236 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8237 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8239 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8242 out = hfinfo_number_value_format(hfinfo, buf, value);
8244 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8249 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
8252 int bitfield_byte_length, bitwidth;
8253 guint64 unshifted_value;
8259 header_field_info *hfinfo = fi->hfinfo;
8261 /* Figure out the bit width */
8262 bitwidth = hfinfo_container_bitwidth(hfinfo);
8266 value = fvalue_get_sinteger64(&fi->value);
8268 value = fvalue_get_uinteger64(&fi->value);
8270 unshifted_value = value;
8271 if (hfinfo->bitmask) {
8272 unshifted_value <<= hfinfo_bitshift(hfinfo);
8275 /* Create the bitfield first */
8276 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8277 bitfield_byte_length = (int) (p - label_str);
8279 /* Fill in the textual info using stored (shifted) value */
8280 if (hfinfo->display == BASE_CUSTOM) {
8281 gchar tmp[ITEM_LABEL_LENGTH];
8282 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
8284 DISSECTOR_ASSERT(fmtfunc64);
8285 fmtfunc64(tmp, value);
8286 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8288 else if (hfinfo->strings) {
8289 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
8291 out = hfinfo_number_vals_format64(hfinfo, buf, value);
8292 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8293 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8295 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8298 out = hfinfo_number_value_format64(hfinfo, buf, value);
8300 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8305 fill_label_char(field_info *fi, gchar *label_str)
8307 header_field_info *hfinfo = fi->hfinfo;
8313 value = fvalue_get_uinteger(&fi->value);
8315 /* Fill in the textual info */
8316 if (hfinfo->display == BASE_CUSTOM) {
8317 gchar tmp[ITEM_LABEL_LENGTH];
8318 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8320 DISSECTOR_ASSERT(fmtfunc);
8321 fmtfunc(tmp, value);
8322 label_fill(label_str, 0, hfinfo, tmp);
8324 else if (hfinfo->strings) {
8325 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8327 out = hfinfo_char_vals_format(hfinfo, buf, value);
8328 label_fill_descr(label_str, 0, hfinfo, val_str, out);
8331 out = hfinfo_char_value_format(hfinfo, buf, value);
8333 label_fill(label_str, 0, hfinfo, out);
8338 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
8340 header_field_info *hfinfo = fi->hfinfo;
8347 value = fvalue_get_sinteger(&fi->value);
8349 value = fvalue_get_uinteger(&fi->value);
8351 /* Fill in the textual info */
8352 if (hfinfo->display == BASE_CUSTOM) {
8353 gchar tmp[ITEM_LABEL_LENGTH];
8354 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8356 DISSECTOR_ASSERT(fmtfunc);
8357 fmtfunc(tmp, value);
8358 label_fill(label_str, 0, hfinfo, tmp);
8360 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
8362 * It makes no sense to have a value-string table for a
8363 * frame-number field - they're just integers giving
8364 * the ordinal frame number.
8366 const char *val_str = hf_try_val_to_str(value, hfinfo);
8368 out = hfinfo_number_vals_format(hfinfo, buf, value);
8369 if (hfinfo->display & BASE_SPECIAL_VALS) {
8371 * Unique values only display value_string string
8372 * if there is a match. Otherwise it's just a number
8375 label_fill_descr(label_str, 0, hfinfo, val_str, out);
8377 label_fill(label_str, 0, hfinfo, out);
8380 if (val_str == NULL)
8381 val_str = "Unknown";
8383 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8384 label_fill(label_str, 0, hfinfo, val_str);
8386 label_fill_descr(label_str, 0, hfinfo, val_str, out);
8389 else if (IS_BASE_PORT(hfinfo->display)) {
8390 gchar tmp[ITEM_LABEL_LENGTH];
8392 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
8393 display_to_port_type((field_display_e)hfinfo->display), value);
8394 label_fill(label_str, 0, hfinfo, tmp);
8397 out = hfinfo_number_value_format(hfinfo, buf, value);
8399 label_fill(label_str, 0, hfinfo, out);
8404 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
8406 header_field_info *hfinfo = fi->hfinfo;
8413 value = fvalue_get_sinteger64(&fi->value);
8415 value = fvalue_get_uinteger64(&fi->value);
8417 /* Fill in the textual info */
8418 if (hfinfo->display == BASE_CUSTOM) {
8419 gchar tmp[ITEM_LABEL_LENGTH];
8420 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
8422 DISSECTOR_ASSERT(fmtfunc64);
8423 fmtfunc64(tmp, value);
8424 label_fill(label_str, 0, hfinfo, tmp);
8426 else if (hfinfo->strings) {
8427 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
8429 out = hfinfo_number_vals_format64(hfinfo, buf, value);
8430 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8431 label_fill(label_str, 0, hfinfo, val_str);
8433 label_fill_descr(label_str, 0, hfinfo, val_str, out);
8436 out = hfinfo_number_value_format64(hfinfo, buf, value);
8438 label_fill(label_str, 0, hfinfo, out);
8443 hfinfo_bitshift(const header_field_info *hfinfo)
8445 return ws_ctz(hfinfo->bitmask);
8449 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
8451 if (!hfinfo->bitmask) {
8455 /* ilog2 = first set bit, ctz = last set bit */
8456 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
8460 hfinfo_type_bitwidth(enum ftenum type)
8499 DISSECTOR_ASSERT_NOT_REACHED();
8507 hfinfo_container_bitwidth(const header_field_info *hfinfo)
8509 if (!hfinfo->bitmask) {
8513 if (hfinfo->type == FT_BOOLEAN) {
8514 return hfinfo->display; /* hacky? :) */
8517 return hfinfo_type_bitwidth(hfinfo->type);
8521 hfinfo_hex_digits(const header_field_info *hfinfo)
8525 /* If we have a bitmask, hfinfo->type is the width of the container, so not
8526 * appropriate to determine the number of hex digits for the field.
8527 * So instead, we compute it from the bitmask.
8529 if (hfinfo->bitmask != 0) {
8530 bitwidth = hfinfo_mask_bitwidth(hfinfo);
8532 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
8535 /* Divide by 4, rounding up, to get number of hex digits. */
8536 return (bitwidth + 3) / 4;
8540 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
8542 char *ptr = &buf[6];
8543 static const gchar hex_digits[16] =
8544 { '0', '1', '2', '3', '4', '5', '6', '7',
8545 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
8549 /* Properly format value */
8550 if (g_ascii_isprint(value)) {
8552 * Printable, so just show the character, and, if it needs
8553 * to be escaped, escape it.
8556 if (value == '\\' || value == '\'')
8560 * Non-printable; show it as an escape sequence.
8566 * Show a NUL with only one digit.
8600 switch (display & FIELD_DISPLAY_E_MASK) {
8603 *(--ptr) = (value & 0x7) + '0';
8605 *(--ptr) = (value & 0x7) + '0';
8607 *(--ptr) = (value & 0x7) + '0';
8611 *(--ptr) = hex_digits[value & 0x0F];
8613 *(--ptr) = hex_digits[value & 0x0F];
8618 g_assert_not_reached();
8628 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
8630 char *ptr = &buf[31];
8631 gboolean isint = IS_FT_INT(hfinfo->type);
8634 /* Properly format value */
8635 switch (display & FIELD_DISPLAY_E_MASK) {
8637 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8641 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8644 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8648 return oct_to_str_back(ptr, value);
8651 return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8655 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8658 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8665 port_with_resolution_to_str_buf(buf, 32,
8666 display_to_port_type((field_display_e)display), value);
8670 g_assert_not_reached();
8676 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
8678 char *ptr = &buf[47];
8679 gboolean isint = IS_FT_INT(hfinfo->type);
8682 /* Properly format value */
8685 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8689 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8692 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8696 return oct64_to_str_back(ptr, value);
8699 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8703 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8706 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8710 g_assert_not_reached();
8716 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8718 int display = hfinfo->display;
8720 if (hfinfo->type == FT_FRAMENUM) {
8722 * Frame numbers are always displayed in decimal.
8727 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8731 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8733 int display = hfinfo->display;
8735 if (hfinfo->type == FT_FRAMENUM) {
8737 * Frame numbers are always displayed in decimal.
8742 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8746 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8748 /* Get the underlying BASE_ value */
8749 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8751 return hfinfo_char_value_format_display(display, buf, value);
8755 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8757 /* Get the underlying BASE_ value */
8758 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8760 if (hfinfo->type == FT_FRAMENUM) {
8762 * Frame numbers are always displayed in decimal.
8767 if (IS_BASE_PORT(display)) {
8773 /* case BASE_DEC: */
8775 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
8780 /* case BASE_HEX: */
8786 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8790 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8792 /* Get the underlying BASE_ value */
8793 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8795 if (hfinfo->type == FT_FRAMENUM) {
8797 * Frame numbers are always displayed in decimal.
8804 /* case BASE_DEC: */
8806 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
8811 /* case BASE_HEX: */
8817 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8821 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8823 /* Get the underlying BASE_ value */
8824 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8826 return hfinfo_char_value_format_display(display, buf, value);
8830 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8832 /* Get the underlying BASE_ value */
8833 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8835 if (display == BASE_NONE)
8838 if (display == BASE_DEC_HEX)
8840 if (display == BASE_HEX_DEC)
8843 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8847 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8849 /* Get the underlying BASE_ value */
8850 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8852 if (display == BASE_NONE)
8855 if (display == BASE_DEC_HEX)
8857 if (display == BASE_HEX_DEC)
8860 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8864 proto_registrar_get_name(const int n)
8866 header_field_info *hfinfo;
8868 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8869 return hfinfo->name;
8873 proto_registrar_get_abbrev(const int n)
8875 header_field_info *hfinfo;
8877 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8878 return hfinfo->abbrev;
8882 proto_registrar_get_ftype(const int n)
8884 header_field_info *hfinfo;
8886 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8887 return hfinfo->type;
8891 proto_registrar_get_parent(const int n)
8893 header_field_info *hfinfo;
8895 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8896 return hfinfo->parent;
8900 proto_registrar_is_protocol(const int n)
8902 header_field_info *hfinfo;
8904 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8905 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
8908 /* Returns length of field in packet (not necessarily the length
8909 * in our internal representation, as in the case of IPv4).
8910 * 0 means undeterminable at time of registration
8911 * -1 means the field is not registered. */
8913 proto_registrar_get_length(const int n)
8915 header_field_info *hfinfo;
8917 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8918 return ftype_length(hfinfo->type);
8921 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
8922 * it exists anywhere, or FALSE if it exists nowhere. */
8924 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
8926 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
8928 if (g_ptr_array_len(ptrs) > 0) {
8936 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
8937 * This only works if the hfindex was "primed" before the dissection
8938 * took place, as we just pass back the already-created GPtrArray*.
8939 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
8942 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
8947 if (PTREE_DATA(tree)->interesting_hfids != NULL)
8948 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
8949 GINT_TO_POINTER(id));
8955 proto_tracking_interesting_fields(const proto_tree *tree)
8957 GHashTable *interesting_hfids;
8962 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
8964 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
8967 /* Helper struct for proto_find_info() and proto_all_finfos() */
8973 /* Helper function for proto_find_info() */
8975 find_finfo(proto_node *node, gpointer data)
8977 field_info *fi = PNODE_FINFO(node);
8978 if (fi && fi->hfinfo) {
8979 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8980 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8984 /* Don't stop traversing. */
8988 /* Helper function for proto_find_first_info() */
8990 find_first_finfo(proto_node *node, gpointer data)
8992 field_info *fi = PNODE_FINFO(node);
8993 if (fi && fi->hfinfo) {
8994 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8995 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8999 /* Stop traversing. */
9003 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
9004 * This works on any proto_tree, primed or unprimed, but actually searches
9005 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
9006 * The caller does need to free the returned GPtrArray with
9007 * g_ptr_array_free(<array>, TRUE).
9010 proto_find_finfo(proto_tree *tree, const int id)
9014 ffdata.array = g_ptr_array_new();
9017 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
9019 return ffdata.array;
9022 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
9023 * This works on any proto_tree, primed or unprimed, but actually searches
9024 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
9025 * The caller does need to free the returned GPtrArray with
9026 * g_ptr_array_free(<array>, TRUE).
9029 proto_find_first_finfo(proto_tree *tree, const int id)
9033 ffdata.array = g_ptr_array_new();
9036 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
9038 return ffdata.array;
9041 /* Helper function for proto_all_finfos() */
9043 every_finfo(proto_node *node, gpointer data)
9045 field_info *fi = PNODE_FINFO(node);
9046 if (fi && fi->hfinfo) {
9047 g_ptr_array_add(((ffdata_t*)data)->array, fi);
9050 /* Don't stop traversing. */
9054 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
9056 proto_all_finfos(proto_tree *tree)
9060 /* Pre allocate enough space to hold all fields in most cases */
9061 ffdata.array = g_ptr_array_sized_new(512);
9064 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
9066 return ffdata.array;
9077 check_for_offset(proto_node *node, gpointer data)
9079 field_info *fi = PNODE_FINFO(node);
9080 offset_search_t *offsearch = (offset_search_t *)data;
9082 /* !fi == the top most container node which holds nothing */
9083 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
9084 if (offsearch->offset >= (guint) fi->start &&
9085 offsearch->offset < (guint) (fi->start + fi->length)) {
9087 offsearch->finfo = fi;
9088 return FALSE; /* keep traversing */
9091 return FALSE; /* keep traversing */
9094 /* Search a proto_tree backwards (from leaves to root) looking for the field
9095 * whose start/length occupies 'offset' */
9096 /* XXX - I couldn't find an easy way to search backwards, so I search
9097 * forwards, w/o stopping. Therefore, the last finfo I find will the be
9098 * the one I want to return to the user. This algorithm is inefficient
9099 * and could be re-done, but I'd have to handle all the children and
9100 * siblings of each node myself. When I have more time I'll do that.
9103 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
9105 offset_search_t offsearch;
9107 offsearch.offset = offset;
9108 offsearch.finfo = NULL;
9109 offsearch.tvb = tvb;
9111 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
9113 return offsearch.finfo;
9118 check_for_undecoded(proto_node *node, gpointer data)
9120 field_info *fi = PNODE_FINFO(node);
9121 gchar* decoded = (gchar*)data;
9126 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
9127 for (i = fi->start; i < fi->start + fi->length; i++) {
9130 decoded[byte] |= (1 << bit);
9138 proto_find_undecoded_data(proto_tree *tree, guint length)
9140 gchar* decoded = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
9142 proto_tree_traverse_pre_order(tree, check_for_undecoded, decoded);
9146 /* Dumps the protocols in the registration database to stdout. An independent
9147 * program can take this output and format it into nice tables or HTML or
9150 * There is one record per line. The fields are tab-delimited.
9152 * Field 1 = protocol name
9153 * Field 2 = protocol short name
9154 * Field 3 = protocol filter name
9157 proto_registrar_dump_protocols(void)
9159 protocol_t *protocol;
9161 void *cookie = NULL;
9164 i = proto_get_first_protocol(&cookie);
9166 protocol = find_protocol_by_id(i);
9167 ws_debug_printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
9168 protocol->filter_name);
9169 i = proto_get_next_protocol(&cookie);
9173 /* Dumps the value_strings, extended value string headers, range_strings
9174 * or true/false strings for fields that have them.
9175 * There is one record per line. Fields are tab-delimited.
9176 * There are four types of records: Value String, Extended Value String Header,
9177 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
9178 * the type of record.
9180 * Note that a record will be generated only if the value_string,... is referenced
9181 * in a registered hfinfo entry.
9187 * Field 2 = Field abbreviation to which this value string corresponds
9188 * Field 3 = Integer value
9191 * Extended Value String Headers
9192 * -----------------------------
9194 * Field 2 = Field abbreviation to which this extended value string header corresponds
9195 * Field 3 = Extended Value String "Name"
9196 * Field 4 = Number of entries in the associated value_string array
9197 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
9202 * Field 2 = Field abbreviation to which this range string corresponds
9203 * Field 3 = Integer value: lower bound
9204 * Field 4 = Integer value: upper bound
9207 * True/False Strings
9208 * ------------------
9210 * Field 2 = Field abbreviation to which this true/false string corresponds
9211 * Field 3 = True String
9212 * Field 4 = False String
9215 proto_registrar_dump_values(void)
9217 header_field_info *hfinfo;
9219 const value_string *vals;
9220 const val64_string *vals64;
9221 const range_string *range;
9222 const true_false_string *tfs;
9223 const unit_name_string *units;
9225 len = gpa_hfinfo.len;
9226 for (i = 0; i < len ; i++) {
9227 if (gpa_hfinfo.hfi[i] == NULL)
9228 continue; /* This is a deregistered protocol or field */
9230 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
9232 if (hfinfo->id == hf_text_only) {
9236 /* ignore protocols */
9237 if (proto_registrar_is_protocol(i)) {
9240 /* process header fields */
9241 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
9243 * If this field isn't at the head of the list of
9244 * fields with this name, skip this field - all
9245 * fields with the same name are really just versions
9246 * of the same field stored in different bits, and
9247 * should have the same type/radix/value list, and
9248 * just differ in their bit masks. (If a field isn't
9249 * a bitfield, but can be, say, 1 or 2 bytes long,
9250 * it can just be made FT_UINT16, meaning the
9251 * *maximum* length is 2 bytes, and be used
9254 if (hfinfo->same_name_prev_id != -1)
9263 if (hfinfo->strings != NULL) {
9264 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) != BASE_CUSTOM &&
9265 (hfinfo->type == FT_CHAR ||
9266 hfinfo->type == FT_UINT8 ||
9267 hfinfo->type == FT_UINT16 ||
9268 hfinfo->type == FT_UINT24 ||
9269 hfinfo->type == FT_UINT32 ||
9270 hfinfo->type == FT_UINT40 ||
9271 hfinfo->type == FT_UINT48 ||
9272 hfinfo->type == FT_UINT56 ||
9273 hfinfo->type == FT_UINT64 ||
9274 hfinfo->type == FT_INT8 ||
9275 hfinfo->type == FT_INT16 ||
9276 hfinfo->type == FT_INT24 ||
9277 hfinfo->type == FT_INT32 ||
9278 hfinfo->type == FT_INT40 ||
9279 hfinfo->type == FT_INT48 ||
9280 hfinfo->type == FT_INT56 ||
9281 hfinfo->type == FT_INT64)) {
9283 if (hfinfo->display & BASE_RANGE_STRING) {
9284 range = (const range_string *)hfinfo->strings;
9285 } else if (hfinfo->display & BASE_EXT_STRING) {
9286 vals = VALUE_STRING_EXT_VS_P((value_string_ext *)hfinfo->strings);
9287 } else if (hfinfo->display & BASE_VAL64_STRING) {
9288 vals64 = (const val64_string *)hfinfo->strings;
9289 } else if (hfinfo->display & BASE_UNIT_STRING) {
9290 units = (const unit_name_string *)hfinfo->strings;
9292 vals = (const value_string *)hfinfo->strings;
9295 else if (hfinfo->type == FT_BOOLEAN) {
9296 tfs = (const struct true_false_string *)hfinfo->strings;
9300 /* Print value strings? */
9302 if (hfinfo->display & BASE_EXT_STRING) {
9303 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
9304 if (!value_string_ext_validate(vse_p)) {
9305 ws_g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
9308 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
9309 ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
9311 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
9312 VALUE_STRING_EXT_VS_NAME(vse_p),
9313 value_string_ext_match_type_str(vse_p));
9316 while (vals[vi].strptr) {
9317 /* Print in the proper base */
9318 if (hfinfo->type == FT_CHAR) {
9319 if (g_ascii_isprint(vals[vi].value)) {
9320 ws_debug_printf("V\t%s\t'%c'\t%s\n",
9325 if (hfinfo->display == BASE_HEX) {
9326 ws_debug_printf("V\t%s\t'\\x%02x'\t%s\n",
9332 ws_debug_printf("V\t%s\t'\\%03o'\t%s\n",
9339 if (hfinfo->display == BASE_HEX) {
9340 ws_debug_printf("V\t%s\t0x%x\t%s\n",
9346 ws_debug_printf("V\t%s\t%u\t%s\n",
9357 while (vals64[vi].strptr) {
9358 ws_debug_printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
9366 /* print range strings? */
9369 while (range[vi].strptr) {
9370 /* Print in the proper base */
9371 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_HEX) {
9372 ws_debug_printf("R\t%s\t0x%x\t0x%x\t%s\n",
9374 range[vi].value_min,
9375 range[vi].value_max,
9379 ws_debug_printf("R\t%s\t%u\t%u\t%s\n",
9381 range[vi].value_min,
9382 range[vi].value_max,
9389 /* Print true/false strings? */
9391 ws_debug_printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
9392 tfs->true_string, tfs->false_string);
9394 /* Print unit strings? */
9396 ws_debug_printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
9397 units->singular, units->plural ? units->plural : "(no plural)");
9402 /* Prints the number of registered fields.
9403 * Useful for determining an appropriate value for
9404 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
9406 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
9407 * the number of fields, TRUE otherwise.
9410 proto_registrar_dump_fieldcount(void)
9413 header_field_info *hfinfo;
9414 guint32 deregistered_count = 0;
9415 guint32 same_name_count = 0;
9416 guint32 protocol_count = 0;
9418 for (i = 0; i < gpa_hfinfo.len; i++) {
9419 if (gpa_hfinfo.hfi[i] == NULL) {
9420 deregistered_count++;
9421 continue; /* This is a deregistered protocol or header field */
9424 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
9426 if (proto_registrar_is_protocol(i))
9429 if (hfinfo->same_name_prev_id != -1)
9433 ws_debug_printf("There are %u header fields registered, of which:\n"
9434 "\t%u are deregistered\n"
9435 "\t%u are protocols\n"
9436 "\t%u have the same name as another field\n\n",
9437 gpa_hfinfo.len, deregistered_count, protocol_count,
9440 ws_debug_printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
9441 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
9442 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
9445 ws_debug_printf("The header field table consumes %u KiB of memory.\n",
9446 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
9447 ws_debug_printf("The fields themselves consume %u KiB of memory.\n",
9448 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
9450 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
9454 /* Dumps the contents of the registration database to stdout. An independent
9455 * program can take this output and format it into nice tables or HTML or
9458 * There is one record per line. Each record is either a protocol or a header
9459 * field, differentiated by the first field. The fields are tab-delimited.
9464 * Field 2 = descriptive protocol name
9465 * Field 3 = protocol abbreviation
9470 * Field 2 = descriptive field name
9471 * Field 3 = field abbreviation
9472 * Field 4 = type ( textual representation of the the ftenum type )
9473 * Field 5 = parent protocol abbreviation
9474 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
9475 * Field 7 = bitmask: format: hex: 0x....
9476 * Field 8 = blurb describing field
9479 proto_registrar_dump_fields(void)
9481 header_field_info *hfinfo, *parent_hfinfo;
9483 const char *enum_name;
9484 const char *base_name;
9488 len = gpa_hfinfo.len;
9489 for (i = 0; i < len ; i++) {
9490 if (gpa_hfinfo.hfi[i] == NULL)
9491 continue; /* This is a deregistered protocol or header field */
9493 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
9496 * Skip the pseudo-field for "proto_tree_add_text()" since
9497 * we don't want it in the list of filterable fields.
9499 if (hfinfo->id == hf_text_only)
9502 /* format for protocols */
9503 if (proto_registrar_is_protocol(i)) {
9504 ws_debug_printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
9506 /* format for header fields */
9509 * If this field isn't at the head of the list of
9510 * fields with this name, skip this field - all
9511 * fields with the same name are really just versions
9512 * of the same field stored in different bits, and
9513 * should have the same type/radix/value list, and
9514 * just differ in their bit masks. (If a field isn't
9515 * a bitfield, but can be, say, 1 or 2 bytes long,
9516 * it can just be made FT_UINT16, meaning the
9517 * *maximum* length is 2 bytes, and be used
9520 if (hfinfo->same_name_prev_id != -1)
9523 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
9525 enum_name = ftype_name(hfinfo->type);
9528 if (hfinfo->type == FT_CHAR ||
9529 hfinfo->type == FT_UINT8 ||
9530 hfinfo->type == FT_UINT16 ||
9531 hfinfo->type == FT_UINT24 ||
9532 hfinfo->type == FT_UINT32 ||
9533 hfinfo->type == FT_UINT40 ||
9534 hfinfo->type == FT_UINT48 ||
9535 hfinfo->type == FT_UINT56 ||
9536 hfinfo->type == FT_UINT64 ||
9537 hfinfo->type == FT_INT8 ||
9538 hfinfo->type == FT_INT16 ||
9539 hfinfo->type == FT_INT24 ||
9540 hfinfo->type == FT_INT32 ||
9541 hfinfo->type == FT_INT40 ||
9542 hfinfo->type == FT_INT48 ||
9543 hfinfo->type == FT_INT56 ||
9544 hfinfo->type == FT_INT64) {
9546 switch (FIELD_DISPLAY(hfinfo->display)) {
9558 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
9564 } else if (hfinfo->type == FT_BOOLEAN) {
9565 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
9566 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
9570 blurb = hfinfo->blurb;
9573 else if (strlen(blurb) == 0)
9576 ws_debug_printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
9577 hfinfo->name, hfinfo->abbrev, enum_name,
9578 parent_hfinfo->abbrev, base_name,
9579 hfinfo->bitmask, blurb);
9584 /* Dumps field types and descriptive names to stdout. An independent
9585 * program can take this output and format it into nice tables or HTML or
9588 * There is one record per line. The fields are tab-delimited.
9590 * Field 1 = field type name, e.g. FT_UINT8
9591 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
9594 proto_registrar_dump_ftypes(void)
9598 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
9599 ws_debug_printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
9603 /* This function indicates whether it's possible to construct a
9604 * "match selected" display filter string for the specified field,
9605 * returns an indication of whether it's possible, and, if it's
9606 * possible and "filter" is non-null, constructs the filter and
9607 * sets "*filter" to point to it.
9608 * You do not need to [g_]free() this string since it will be automatically
9609 * freed once the next packet is dissected.
9612 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
9615 header_field_info *hfinfo;
9620 gint start, length, length_remaining;
9622 gchar is_signed_num = FALSE;
9627 hfinfo = finfo->hfinfo;
9628 DISSECTOR_ASSERT(hfinfo);
9629 abbrev_len = (int) strlen(hfinfo->abbrev);
9631 if (hfinfo->strings && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
9632 const gchar *str = NULL;
9634 switch (hfinfo->type) {
9640 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
9648 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
9655 if (str != NULL && filter != NULL) {
9656 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
9662 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
9663 * functions for FT_UINT and FT_INT types, as we choose the base in
9664 * the string expression based on the display base of the field.
9666 * Note that the base does matter, as this is also used for
9667 * the protocolinfo tap.
9669 * It might be nice to use them in "proto_item_fill_label()"
9670 * as well, although, there, you'd have to deal with the base
9671 * *and* with resolved values for addresses.
9673 * Perhaps we need two different val_to_string routines, one
9674 * to generate items for display filters and one to generate
9675 * strings for display, and pass to both of them the
9676 * "display" and "strings" values in the header_field_info
9677 * structure for the field, so they can get the base and,
9678 * if the field is Boolean or an enumerated integer type,
9679 * the tables used to generate human-readable values.
9681 switch (hfinfo->type) {
9684 if (filter != NULL) {
9690 number = fvalue_get_uinteger(&finfo->value);
9692 out = hfinfo_char_value_format(hfinfo, buf, number);
9694 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9702 is_signed_num = TRUE;
9709 if (filter != NULL) {
9716 number = fvalue_get_sinteger(&finfo->value);
9718 number = fvalue_get_uinteger(&finfo->value);
9720 out = hfinfo_numeric_value_format(hfinfo, buf, number);
9722 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9730 is_signed_num = TRUE;
9736 if (filter != NULL) {
9743 number = fvalue_get_sinteger64(&finfo->value);
9745 number = fvalue_get_uinteger64(&finfo->value);
9747 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
9749 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9755 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
9760 * If the length is 0, just match the name of the
9763 * (Also check for negative values, just in case,
9764 * as we'll cast it to an unsigned value later.)
9766 length = finfo->length;
9769 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
9776 * This doesn't have a value, so we'd match
9777 * on the raw bytes at this address.
9779 * Should we be allowed to access to the raw bytes?
9780 * If "edt" is NULL, the answer is "no".
9786 * Is this field part of the raw frame tvbuff?
9787 * If not, we can't use "frame[N:M]" to match
9790 * XXX - should this be frame-relative, or
9791 * protocol-relative?
9793 * XXX - does this fallback for non-registered
9794 * fields even make sense?
9796 if (finfo->ds_tvb != edt->tvb)
9797 return FALSE; /* you lose */
9800 * Don't go past the end of that tvbuff.
9802 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
9803 if (length > length_remaining)
9804 length = length_remaining;
9808 if (filter != NULL) {
9809 start = finfo->start;
9810 buf_len = 32 + length * 3;
9811 *filter = (char *)wmem_alloc0(NULL, buf_len);
9814 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
9815 "frame[%d:%d] == ", finfo->start, length);
9816 for (i=0; i<length; i++) {
9817 c = tvb_get_guint8(finfo->ds_tvb, start);
9820 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
9823 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
9830 /* FT_PCRE never appears as a type for a registered field. It is
9831 * only used internally. */
9832 DISSECTOR_ASSERT_NOT_REACHED();
9835 /* By default, use the fvalue's "to_string_repr" method. */
9837 /* Figure out the string length needed.
9838 * The ft_repr length.
9839 * 4 bytes for " == ".
9840 * 1 byte for trailing NUL.
9842 if (filter != NULL) {
9844 dfilter_len = fvalue_string_repr_len(&finfo->value,
9845 FTREPR_DFILTER, finfo->hfinfo->display);
9846 dfilter_len += abbrev_len + 4 + 1;
9847 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
9849 /* Create the string */
9850 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
9851 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
9852 wmem_free(NULL, str);
9861 * Returns TRUE if we can do a "match selected" on the field, FALSE
9865 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
9867 return construct_match_selected_string(finfo, edt, NULL);
9870 /* This function attempts to construct a "match selected" display filter
9871 * string for the specified field; if it can do so, it returns a pointer
9872 * to the string, otherwise it returns NULL.
9874 * The string is allocated with packet lifetime scope.
9875 * You do not need to [g_]free() this string since it will be automatically
9876 * freed once the next packet is dissected.
9879 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
9881 char *filter = NULL;
9883 if (!construct_match_selected_string(finfo, edt, &filter))
9885 wmem_free(NULL, filter);
9891 /* This function is common code for all proto_tree_add_bitmask... functions.
9895 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
9896 const int len, const gint ett, const int **fields,
9897 const int flags, gboolean first,
9898 gboolean use_parent_tree,
9899 proto_tree* tree, guint64 value)
9902 guint64 available_bits = 0;
9904 header_field_info *hf;
9908 if (len < 0 || len > 8)
9909 g_assert_not_reached();
9910 bitshift = (8 - (guint)len)*8;
9911 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
9913 if (use_parent_tree == FALSE)
9914 tree = proto_item_add_subtree(item, ett);
9917 guint64 present_bits;
9918 PROTO_REGISTRAR_GET_NTH(**fields,hf);
9919 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
9921 /* Skip fields that aren't fully present */
9922 present_bits = available_bits & hf->bitmask;
9923 if (present_bits != hf->bitmask) {
9934 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
9941 proto_tree_add_int(tree, **fields, tvb, offset, len, (gint32)value);
9948 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
9955 proto_tree_add_int64(tree, **fields, tvb, offset, len, (gint64)value);
9959 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
9963 DISSECTOR_ASSERT_NOT_REACHED();
9966 if (flags & BMT_NO_APPEND) {
9970 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
9974 if (hf->display == BASE_CUSTOM) {
9975 gchar lbl[ITEM_LABEL_LENGTH];
9976 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9978 DISSECTOR_ASSERT(fmtfunc);
9979 fmtfunc(lbl, (guint32) tmpval);
9980 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9984 else if (hf->strings) {
9985 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9986 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
9989 else if (!(flags & BMT_NO_INT)) {
9994 proto_item_append_text(item, ", ");
9997 out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
9998 proto_item_append_text(item, "%s: %s", hf->name, out);
10008 if (hf->display == BASE_CUSTOM) {
10009 gchar lbl[ITEM_LABEL_LENGTH];
10010 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
10012 DISSECTOR_ASSERT(fmtfunc);
10013 fmtfunc(lbl, (guint32) tmpval);
10014 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10018 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
10019 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10020 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
10023 else if (!(flags & BMT_NO_INT)) {
10028 proto_item_append_text(item, ", ");
10031 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
10032 if (hf->display & BASE_UNIT_STRING) {
10033 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (unit_name_string*)hf->strings));
10035 proto_item_append_text(item, "%s: %s", hf->name, out);
10046 integer32 = (guint32) tmpval;
10048 no_of_bits = ws_count_ones(hf->bitmask);
10049 integer32 = ws_sign_ext32(integer32, no_of_bits);
10051 if (hf->display == BASE_CUSTOM) {
10052 gchar lbl[ITEM_LABEL_LENGTH];
10053 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
10055 DISSECTOR_ASSERT(fmtfunc);
10056 fmtfunc(lbl, (gint32) integer32);
10057 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10061 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
10062 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10063 hf->name, hf_try_val_to_str_const((gint32) integer32, hf, "Unknown"));
10066 else if (!(flags & BMT_NO_INT)) {
10071 proto_item_append_text(item, ", ");
10074 out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
10075 if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
10076 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (unit_name_string*)hf->strings));
10078 proto_item_append_text(item, "%s: %s", hf->name, out);
10089 if (hf->display == BASE_CUSTOM) {
10090 gchar lbl[ITEM_LABEL_LENGTH];
10091 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
10093 DISSECTOR_ASSERT(fmtfunc);
10094 fmtfunc(lbl, tmpval);
10095 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10099 else if (hf->strings) {
10100 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10101 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
10104 else if (!(flags & BMT_NO_INT)) {
10109 proto_item_append_text(item, ", ");
10112 out = hfinfo_number_value_format64(hf, buf, tmpval);
10113 proto_item_append_text(item, "%s: %s", hf->name, out);
10124 no_of_bits = ws_count_ones(hf->bitmask);
10125 tmpval = ws_sign_ext64(tmpval, no_of_bits);
10127 if (hf->display == BASE_CUSTOM) {
10128 gchar lbl[ITEM_LABEL_LENGTH];
10129 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
10131 DISSECTOR_ASSERT(fmtfunc);
10132 fmtfunc(lbl, (gint64) tmpval);
10133 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10137 else if (hf->strings) {
10138 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10139 hf->name, hf_try_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
10142 else if (!(flags & BMT_NO_INT)) {
10147 proto_item_append_text(item, ", ");
10150 out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
10151 proto_item_append_text(item, "%s: %s", hf->name, out);
10158 if (hf->strings && !(flags & BMT_NO_TFS)) {
10159 /* If we have true/false strings, emit full - otherwise messages
10160 might look weird */
10161 const struct true_false_string *tfs =
10162 (const struct true_false_string *)hf->strings;
10165 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10166 hf->name, tfs->true_string);
10168 } else if (!(flags & BMT_NO_FALSE)) {
10169 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10170 hf->name, tfs->false_string);
10173 } else if (hf->bitmask & value) {
10174 /* If the flag is set, show the name */
10175 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
10180 DISSECTOR_ASSERT_NOT_REACHED();
10190 /* This function will dissect a sequence of bytes that describe a
10191 * bitmask and supply the value of that sequence through a pointer.
10192 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
10194 * This field will form an expansion under which the individual fields of the
10195 * bitmask is dissected and displayed.
10196 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
10198 * fields is an array of pointers to int that lists all the fields of the
10199 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
10200 * or another integer of the same type/size as hf_hdr with a mask specified.
10201 * This array is terminated by a NULL entry.
10203 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
10204 * FT_integer fields that have a value_string attached will have the
10205 * matched string displayed on the expansion line.
10208 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
10209 const guint offset, const int hf_hdr,
10210 const gint ett, const int **fields,
10211 const guint encoding, guint64 *retval)
10213 return proto_tree_add_bitmask_with_flags_ret_uint64(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, retval);
10216 /* This function will dissect a sequence of bytes that describe a
10218 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
10220 * This field will form an expansion under which the individual fields of the
10221 * bitmask is dissected and displayed.
10222 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
10224 * fields is an array of pointers to int that lists all the fields of the
10225 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
10226 * or another integer of the same type/size as hf_hdr with a mask specified.
10227 * This array is terminated by a NULL entry.
10229 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
10230 * FT_integer fields that have a value_string attached will have the
10231 * matched string displayed on the expansion line.
10234 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
10235 const guint offset, const int hf_hdr,
10236 const gint ett, const int **fields,
10237 const guint encoding)
10239 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
10242 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
10243 * what data is appended to the header.
10246 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
10247 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
10250 proto_item *item = NULL;
10251 header_field_info *hf;
10255 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
10256 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
10257 len = ftype_length(hf->type);
10258 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
10261 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
10262 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
10263 flags, FALSE, FALSE, NULL, value);
10268 /* Mask out irrelevant portions */
10269 *retval &= hf->bitmask;
10271 *retval >>= hfinfo_bitshift(hf);
10277 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
10278 * what data is appended to the header.
10281 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
10282 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
10284 proto_item *item = NULL;
10285 header_field_info *hf;
10289 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
10290 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
10293 len = ftype_length(hf->type);
10294 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
10295 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
10296 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
10297 flags, FALSE, FALSE, NULL, value);
10303 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
10304 can't be retrieved directly from tvb) */
10306 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
10307 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
10309 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
10310 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
10313 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
10314 WS_DLL_PUBLIC proto_item *
10315 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
10316 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
10318 proto_item *item = NULL;
10319 header_field_info *hf;
10322 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
10323 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
10324 /* the proto_tree_add_uint/_uint64() calls below
10325 will fail if tvb==NULL and len!=0 */
10326 len = tvb ? ftype_length(hf->type) : 0;
10330 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
10332 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
10334 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
10335 flags, FALSE, FALSE, NULL, value);
10341 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
10343 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
10344 const int len, const int **fields, const guint encoding)
10349 value = get_uint64_value(tree, tvb, offset, len, encoding);
10350 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
10351 BMT_NO_APPEND, FALSE, TRUE, tree, value);
10356 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
10357 const int len, const int **fields, const guint64 value)
10360 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
10361 BMT_NO_APPEND, FALSE, TRUE, tree, value);
10366 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
10367 * This is intended to support bitmask fields whose lengths can vary, perhaps
10368 * as the underlying standard evolves over time.
10369 * With this API there is the possibility of being called to display more or
10370 * less data than the dissector was coded to support.
10371 * In such cases, it is assumed that bitmasks are extended on the MSb end.
10372 * Thus when presented with "too much" or "too little" data, MSbits will be
10373 * ignored or MSfields sacrificed.
10375 * Only fields for which all defined bits are available are displayed.
10378 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
10379 const guint offset, const guint len, const int hf_hdr,
10380 const gint ett, const int **fields, struct expert_field* exp,
10381 const guint encoding)
10383 proto_item *item = NULL;
10384 header_field_info *hf;
10385 guint decodable_len;
10386 guint decodable_offset;
10387 guint32 decodable_value;
10390 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
10391 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
10393 decodable_offset = offset;
10394 decodable_len = MIN(len, (guint) ftype_length(hf->type));
10396 /* If we are ftype_length-limited,
10397 * make sure we decode as many LSBs as possible.
10399 if (encoding == ENC_BIG_ENDIAN) {
10400 decodable_offset += (len - decodable_len);
10404 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
10405 decodable_len, encoding);
10407 /* The root item covers all the bytes even if we can't decode them all */
10408 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
10412 if (decodable_len < len) {
10413 /* Dissector likely requires updating for new protocol revision */
10414 expert_add_info_format(NULL, item, exp,
10415 "Only least-significant %d of %d bytes decoded",
10416 decodable_len, len);
10420 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
10421 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
10422 ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
10428 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
10430 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
10431 const guint offset, const guint len,
10432 const char *name, const char *fallback,
10433 const gint ett, const int **fields,
10434 const guint encoding, const int flags)
10436 proto_item *item = NULL;
10440 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
10441 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
10442 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
10443 flags, TRUE, FALSE, NULL, value) && fallback) {
10444 /* Still at first item - append 'fallback' text if any */
10445 proto_item_append_text(item, "%s", fallback);
10453 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10454 const guint bit_offset, const gint no_of_bits,
10455 const guint encoding)
10457 header_field_info *hfinfo;
10461 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
10463 octet_length = (no_of_bits + 7) >> 3;
10464 octet_offset = bit_offset >> 3;
10465 test_length(hfinfo, tvb, octet_offset, octet_length);
10467 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
10468 * but only after doing a bunch more work (which we can, in the common
10469 * case, shortcut here).
10471 CHECK_FOR_NULL_TREE(tree);
10472 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10474 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
10478 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
10479 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
10480 * Offset should be given in bits from the start of the tvb.
10483 static proto_item *
10484 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10485 const guint bit_offset, const gint no_of_bits,
10486 guint64 *return_value, const guint encoding)
10490 guint8 tot_no_bits;
10492 char lbl_str[ITEM_LABEL_LENGTH];
10496 header_field_info *hf_field;
10498 const true_false_string *tfstring;
10500 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
10501 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
10503 if (hf_field->bitmask != 0) {
10504 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10505 "Incompatible use of proto_tree_add_bits_ret_val"
10506 " with field '%s' (%s) with bitmask != 0",
10507 hf_field->abbrev, hf_field->name));
10510 DISSECTOR_ASSERT(no_of_bits > 0);
10512 /* Byte align offset */
10513 offset = bit_offset>>3;
10516 * Calculate the number of octets used to hold the bits
10518 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
10519 length = (tot_no_bits + 7) >> 3;
10521 if (no_of_bits < 65) {
10522 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
10524 DISSECTOR_ASSERT_NOT_REACHED();
10528 /* Sign extend for signed types */
10529 switch (hf_field->type) {
10538 value = ws_sign_ext64(value, no_of_bits);
10545 if (return_value) {
10546 *return_value = value;
10549 /* Coast clear. Try and fake it */
10550 CHECK_FOR_NULL_TREE(tree);
10551 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10553 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
10555 switch (hf_field->type) {
10557 /* Boolean field */
10558 tfstring = (const true_false_string *) &tfs_true_false;
10559 if (hf_field->strings)
10560 tfstring = (const true_false_string *)hf_field->strings;
10561 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
10563 bf_str, hf_field->name,
10564 (guint64)value ? tfstring->true_string : tfstring->false_string);
10568 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
10569 fill_label_char(PITEM_FINFO(pi), lbl_str);
10576 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
10577 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
10584 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
10585 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
10592 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
10593 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
10600 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
10601 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
10605 DISSECTOR_ASSERT_NOT_REACHED();
10610 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
10615 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10616 const guint bit_offset, const crumb_spec_t *crumb_spec,
10617 guint64 *return_value)
10622 guint mask_initial_bit_offset;
10623 guint mask_greatest_bit_offset;
10624 guint octet_length;
10627 char lbl_str[ITEM_LABEL_LENGTH];
10629 guint64 composite_bitmask;
10630 guint64 composite_bitmap;
10632 header_field_info *hf_field;
10633 const true_false_string *tfstring;
10635 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
10636 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
10638 if (hf_field->bitmask != 0) {
10639 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10640 "Incompatible use of proto_tree_add_split_bits_item_ret_val"
10641 " with field '%s' (%s) with bitmask != 0",
10642 hf_field->abbrev, hf_field->name));
10645 mask_initial_bit_offset = bit_offset % 8;
10650 mask_greatest_bit_offset = 0;
10651 composite_bitmask = 0;
10652 composite_bitmap = 0;
10654 while (crumb_spec[i].crumb_bit_length != 0) {
10655 guint64 crumb_mask, crumb_value;
10656 guint8 crumb_end_bit_offset;
10658 DISSECTOR_ASSERT(i < 64);
10659 crumb_value = tvb_get_bits64(tvb,
10660 bit_offset + crumb_spec[i].crumb_bit_offset,
10661 crumb_spec[i].crumb_bit_length,
10663 value += crumb_value;
10664 no_of_bits += crumb_spec[i].crumb_bit_length;
10666 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
10667 octet containing the initial offset.
10668 If the mask is beyond 32 bits, then give up on bit map display.
10669 This could be improved in future, probably showing a table
10670 of 32 or 64 bits per row */
10671 if (mask_greatest_bit_offset < 32) {
10672 crumb_end_bit_offset = mask_initial_bit_offset
10673 + crumb_spec[i].crumb_bit_offset
10674 + crumb_spec[i].crumb_bit_length;
10675 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
10677 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
10678 mask_greatest_bit_offset = crumb_end_bit_offset;
10680 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
10681 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
10683 /* Shift left for the next segment */
10684 value <<= crumb_spec[++i].crumb_bit_length;
10687 /* Sign extend for signed types */
10688 switch (hf_field->type) {
10697 value = ws_sign_ext64(value, no_of_bits);
10703 if (return_value) {
10704 *return_value = value;
10707 /* Coast clear. Try and fake it */
10708 CHECK_FOR_NULL_TREE(tree);
10709 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10711 /* initialise the format string */
10714 octet_offset = bit_offset >> 3;
10716 /* Round up mask length to nearest octet */
10717 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
10718 mask_greatest_bit_offset = octet_length << 3;
10720 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
10721 It would be a useful enhancement to eliminate this restriction. */
10722 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
10723 other_decode_bitfield_value(bf_str,
10724 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
10725 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
10726 mask_greatest_bit_offset);
10729 switch (hf_field->type) {
10730 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
10731 /* Boolean field */
10732 tfstring = (const true_false_string *) &tfs_true_false;
10733 if (hf_field->strings)
10734 tfstring = (const true_false_string *) hf_field->strings;
10735 return proto_tree_add_boolean_format(tree, hfindex,
10736 tvb, octet_offset, octet_length, (guint32)value,
10738 bf_str, hf_field->name,
10739 (guint64)value ? tfstring->true_string : tfstring->false_string);
10743 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
10744 fill_label_char(PITEM_FINFO(pi), lbl_str);
10751 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
10752 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
10759 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
10760 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
10767 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
10768 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
10775 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
10776 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
10780 DISSECTOR_ASSERT_NOT_REACHED();
10784 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
10789 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
10790 const crumb_spec_t *crumb_spec, guint16 crumb_index)
10792 header_field_info *hfinfo;
10794 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
10795 proto_tree_add_text_internal(tree, tvb,
10797 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
10798 "%s crumb %d of %s (decoded above)",
10799 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
10802 crumb_spec[crumb_index].crumb_bit_length,
10809 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10810 const guint bit_offset, const gint no_of_bits,
10811 guint64 *return_value, const guint encoding)
10815 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
10816 bit_offset, no_of_bits,
10817 return_value, encoding))) {
10818 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
10819 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
10824 static proto_item *
10825 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
10826 tvbuff_t *tvb, const guint bit_offset,
10827 const gint no_of_bits, void *value_ptr,
10832 guint8 tot_no_bits;
10835 header_field_info *hf_field;
10837 /* We do not have to return a value, try to fake it as soon as possible */
10838 CHECK_FOR_NULL_TREE(tree);
10839 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10841 if (hf_field->bitmask != 0) {
10842 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10843 "Incompatible use of proto_tree_add_bits_format_value"
10844 " with field '%s' (%s) with bitmask != 0",
10845 hf_field->abbrev, hf_field->name));
10848 DISSECTOR_ASSERT(no_of_bits > 0);
10850 /* Byte align offset */
10851 offset = bit_offset>>3;
10854 * Calculate the number of octets used to hold the bits
10856 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
10857 length = tot_no_bits>>3;
10858 /* If we are using part of the next octet, increase length by 1 */
10859 if (tot_no_bits & 0x07)
10862 if (no_of_bits < 65) {
10863 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
10865 DISSECTOR_ASSERT_NOT_REACHED();
10869 str = decode_bits_in_field(bit_offset, no_of_bits, value);
10871 g_strlcat(str, " = ", 256+64);
10872 g_strlcat(str, hf_field->name, 256+64);
10875 * This function does not receive an actual value but a dimensionless pointer to that value.
10876 * For this reason, the type of the header field is examined in order to determine
10877 * what kind of value we should read from this address.
10878 * The caller of this function must make sure that for the specific header field type the address of
10879 * a compatible value is provided.
10881 switch (hf_field->type) {
10883 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
10884 "%s: %s", str, value_str);
10892 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
10893 "%s: %s", str, value_str);
10900 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
10901 "%s: %s", str, value_str);
10908 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
10909 "%s: %s", str, value_str);
10916 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
10917 "%s: %s", str, value_str);
10921 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
10922 "%s: %s", str, value_str);
10926 DISSECTOR_ASSERT_NOT_REACHED();
10932 static proto_item *
10933 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
10934 tvbuff_t *tvb, const guint bit_offset,
10935 const gint no_of_bits, void *value_ptr,
10940 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
10941 tvb, bit_offset, no_of_bits,
10942 value_ptr, value_str))) {
10943 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
10944 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
10949 #define CREATE_VALUE_STRING(dst,format,ap) \
10950 va_start(ap, format); \
10951 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
10955 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
10956 tvbuff_t *tvb, const guint bit_offset,
10957 const gint no_of_bits, guint32 value,
10958 const char *format, ...)
10962 header_field_info *hf_field;
10964 CHECK_FOR_NULL_TREE(tree);
10966 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10968 switch (hf_field->type) {
10976 DISSECTOR_ASSERT_NOT_REACHED();
10981 CREATE_VALUE_STRING(dst, format, ap);
10983 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10987 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
10988 tvbuff_t *tvb, const guint bit_offset,
10989 const gint no_of_bits, guint64 value,
10990 const char *format, ...)
10994 header_field_info *hf_field;
10996 CHECK_FOR_NULL_TREE(tree);
10998 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11000 switch (hf_field->type) {
11008 DISSECTOR_ASSERT_NOT_REACHED();
11013 CREATE_VALUE_STRING(dst, format, ap);
11015 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11019 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
11020 tvbuff_t *tvb, const guint bit_offset,
11021 const gint no_of_bits, float value,
11022 const char *format, ...)
11026 header_field_info *hf_field;
11028 CHECK_FOR_NULL_TREE(tree);
11030 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11032 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
11034 CREATE_VALUE_STRING(dst, format, ap);
11036 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11040 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
11041 tvbuff_t *tvb, const guint bit_offset,
11042 const gint no_of_bits, gint32 value,
11043 const char *format, ...)
11047 header_field_info *hf_field;
11049 CHECK_FOR_NULL_TREE(tree);
11051 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11053 switch (hf_field->type) {
11061 DISSECTOR_ASSERT_NOT_REACHED();
11066 CREATE_VALUE_STRING(dst, format, ap);
11068 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11072 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
11073 tvbuff_t *tvb, const guint bit_offset,
11074 const gint no_of_bits, gint64 value,
11075 const char *format, ...)
11079 header_field_info *hf_field;
11081 CHECK_FOR_NULL_TREE(tree);
11083 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11085 switch (hf_field->type) {
11093 DISSECTOR_ASSERT_NOT_REACHED();
11098 CREATE_VALUE_STRING(dst, format, ap);
11100 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11104 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
11105 tvbuff_t *tvb, const guint bit_offset,
11106 const gint no_of_bits, guint32 value,
11107 const char *format, ...)
11111 header_field_info *hf_field;
11113 CHECK_FOR_NULL_TREE(tree);
11115 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11117 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
11119 CREATE_VALUE_STRING(dst, format, ap);
11121 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11125 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
11126 tvbuff_t *tvb, const guint bit_offset,
11127 const gint no_of_bits, guint64 value,
11128 const char *format, ...)
11132 header_field_info *hf_field;
11134 CHECK_FOR_NULL_TREE(tree);
11136 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11138 DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
11140 CREATE_VALUE_STRING(dst, format, ap);
11142 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11146 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11147 const guint bit_offset, const gint no_of_chars)
11150 header_field_info *hfinfo;
11155 CHECK_FOR_NULL_TREE(tree);
11157 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
11159 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
11161 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
11162 byte_offset = bit_offset >> 3;
11164 string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
11166 if (hfinfo->display == STR_UNICODE) {
11167 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
11170 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
11171 DISSECTOR_ASSERT(byte_length >= 0);
11172 proto_tree_set_string(PNODE_FINFO(pi), string);
11178 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11179 const guint bit_offset, const gint no_of_chars)
11182 header_field_info *hfinfo;
11187 CHECK_FOR_NULL_TREE(tree);
11189 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
11191 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
11193 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
11194 byte_offset = bit_offset >> 3;
11196 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
11198 if (hfinfo->display == STR_UNICODE) {
11199 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
11202 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
11203 DISSECTOR_ASSERT(byte_length >= 0);
11204 proto_tree_set_string(PNODE_FINFO(pi), string);
11209 const value_string proto_checksum_vals[] = {
11210 { PROTO_CHECKSUM_E_BAD, "Bad" },
11211 { PROTO_CHECKSUM_E_GOOD, "Good" },
11212 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
11213 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
11219 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
11220 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
11221 packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
11223 header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
11226 proto_item* ti = NULL;
11228 gboolean incorrect_checksum = TRUE;
11230 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
11232 if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
11233 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, 0, 0, "[missing]");
11234 PROTO_ITEM_SET_GENERATED(ti);
11235 if (hf_checksum_status != -1) {
11236 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_NOT_PRESENT);
11237 PROTO_ITEM_SET_GENERATED(ti2);
11242 switch (hfinfo->type){
11256 DISSECTOR_ASSERT_NOT_REACHED();
11259 if (flags & PROTO_CHECKSUM_GENERATED) {
11260 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, 0, computed_checksum);
11261 PROTO_ITEM_SET_GENERATED(ti);
11263 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
11264 if (flags & PROTO_CHECKSUM_VERIFY) {
11265 if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
11266 if (computed_checksum == 0) {
11267 proto_item_append_text(ti, " [correct]");
11268 if (hf_checksum_status != -1) {
11269 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
11270 PROTO_ITEM_SET_GENERATED(ti2);
11272 incorrect_checksum = FALSE;
11273 } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
11274 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
11277 if (checksum == computed_checksum) {
11278 proto_item_append_text(ti, " [correct]");
11279 if (hf_checksum_status != -1) {
11280 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
11281 PROTO_ITEM_SET_GENERATED(ti2);
11283 incorrect_checksum = FALSE;
11287 if (incorrect_checksum) {
11288 if (hf_checksum_status != -1) {
11289 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
11290 PROTO_ITEM_SET_GENERATED(ti2);
11292 if (flags & PROTO_CHECKSUM_ZERO) {
11293 proto_item_append_text(ti, " [incorrect]");
11294 if (bad_checksum_expert != NULL)
11295 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum");
11297 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
11298 if (bad_checksum_expert != NULL)
11299 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum [should be 0x%0*x]", len*2, computed_checksum);
11303 if (hf_checksum_status != -1) {
11304 proto_item_append_text(ti, " [unverified]");
11305 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
11306 PROTO_ITEM_SET_GENERATED(ti2);
11315 proto_check_field_name(const gchar *field_name)
11317 return wrs_check_charset(fld_abbrev_chars, field_name);
11321 tree_expanded(int tree_type)
11323 g_assert(tree_type >= 0 && tree_type < num_tree_types);
11324 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
11328 tree_expanded_set(int tree_type, gboolean value)
11330 g_assert(tree_type >= 0 && tree_type < num_tree_types);
11333 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
11335 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
11339 * Editor modelines - http://www.wireshark.org/tools/modelines.html
11342 * c-basic-offset: 8
11344 * indent-tabs-mode: t
11347 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
11348 * :indentSize=8:tabSize=8:noTabs=false: