2 * Routines for protocol tree
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include <wsutil/bits_ctz.h>
32 #include <wsutil/bits_count_ones.h>
33 #include <wsutil/sign_ext.h>
35 #include <ftypes/ftypes-int.h>
38 #include "exceptions.h"
39 #include "ptvcursor.h"
41 #include "addr_resolv.h"
42 #include "address_types.h"
45 #include "epan_dissect.h"
47 #include "wmem/wmem.h"
49 #include "asm_utils.h"
50 #include "column-utils.h"
51 #include "to_str-int.h"
53 #include "osi-utils.h"
55 #include "show_exception.h"
57 #include <wsutil/plugins.h>
59 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
60 #define SUBTREE_MAX_LEVELS 256
61 /* Throw an exception if we exceed this many tree items. */
62 /* XXX - This should probably be a preference */
63 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
65 typedef struct __subtree_lvl {
72 subtree_lvl *pushed_tree;
73 guint8 pushed_tree_index;
74 guint8 pushed_tree_max;
80 #define cVALS(x) (const value_string*)(x)
82 /** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block) \
92 /** See inlined comments.
93 @param tree the tree to append this item to
94 @param free_block a code block to call to free resources if this returns
95 @return NULL if 'tree' is null */
96 #define CHECK_FOR_NULL_TREE(tree) \
97 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
99 /** See inlined comments.
100 @param tree the tree to append this item to
101 @param hfindex field index
102 @param hfinfo header_field
103 @param free_block a code block to call to free resources if this returns
104 @return the header field matching 'hfinfo' */
105 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
106 /* If this item is not referenced we don't have to do much work \
107 at all but we should still return a node so that field items \
108 below this node (think proto_item_add_subtree()) will still \
109 have somewhere to attach to or else filtering will not work \
110 (they would be ignored since tree would be NULL). \
111 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
112 since dissectors that want to do proto_item_set_len() or \
113 other operations that dereference this would crash. \
114 We fake FT_PROTOCOL unless some clients have requested us \
117 PTREE_DATA(tree)->count++; \
118 if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
120 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
121 g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
122 /* Let the exception handler add items to the tree */ \
123 PTREE_DATA(tree)->count = 0; \
124 THROW_MESSAGE(DissectorError, \
125 wmem_strdup_printf(wmem_packet_scope(), "More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
127 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
128 if (!(PTREE_DATA(tree)->visible)) { \
129 if (PTREE_FINFO(tree)) { \
130 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
131 && (hfinfo->type != FT_PROTOCOL || \
132 PTREE_DATA(tree)->fake_protocols)) { \
134 /* just return tree back to the caller */\
140 /** See inlined comments.
141 @param tree the tree to append this item to
142 @param hfindex field index
143 @param hfinfo header_field
144 @return the header field matching 'hfinfo' */
145 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
146 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
149 /** See inlined comments.
150 @param pi the created protocol item we're about to return */
151 #define TRY_TO_FAKE_THIS_REPR(pi) \
153 if (!(PTREE_DATA(pi)->visible)) { \
154 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
155 * items string representation */ \
158 /* Same as above but returning void */
159 #define TRY_TO_FAKE_THIS_REPR_VOID(pi) \
162 if (!(PTREE_DATA(pi)->visible)) { \
163 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
164 * items string representation */ \
168 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
169 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
170 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
172 static void label_mark_truncated(char *label_str, gsize name_pos);
173 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
175 static void fill_label_boolean(field_info *fi, gchar *label_str);
176 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
177 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
178 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
179 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
181 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
182 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
183 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
184 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
185 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
186 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
187 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
188 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
191 proto_tree_add_node(proto_tree *tree, field_info *fi);
194 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
198 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
199 gint length, guint item_length, const gint encoding);
202 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
203 const gint start, const gint item_length);
206 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
207 gint start, gint *length);
210 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
212 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
215 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb);
217 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
219 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
221 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
223 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
225 proto_tree_set_string(field_info *fi, const char* value);
227 proto_tree_set_ax25(field_info *fi, const guint8* value);
229 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
231 proto_tree_set_vines(field_info *fi, const guint8* value);
233 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
235 proto_tree_set_ether(field_info *fi, const guint8* value);
237 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
239 proto_tree_set_ipxnet(field_info *fi, guint32 value);
241 proto_tree_set_ipv4(field_info *fi, guint32 value);
243 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
245 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
247 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
249 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
251 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
253 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
255 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
257 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
259 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
261 proto_tree_set_boolean(field_info *fi, guint64 value);
263 proto_tree_set_float(field_info *fi, float value);
265 proto_tree_set_double(field_info *fi, double value);
267 proto_tree_set_uint(field_info *fi, guint32 value);
269 proto_tree_set_int(field_info *fi, gint32 value);
271 proto_tree_set_uint64(field_info *fi, guint64 value);
273 proto_tree_set_int64(field_info *fi, gint64 value);
275 proto_tree_set_eui64(field_info *fi, const guint64 value);
277 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
279 /* Handle type length mismatch (now filterable) expert info */
280 static int proto_type_length_mismatch = -1;
281 static expert_field ei_type_length_mismatch_error = EI_INIT;
282 static expert_field ei_type_length_mismatch_warn = EI_INIT;
283 static void register_type_length_mismatch(void);
285 /* Handle number string decoding errors with expert info */
286 static int proto_number_string_decoding_error = -1;
287 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
288 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
289 static void register_number_string_decoding_error(void);
291 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
293 /* special-case header field used within proto.c */
294 static header_field_info hfi_text_only =
295 { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
296 int hf_text_only = -1;
298 /* Structure for information about a protocol */
300 const char *name; /* long description */
301 const char *short_name; /* short description */
302 const char *filter_name; /* name of this protocol in filters */
303 GPtrArray *fields; /* fields for this protocol */
304 int proto_id; /* field ID for this protocol */
305 gboolean is_enabled; /* TRUE if protocol is enabled */
306 gboolean can_toggle; /* TRUE if is_enabled can be changed */
307 GList *heur_list; /* Heuristic dissectors associated with this protocol */
310 /* List of all protocols */
311 static GList *protocols = NULL;
313 /* Deregistered fields */
314 static GPtrArray *deregistered_fields = NULL;
315 static GPtrArray *deregistered_data = NULL;
317 /* Contains information about a field when a dissector calls
318 * proto_tree_add_item. */
319 #define FIELD_INFO_NEW(pool, fi) fi = wmem_new(pool, field_info)
320 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
322 /* Contains the space for proto_nodes. */
323 #define PROTO_NODE_INIT(node) \
324 node->first_child = NULL; \
325 node->last_child = NULL; \
328 #define PROTO_NODE_FREE(pool, node) \
329 wmem_free(pool, node)
331 /* String space for protocol and field items for the GUI */
332 #define ITEM_LABEL_NEW(pool, il) \
333 il = wmem_new(pool, item_label_t);
334 #define ITEM_LABEL_FREE(pool, il) \
337 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
338 if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
339 g_error("Unregistered hf! index=%d", hfindex); \
340 DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
341 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
342 hfinfo = gpa_hfinfo.hfi[hfindex];
344 /* List which stores protocols and fields that have been registered */
345 typedef struct _gpa_hfinfo_t {
347 guint32 allocated_len;
348 header_field_info **hfi;
351 static gpa_hfinfo_t gpa_hfinfo;
353 /* Hash table of abbreviations and IDs */
354 static GHashTable *gpa_name_map = NULL;
355 static header_field_info *same_name_hfinfo;
357 * We're called repeatedly with the same field name when sorting a column.
358 * Cache our last gpa_name_map hit for faster lookups.
360 static char *last_field_name = NULL;
361 static header_field_info *last_hfinfo;
363 static void save_same_name_hfinfo(gpointer data)
365 same_name_hfinfo = (header_field_info*)data;
368 /* Points to the first element of an array of bits, indexed by
369 a subtree item type; that array element is TRUE if subtrees of
370 an item of that type are to be expanded. */
371 static guint32 *tree_is_expanded;
373 /* Number of elements in that array. */
376 /* Name hashtables for fast detection of duplicate names */
377 static GHashTable* proto_names = NULL;
378 static GHashTable* proto_short_names = NULL;
379 static GHashTable* proto_filter_names = NULL;
382 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
384 const protocol_t *p1 = (const protocol_t *)p1_arg;
385 const protocol_t *p2 = (const protocol_t *)p2_arg;
387 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
392 * List of dissector plugins.
395 void (*register_protoinfo)(void); /* routine to call to register protocol information */
396 void (*reg_handoff)(void); /* routine to call to register dissector handoff */
399 static GSList *dissector_plugins = NULL;
402 * Callback for each plugin found.
405 check_for_dissector_plugin(GModule *handle)
408 void (*register_protoinfo)(void);
409 void (*reg_handoff)(void);
410 dissector_plugin *plugin;
413 * Do we have a register routine?
415 if (g_module_symbol(handle, "plugin_register", &gp)) {
417 register_protoinfo = (void (*)(void))gp;
421 register_protoinfo = NULL;
425 * Do we have a reg_handoff routine?
427 if (g_module_symbol(handle, "plugin_reg_handoff", &gp)) {
429 reg_handoff = (void (*)(void))gp;
437 * If we have neither, we're not a dissector plugin.
439 if (register_protoinfo == NULL && reg_handoff == NULL)
443 * Add this one to the list of dissector plugins.
445 plugin = (dissector_plugin *)g_malloc(sizeof (dissector_plugin));
446 plugin->register_protoinfo = register_protoinfo;
447 plugin->reg_handoff = reg_handoff;
448 dissector_plugins = g_slist_append(dissector_plugins, plugin);
453 register_dissector_plugin(gpointer data, gpointer user_data _U_)
455 dissector_plugin *plugin = (dissector_plugin *)data;
457 if (plugin->register_protoinfo)
458 (plugin->register_protoinfo)();
462 reg_handoff_dissector_plugin(gpointer data, gpointer user_data _U_)
464 dissector_plugin *plugin = (dissector_plugin *)data;
466 if (plugin->reg_handoff)
467 (plugin->reg_handoff)();
471 * Register dissector plugin type.
474 register_dissector_plugin_type(void)
476 add_plugin_type("dissector", check_for_dissector_plugin);
478 #endif /* HAVE_PLUGINS */
480 /* initialize data structures and register protocols and fields */
482 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
483 void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
485 gpointer client_data)
489 proto_names = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
490 proto_short_names = g_hash_table_new(wrs_str_hash, g_str_equal);
491 proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
494 gpa_hfinfo.allocated_len = 0;
495 gpa_hfinfo.hfi = NULL;
496 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
497 deregistered_fields = g_ptr_array_new();
498 deregistered_data = g_ptr_array_new();
500 /* Initialize the ftype subsystem */
503 /* Initialize the addres type subsystem */
504 address_types_initialize();
506 /* Register one special-case FT_TEXT_ONLY field for use when
507 converting wireshark to new-style proto_tree. These fields
508 are merely strings on the GUI tree; they are not filterable */
509 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
511 /* Register the pseudo-protocols used for exceptions. */
512 register_show_exception();
513 register_type_length_mismatch();
514 register_number_string_decoding_error();
516 /* Have each built-in dissector register its protocols, fields,
517 dissector tables, and dissectors to be called through a
518 handle, and do whatever one-time initialization it needs to
520 register_all_protocols_func(cb, client_data);
523 /* Now call the registration routines for all disssector
526 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
527 g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL);
530 /* Now call the "handoff registration" routines of all built-in
531 dissectors; those routines register the dissector in other
532 dissectors' handoff tables, and fetch any dissector handles
534 register_all_handoffs_func(cb, client_data);
537 /* Now do the same with plugins. */
539 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
540 g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL);
543 /* sort the protocols by protocol name */
544 protocols = g_list_sort(protocols, proto_compare_name);
546 /* We've assigned all the subtree type values; allocate the array
547 for them, and zero it out. */
548 tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
554 /* Free the abbrev/ID hash table */
556 g_hash_table_destroy(gpa_name_map);
559 g_free(last_field_name);
560 last_field_name = NULL;
563 protocol_t *protocol = (protocol_t *)protocols->data;
564 header_field_info *hfinfo;
565 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
566 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
568 g_slice_free(header_field_info, hfinfo);
569 g_ptr_array_free(protocol->fields, TRUE);
570 g_list_free(protocol->heur_list);
571 protocols = g_list_remove(protocols, protocol);
576 g_hash_table_destroy(proto_names);
580 if (proto_short_names) {
581 g_hash_table_destroy(proto_short_names);
582 proto_short_names = NULL;
585 if (proto_filter_names) {
586 g_hash_table_destroy(proto_filter_names);
587 proto_filter_names = NULL;
590 if (gpa_hfinfo.allocated_len) {
592 gpa_hfinfo.allocated_len = 0;
593 g_free(gpa_hfinfo.hfi);
594 gpa_hfinfo.hfi = NULL;
597 if (deregistered_fields) {
598 g_ptr_array_free(deregistered_fields, FALSE);
599 deregistered_fields = NULL;
602 if (deregistered_data) {
603 g_ptr_array_free(deregistered_data, FALSE);
604 deregistered_data = NULL;
607 g_free(tree_is_expanded);
608 tree_is_expanded = NULL;
612 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
615 proto_node *pnode = tree;
619 if (func(pnode, data))
622 child = pnode->first_child;
623 while (child != NULL) {
625 * The routine we call might modify the child, e.g. by
626 * freeing it, so we get the child's successor before
627 * calling that routine.
630 child = current->next;
631 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
639 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
642 proto_node *pnode = tree;
646 child = pnode->first_child;
647 while (child != NULL) {
649 * The routine we call might modify the child, e.g. by
650 * freeing it, so we get the child's successor before
651 * calling that routine.
654 child = current->next;
655 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
658 if (func(pnode, data))
665 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
668 proto_node *node = tree;
674 node = node->first_child;
675 while (node != NULL) {
677 node = current->next;
678 func((proto_tree *)current, data);
683 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
685 GPtrArray *ptrs = (GPtrArray *)value;
686 gint hfid = GPOINTER_TO_UINT(key);
687 header_field_info *hfinfo;
689 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
690 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
691 /* when a field is referenced by a filter this also
692 affects the refcount for the parent protocol so we need
693 to adjust the refcount for the parent as well
695 if (hfinfo->parent != -1) {
696 header_field_info *parent_hfinfo;
697 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
698 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
700 hfinfo->ref_type = HF_REF_TYPE_NONE;
703 g_ptr_array_free(ptrs, TRUE);
707 proto_tree_free_node(proto_node *node, gpointer data _U_)
709 field_info *finfo = PNODE_FINFO(node);
711 proto_tree_children_foreach(node, proto_tree_free_node, NULL);
713 FVALUE_CLEANUP(&finfo->value);
717 proto_tree_reset(proto_tree *tree)
719 tree_data_t *tree_data = PTREE_DATA(tree);
721 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
724 if (tree_data->interesting_hfids) {
725 /* Free all the GPtrArray's in the interesting_hfids hash. */
726 g_hash_table_foreach(tree_data->interesting_hfids,
727 free_GPtrArray_value, NULL);
729 /* And then remove all values. */
730 g_hash_table_remove_all(tree_data->interesting_hfids);
733 /* Reset track of the number of children */
734 tree_data->count = 0;
736 PROTO_NODE_INIT(tree);
739 /* frees the resources that the dissection a proto_tree uses */
741 proto_tree_free(proto_tree *tree)
743 tree_data_t *tree_data = PTREE_DATA(tree);
745 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
748 if (tree_data->interesting_hfids) {
749 /* Free all the GPtrArray's in the interesting_hfids hash. */
750 g_hash_table_foreach(tree_data->interesting_hfids,
751 free_GPtrArray_value, NULL);
753 /* And then destroy the hash. */
754 g_hash_table_destroy(tree_data->interesting_hfids);
757 g_slice_free(tree_data_t, tree_data);
759 g_slice_free(proto_tree, tree);
762 /* Is the parsing being done for a visible proto_tree or an invisible one?
763 * By setting this correctly, the proto_tree creation is sped up by not
764 * having to call g_vsnprintf and copy strings around.
767 proto_tree_set_visible(proto_tree *tree, gboolean visible)
769 gboolean old_visible = PTREE_DATA(tree)->visible;
771 PTREE_DATA(tree)->visible = visible;
777 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
779 PTREE_DATA(tree)->fake_protocols = fake_protocols;
782 /* Assume dissector set only its protocol fields.
783 This function is called by dissectors and allows the speeding up of filtering
784 in wireshark; if this function returns FALSE it is safe to reset tree to NULL
785 and thus skip calling most of the expensive proto_tree_add_...()
787 If the tree is visible we implicitly assume the field is referenced.
790 proto_field_is_referenced(proto_tree *tree, int proto_id)
792 register header_field_info *hfinfo;
798 if (PTREE_DATA(tree)->visible)
801 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
802 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
805 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
812 /* Finds a record in the hfinfo array by id. */
814 proto_registrar_get_nth(guint hfindex)
816 register header_field_info *hfinfo;
818 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
823 /* Prefix initialization
824 * this allows for a dissector to register a display filter name prefix
825 * so that it can delay the initialization of the hf array as long as
829 /* compute a hash for the part before the dot of a display filter */
831 prefix_hash (gconstpointer key) {
832 /* end the string at the dot and compute its hash */
833 gchar* copy = g_strdup((const gchar *)key);
844 tmp = g_str_hash(copy);
849 /* are both strings equal up to the end or the dot? */
851 prefix_equal (gconstpointer ap, gconstpointer bp) {
852 const gchar* a = (const gchar *)ap;
853 const gchar* b = (const gchar *)bp;
859 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
861 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
862 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
864 if (ac != bc) return FALSE;
871 /* indexed by prefix, contains initializers */
872 static GHashTable* prefixes = NULL;
875 /* Register a new prefix for "delayed" initialization of field arrays */
877 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
879 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
882 g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
885 /* helper to call all prefix initializers */
887 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
888 ((prefix_initializer_t)v)((const char *)k);
892 /** Initialize every remaining uninitialized prefix. */
894 proto_initialize_all_prefixes(void) {
895 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
898 /* Finds a record in the hfinfo array by name.
899 * If it fails to find it in the already registered fields,
900 * it tries to find and call an initializer in the prefixes
901 * table and if so it looks again.
905 proto_registrar_get_byname(const char *field_name)
907 header_field_info *hfinfo;
908 prefix_initializer_t pi;
913 if (g_strcmp0(field_name, last_field_name) == 0) {
917 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
920 g_free(last_field_name);
921 last_field_name = g_strdup(field_name);
922 last_hfinfo = hfinfo;
929 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
931 g_hash_table_remove(prefixes, field_name);
936 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
939 g_free(last_field_name);
940 last_field_name = g_strdup(field_name);
941 last_hfinfo = hfinfo;
947 proto_registrar_get_id_byname(const char *field_name)
949 header_field_info *hfinfo;
951 hfinfo = proto_registrar_get_byname(field_name);
961 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
963 subtree_lvl *pushed_tree;
965 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
966 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
968 pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
969 DISSECTOR_ASSERT(pushed_tree != NULL);
970 if (ptvc->pushed_tree)
971 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
972 ptvc->pushed_tree = pushed_tree;
976 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
978 ptvc->pushed_tree = NULL;
979 ptvc->pushed_tree_max = 0;
980 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
981 ptvc->pushed_tree_index = 0;
984 /* Allocates an initializes a ptvcursor_t with 3 variables:
985 * proto_tree, tvbuff, and offset. */
987 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
991 ptvc = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
994 ptvc->offset = offset;
995 ptvc->pushed_tree = NULL;
996 ptvc->pushed_tree_max = 0;
997 ptvc->pushed_tree_index = 0;
1002 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1004 ptvcursor_free(ptvcursor_t *ptvc)
1006 ptvcursor_free_subtree_levels(ptvc);
1010 /* Returns tvbuff. */
1012 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1017 /* Returns current offset. */
1019 ptvcursor_current_offset(ptvcursor_t *ptvc)
1021 return ptvc->offset;
1025 ptvcursor_tree(ptvcursor_t *ptvc)
1034 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1039 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1041 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1043 subtree_lvl *subtree;
1044 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1045 ptvcursor_new_subtree_levels(ptvc);
1047 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1048 subtree->tree = ptvc->tree;
1050 ptvc->pushed_tree_index++;
1051 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1054 /* pops a subtree */
1056 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1058 subtree_lvl *subtree;
1060 if (ptvc->pushed_tree_index <= 0)
1063 ptvc->pushed_tree_index--;
1064 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1065 if (subtree->it != NULL)
1066 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1068 ptvc->tree = subtree->tree;
1071 /* saves the current tvb offset and the item in the current subtree level */
1073 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1075 subtree_lvl *subtree;
1077 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1079 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1081 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1084 /* Creates a subtree and adds it to the cursor as the working tree but does not
1085 * save the old working tree */
1087 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1089 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1094 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1096 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1097 if (length == SUBTREE_UNDEFINED_LENGTH)
1098 ptvcursor_subtree_set_item(ptvc, it);
1099 return ptvcursor_tree(ptvc);
1102 /* Add an item to the tree and create a subtree
1103 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1104 * In this case, when the subtree will be closed, the parent item length will
1105 * be equal to the advancement of the cursor since the creation of the subtree.
1108 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1109 const guint encoding, gint ett_subtree)
1113 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1114 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1118 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1120 /* Add a text node to the tree and create a subtree
1121 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1122 * In this case, when the subtree will be closed, the item length will be equal
1123 * to the advancement of the cursor since the creation of the subtree.
1126 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1127 gint ett_subtree, const char *format, ...)
1131 header_field_info *hfinfo;
1134 tree = ptvcursor_tree(ptvc);
1136 CHECK_FOR_NULL_TREE(tree);
1138 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1140 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1141 ptvcursor_current_offset(ptvc), length);
1143 TRY_TO_FAKE_THIS_REPR(pi);
1145 va_start(ap, format);
1146 proto_tree_set_representation(pi, format, ap);
1149 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1152 /* Add a text-only node, leaving it to our caller to fill the text in */
1154 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1161 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1166 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1168 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1169 const char *format, ...)
1173 header_field_info *hfinfo;
1175 CHECK_FOR_NULL_TREE(tree);
1177 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1179 pi = proto_tree_add_text_node(tree, tvb, start, length);
1181 TRY_TO_FAKE_THIS_REPR(pi);
1183 va_start(ap, format);
1184 proto_tree_set_representation(pi, format, ap);
1190 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1192 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1193 gint length, const char *format, va_list ap)
1196 header_field_info *hfinfo;
1198 CHECK_FOR_NULL_TREE(tree);
1200 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1202 pi = proto_tree_add_text_node(tree, tvb, start, length);
1204 TRY_TO_FAKE_THIS_REPR(pi);
1206 proto_tree_set_representation(pi, format, ap);
1211 /* Add a text-only node that creates a subtree underneath.
1214 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1216 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1219 /* Add a text-only node that creates a subtree underneath.
1222 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1228 va_start(ap, format);
1229 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1232 if (tree_item != NULL)
1235 pt = proto_item_add_subtree(pi, idx);
1240 /* Add a text-only node for debugging purposes. The caller doesn't need
1241 * to worry about tvbuff, start, or length. Debug message gets sent to
1244 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1249 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1252 va_start(ap, format);
1253 proto_tree_set_representation(pi, format, ap);
1256 va_start(ap, format);
1257 vprintf(format, ap);
1265 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1268 header_field_info *hfinfo;
1270 CHECK_FOR_NULL_TREE(tree);
1272 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1274 pi = proto_tree_add_text_node(tree, tvb, start, length);
1276 TRY_TO_FAKE_THIS_REPR(pi);
1278 proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1284 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1287 header_field_info *hfinfo;
1289 CHECK_FOR_NULL_TREE(tree);
1291 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1293 pi = proto_tree_add_text_node(tree, tvb, start, length);
1295 TRY_TO_FAKE_THIS_REPR(pi);
1297 proto_item_set_text(pi, "%s", tvb_format_text_wsp(tvb, start, length));
1302 void proto_report_dissector_bug(const char *message)
1304 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1307 THROW_MESSAGE(DissectorError, message);
1310 /* We could probably get away with changing is_error to a minimum length value. */
1312 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1315 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1317 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1321 THROW(ReportedBoundsError);
1326 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1329 gboolean length_error;
1334 value = tvb_get_guint8(tvb, offset);
1338 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1339 : tvb_get_ntohs(tvb, offset);
1343 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1344 : tvb_get_ntoh24(tvb, offset);
1348 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1349 : tvb_get_ntohl(tvb, offset);
1354 length_error = TRUE;
1357 length_error = FALSE;
1358 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1359 : tvb_get_ntohl(tvb, offset);
1361 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1367 static inline guint64
1368 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1371 gboolean length_error;
1376 value = tvb_get_guint8(tvb, offset);
1380 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1381 : tvb_get_ntohs(tvb, offset);
1385 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1386 : tvb_get_ntoh24(tvb, offset);
1390 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1391 : tvb_get_ntohl(tvb, offset);
1395 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1396 : tvb_get_ntoh40(tvb, offset);
1400 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1401 : tvb_get_ntoh48(tvb, offset);
1405 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1406 : tvb_get_ntoh56(tvb, offset);
1410 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1411 : tvb_get_ntoh64(tvb, offset);
1416 length_error = TRUE;
1419 length_error = FALSE;
1420 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1421 : tvb_get_ntoh64(tvb, offset);
1423 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1430 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1433 gboolean length_error;
1438 value = (gint8)tvb_get_guint8(tvb, offset);
1442 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1443 : tvb_get_ntohs(tvb, offset));
1447 value = encoding ? tvb_get_letoh24(tvb, offset)
1448 : tvb_get_ntoh24(tvb, offset);
1449 if (value & 0x00800000) {
1450 /* Sign bit is set; sign-extend it. */
1451 value |= 0xFF000000;
1456 value = encoding ? tvb_get_letohl(tvb, offset)
1457 : tvb_get_ntohl(tvb, offset);
1462 length_error = TRUE;
1465 length_error = FALSE;
1466 value = encoding ? tvb_get_letohl(tvb, offset)
1467 : tvb_get_ntohl(tvb, offset);
1469 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1475 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1476 * be cast-able as a gint64. This is weird, but what the code has always done.
1478 static inline guint64
1479 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1481 guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1486 value = ws_sign_ext64(value, 56);
1489 value = ws_sign_ext64(value, 48);
1492 value = ws_sign_ext64(value, 40);
1495 value = ws_sign_ext64(value, 32);
1498 value = ws_sign_ext64(value, 24);
1501 value = ws_sign_ext64(value, 16);
1504 value = ws_sign_ext64(value, 8);
1512 static inline const guint8 *
1513 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1514 gint length, gint *ret_length, const guint encoding)
1517 length = tvb_ensure_captured_length_remaining(tvb, start);
1519 *ret_length = length;
1520 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1523 /* For FT_STRINGZ */
1524 static inline const guint8 *
1525 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1526 gint start, gint length, gint *ret_length, const guint encoding)
1528 const guint8 *value;
1531 report_type_length_mismatch(tree, "a string", length, TRUE);
1534 /* This can throw an exception */
1535 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1536 } else if (length == 0) {
1539 /* In this case, length signifies the length of the string.
1541 * This could either be a null-padded string, which doesn't
1542 * necessarily have a '\0' at the end, or a null-terminated
1543 * string, with a trailing '\0'. (Yes, there are cases
1544 * where you have a string that's both counted and null-
1547 * In the first case, we must allocate a buffer of length
1548 * "length+1", to make room for a trailing '\0'.
1550 * In the second case, we don't assume that there is a
1551 * trailing '\0' there, as the packet might be malformed.
1552 * (XXX - should we throw an exception if there's no
1553 * trailing '\0'?) Therefore, we allocate a buffer of
1554 * length "length+1", and put in a trailing '\0', just to
1557 * (XXX - this would change if we made string values counted
1558 * rather than null-terminated.)
1560 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1562 *ret_length = length;
1566 /* For FT_UINT_STRING */
1567 static inline const guint8 *
1568 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1569 tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1570 const guint encoding)
1573 const guint8 *value;
1575 /* I believe it's ok if this is called with a NULL tree */
1576 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1577 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1579 *ret_length = length;
1583 /* For FT_STRINGZPAD */
1584 static inline const guint8 *
1585 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1586 gint length, gint *ret_length, const guint encoding)
1589 * XXX - currently, string values are null-
1590 * terminated, so a "zero-padded" string
1591 * isn't special. If we represent string
1592 * values as something that includes a counted
1593 * array of bytes, we'll need to strip
1597 length = tvb_ensure_captured_length_remaining(tvb, start);
1599 *ret_length = length;
1600 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1603 /* this can be called when there is no tree, so don't add that as a param */
1605 get_time_value(tvbuff_t *tvb, const gint start, const gint length, const guint encoding,
1606 nstime_t *time_stamp, const gboolean is_relative)
1611 /* relative timestamps don't do TOD/NTP */
1613 (encoding != (ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN)) &&
1614 (encoding != (ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN)) )
1616 /* XXX: I think this should call REPORT_DISSECTOR_BUG(), but
1617 the existing code didn't do that, so I'm not either */
1623 case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1625 * 4-byte UNIX epoch, possibly followed by
1626 * 4-byte fractional time in nanoseconds,
1629 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1631 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1633 time_stamp->nsecs = 0;
1636 case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1638 * 4-byte UNIX epoch, possibly followed by
1639 * 4-byte fractional time in nanoseconds,
1640 * both little-endian.
1642 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1644 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1646 time_stamp->nsecs = 0;
1649 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1651 * TOD time stamp, big-endian.
1653 /* XXX - where should this go? */
1654 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800)
1656 todsecs = tvb_get_ntoh64(tvb, start) >> 12;
1657 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1658 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1661 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1663 * TOD time stamp, big-endian.
1665 todsecs = tvb_get_letoh64(tvb, start) >> 12 ;
1666 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1667 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1670 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1672 * NTP time stamp, big-endian.
1675 /* XXX - where should this go? */
1676 #define NTP_BASETIME G_GUINT64_CONSTANT(2208988800)
1678 /* We need a temporary variable here so the unsigned math
1679 * works correctly (for years > 2036 according to RFC 2030
1682 tmpsecs = tvb_get_ntohl(tvb, start);
1684 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1686 time_stamp->secs = tmpsecs; /* 0 */
1690 * We're using nanoseconds here (and we will
1691 * display nanoseconds), but NTP's timestamps
1692 * have a precision in microseconds or greater.
1693 * Round to 1 microsecond.
1695 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1696 time_stamp->nsecs *= 1000;
1698 time_stamp->nsecs = 0;
1702 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1704 * NTP time stamp, big-endian.
1706 tmpsecs = tvb_get_letohl(tvb, start);
1708 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1710 time_stamp->secs = tmpsecs; /* 0 */
1714 * We're using nanoseconds here (and we will
1715 * display nanoseconds), but NTP's timestamps
1716 * have a precision in microseconds or greater.
1717 * Round to 1 microsecond.
1719 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1720 time_stamp->nsecs *= 1000;
1722 time_stamp->nsecs = 0;
1725 case ENC_TIME_NTP_BASE_ZERO|ENC_BIG_ENDIAN:
1727 * DDS NTP time stamp, big-endian.
1730 #define NTP_BASETIME_ZERO G_GUINT64_CONSTANT(0)
1732 tmpsecs = tvb_get_ntohl(tvb, start);
1734 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1736 time_stamp->secs = tmpsecs; /* 0 */
1740 * We're using nanoseconds here (and we will
1741 * display nanoseconds), but NTP's timestamps
1742 * have a precision in microseconds or greater.
1743 * Round to 1 microsecond.
1745 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1746 time_stamp->nsecs *= 1000;
1748 time_stamp->nsecs = 0;
1752 case ENC_TIME_NTP_BASE_ZERO|ENC_LITTLE_ENDIAN:
1754 * NTP time stamp, big-endian.
1756 tmpsecs = tvb_get_letohl(tvb, start);
1758 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1760 time_stamp->secs = tmpsecs; /* 0 */
1761 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1764 * We're using nanoseconds here (and we will
1765 * display nanoseconds), but NTP's timestamps
1766 * have a precision in microseconds or greater.
1767 * Round to 1 microsecond.
1769 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1770 time_stamp->nsecs *= 1000;
1772 time_stamp->nsecs = 0;
1777 DISSECTOR_ASSERT_NOT_REACHED();
1783 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
1785 const header_field_info *hfinfo = fi->hfinfo;
1787 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
1788 GPtrArray *ptrs = NULL;
1790 if (tree_data->interesting_hfids == NULL) {
1791 /* Initialize the hash because we now know that it is needed */
1792 tree_data->interesting_hfids =
1793 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
1794 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
1795 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
1796 GINT_TO_POINTER(hfinfo->id));
1800 /* First element triggers the creation of pointer array */
1801 ptrs = g_ptr_array_new();
1802 g_hash_table_insert(tree_data->interesting_hfids,
1803 GINT_TO_POINTER(hfinfo->id), ptrs);
1806 g_ptr_array_add(ptrs, fi);
1810 /* Add an item to a proto_tree, using the text label registered to that item;
1811 the item is extracted from the tvbuff handed to it. */
1813 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
1814 tvbuff_t *tvb, gint start, gint length,
1821 const char *stringval;
1822 nstime_t time_stamp;
1823 gboolean length_error;
1825 switch (new_fi->hfinfo->type) {
1827 /* no value to set for FT_NONE */
1831 proto_tree_set_protocol_tvb(new_fi, tvb);
1835 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
1840 * Map all non-zero values to little-endian for
1841 * backwards compatibility.
1844 encoding = ENC_LITTLE_ENDIAN;
1845 n = get_uint_value(tree, tvb, start, length, encoding);
1846 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
1848 /* Instead of calling proto_item_set_len(), since we don't yet
1849 * have a proto_item, we set the field_info's length ourselves. */
1850 new_fi->length = n + length;
1855 * Map all non-zero values to little-endian for
1856 * backwards compatibility.
1859 encoding = ENC_LITTLE_ENDIAN;
1860 proto_tree_set_boolean(new_fi,
1861 get_uint64_value(tree, tvb, start, length, encoding));
1864 /* XXX - make these just FT_UINT? */
1870 * Map all non-zero values to little-endian for
1871 * backwards compatibility.
1874 encoding = ENC_LITTLE_ENDIAN;
1875 proto_tree_set_uint(new_fi,
1876 get_uint_value(tree, tvb, start, length, encoding));
1884 * Map all non-zero values to little-endian for
1885 * backwards compatibility.
1888 encoding = ENC_LITTLE_ENDIAN;
1889 proto_tree_set_uint64(new_fi,
1890 get_uint64_value(tree, tvb, start, length, encoding));
1893 /* XXX - make these just FT_INT? */
1899 * Map all non-zero values to little-endian for
1900 * backwards compatibility.
1903 encoding = ENC_LITTLE_ENDIAN;
1904 proto_tree_set_int(new_fi,
1905 get_int_value(tree, tvb, start, length, encoding));
1913 * Map all non-zero values to little-endian for
1914 * backwards compatibility.
1917 encoding = ENC_LITTLE_ENDIAN;
1918 proto_tree_set_int64(new_fi,
1919 get_int64_value(tree, tvb, start, length, encoding));
1924 * Map all non-zero values to little-endian for
1925 * backwards compatibility.
1928 encoding = ENC_LITTLE_ENDIAN;
1929 if (length != FT_IPv4_LEN) {
1930 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
1931 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
1933 value = tvb_get_ipv4(tvb, start);
1935 * NOTE: to support code written when
1936 * proto_tree_add_item() took a gboolean as its
1937 * last argument, with FALSE meaning "big-endian"
1938 * and TRUE meaning "little-endian", we treat any
1939 * non-zero value of "encoding" as meaning
1942 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
1946 if (length != FT_IPXNET_LEN) {
1947 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
1948 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
1950 proto_tree_set_ipxnet(new_fi,
1951 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
1955 if (length != FT_IPv6_LEN) {
1956 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
1957 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
1959 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
1963 if (length != FT_FCWWN_LEN) {
1964 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
1965 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
1967 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
1972 length_error = length < 7 ? TRUE : FALSE;
1973 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
1975 proto_tree_set_ax25_tvb(new_fi, tvb, start);
1979 if (length != VINES_ADDR_LEN) {
1980 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
1981 report_type_length_mismatch(tree, "a Vines address", length, length_error);
1983 proto_tree_set_vines_tvb(new_fi, tvb, start);
1987 if (length != FT_ETHER_LEN) {
1988 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
1989 report_type_length_mismatch(tree, "a MAC address", length, length_error);
1991 proto_tree_set_ether_tvb(new_fi, tvb, start);
1996 * Map all non-zero values to little-endian for
1997 * backwards compatibility.
2000 encoding = ENC_LITTLE_ENDIAN;
2001 if (length != FT_EUI64_LEN) {
2002 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2003 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2005 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2009 * Map all non-zero values to little-endian for
2010 * backwards compatibility.
2013 encoding = ENC_LITTLE_ENDIAN;
2014 if (length != FT_GUID_LEN) {
2015 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2016 report_type_length_mismatch(tree, "a GUID", length, length_error);
2018 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2023 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2027 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2032 * NOTE: to support code written when
2033 * proto_tree_add_item() took a gboolean as its
2034 * last argument, with FALSE meaning "big-endian"
2035 * and TRUE meaning "little-endian", we treat any
2036 * non-zero value of "encoding" as meaning
2039 * At some point in the future, we might
2040 * support non-IEEE-binary floating-point
2041 * formats in the encoding as well
2042 * (IEEE decimal, System/3x0, VAX).
2045 encoding = ENC_LITTLE_ENDIAN;
2047 length_error = length < 4 ? TRUE : FALSE;
2048 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2051 floatval = tvb_get_letohieee_float(tvb, start);
2053 floatval = tvb_get_ntohieee_float(tvb, start);
2054 proto_tree_set_float(new_fi, floatval);
2059 * NOTE: to support code written when
2060 * proto_tree_add_item() took a gboolean as its
2061 * last argument, with FALSE meaning "big-endian"
2062 * and TRUE meaning "little-endian", we treat any
2063 * non-zero value of "encoding" as meaning
2066 * At some point in the future, we might
2067 * support non-IEEE-binary floating-point
2068 * formats in the encoding as well
2069 * (IEEE decimal, System/3x0, VAX).
2071 if (encoding == TRUE)
2072 encoding = ENC_LITTLE_ENDIAN;
2074 length_error = length < 8 ? TRUE : FALSE;
2075 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2078 doubleval = tvb_get_letohieee_double(tvb, start);
2080 doubleval = tvb_get_ntohieee_double(tvb, start);
2081 proto_tree_set_double(new_fi, doubleval);
2085 stringval = get_string_value(wmem_packet_scope(),
2086 tvb, start, length, &length, encoding);
2087 proto_tree_set_string(new_fi, stringval);
2089 /* Instead of calling proto_item_set_len(), since we
2090 * don't yet have a proto_item, we set the
2091 * field_info's length ourselves.
2093 * XXX - our caller can't use that length to
2094 * advance an offset unless they arrange that
2095 * there always be a protocol tree into which
2096 * we're putting this item.
2098 new_fi->length = length;
2102 stringval = get_stringz_value(wmem_packet_scope(),
2103 tree, tvb, start, length, &length, encoding);
2104 proto_tree_set_string(new_fi, stringval);
2106 /* Instead of calling proto_item_set_len(),
2107 * since we don't yet have a proto_item, we
2108 * set the field_info's length ourselves.
2110 * XXX - our caller can't use that length to
2111 * advance an offset unless they arrange that
2112 * there always be a protocol tree into which
2113 * we're putting this item.
2115 new_fi->length = length;
2118 case FT_UINT_STRING:
2120 * NOTE: to support code written when
2121 * proto_tree_add_item() took a gboolean as its
2122 * last argument, with FALSE meaning "big-endian"
2123 * and TRUE meaning "little-endian", if the
2124 * encoding value is TRUE, treat that as
2125 * ASCII with a little-endian length.
2127 * This won't work for code that passes
2128 * arbitrary non-zero values; that code
2129 * will need to be fixed.
2131 if (encoding == TRUE)
2132 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2133 stringval = get_uint_string_value(wmem_packet_scope(),
2134 tree, tvb, start, length, &length, encoding);
2135 proto_tree_set_string(new_fi, stringval);
2137 /* Instead of calling proto_item_set_len(), since we
2138 * don't yet have a proto_item, we set the
2139 * field_info's length ourselves.
2141 * XXX - our caller can't use that length to
2142 * advance an offset unless they arrange that
2143 * there always be a protocol tree into which
2144 * we're putting this item.
2146 new_fi->length = length;
2150 stringval = get_stringzpad_value(wmem_packet_scope(),
2151 tvb, start, length, &length, encoding);
2152 proto_tree_set_string(new_fi, stringval);
2154 /* Instead of calling proto_item_set_len(), since we
2155 * don't yet have a proto_item, we set the
2156 * field_info's length ourselves.
2158 * XXX - our caller can't use that length to
2159 * advance an offset unless they arrange that
2160 * there always be a protocol tree into which
2161 * we're putting this item.
2163 new_fi->length = length;
2166 case FT_ABSOLUTE_TIME:
2168 * Absolute times can be in any of a number of
2169 * formats, and they can be big-endian or
2172 * Historically FT_TIMEs were only timespecs;
2173 * the only question was whether they were stored
2174 * in big- or little-endian format.
2176 * For backwards compatibility, we interpret an
2177 * encoding of 1 as meaning "little-endian timespec",
2178 * so that passing TRUE is interpreted as that.
2180 if (encoding == TRUE)
2181 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2183 if (length != 8 && length != 4) {
2184 length_error = length < 4 ? TRUE : FALSE;
2185 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2188 get_time_value(tvb, start, length, encoding, &time_stamp, FALSE);
2190 proto_tree_set_time(new_fi, &time_stamp);
2193 case FT_RELATIVE_TIME:
2195 * Relative times can be in any of a number of
2196 * formats, and they can be big-endian or
2199 * Historically FT_TIMEs were only timespecs;
2200 * the only question was whether they were stored
2201 * in big- or little-endian format.
2203 * For backwards compatibility, we interpret an
2204 * encoding of 1 as meaning "little-endian timespec",
2205 * so that passing TRUE is interpreted as that.
2207 if (encoding == TRUE)
2208 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2210 if (length != 8 && length != 4) {
2211 length_error = length < 4 ? TRUE : FALSE;
2212 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2215 get_time_value(tvb, start, length, encoding, &time_stamp, TRUE);
2217 proto_tree_set_time(new_fi, &time_stamp);
2219 case FT_IEEE_11073_SFLOAT:
2221 encoding = ENC_LITTLE_ENDIAN;
2223 length_error = length < 2 ? TRUE : FALSE;
2224 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2227 fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2230 case FT_IEEE_11073_FLOAT:
2232 encoding = ENC_LITTLE_ENDIAN;
2234 length_error = length < 4 ? TRUE : FALSE;
2235 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2240 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2241 new_fi->hfinfo->type,
2242 ftype_name(new_fi->hfinfo->type));
2243 DISSECTOR_ASSERT_NOT_REACHED();
2246 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2248 /* Don't add new node to proto_tree until now so that any exceptions
2249 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2250 /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2251 * to know which item caused exception? */
2252 pi = proto_tree_add_node(tree, new_fi);
2258 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2259 const gint start, gint length,
2260 const guint encoding, gint32 *retval)
2262 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2266 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2268 switch (hfinfo->type){
2275 DISSECTOR_ASSERT_NOT_REACHED();
2278 /* length validation for native number encoding caught by get_uint_value() */
2279 /* length has to be -1 or > 0 regardless of encoding */
2280 if (length < -1 || length == 0)
2281 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2282 "Invalid length %d passed to proto_tree_add_item_ret_int",
2285 if (encoding & ENC_STRING) {
2286 REPORT_DISSECTOR_BUG("wrong encoding");
2288 /* I believe it's ok if this is called with a NULL tree */
2289 value = get_int_value(tree, tvb, start, length, encoding);
2294 CHECK_FOR_NULL_TREE(tree);
2296 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2298 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2300 proto_tree_set_int(new_fi, value);
2302 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2304 return proto_tree_add_node(tree, new_fi);
2308 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2309 const gint start, gint length,
2310 const guint encoding, guint32 *retval)
2312 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2316 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2318 switch (hfinfo->type){
2325 DISSECTOR_ASSERT_NOT_REACHED();
2328 /* length validation for native number encoding caught by get_uint_value() */
2329 /* length has to be -1 or > 0 regardless of encoding */
2330 if (length < -1 || length == 0)
2331 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2332 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2335 if (encoding & ENC_STRING) {
2336 REPORT_DISSECTOR_BUG("wrong encoding");
2338 /* I believe it's ok if this is called with a NULL tree */
2339 value = get_uint_value(tree, tvb, start, length, encoding);
2344 CHECK_FOR_NULL_TREE(tree);
2346 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2348 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2350 proto_tree_set_uint(new_fi, value);
2352 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2354 return proto_tree_add_node(tree, new_fi);
2358 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2359 const gint start, gint length,
2360 const guint encoding, wmem_allocator_t *scope,
2361 const guint8 **retval)
2363 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2365 const guint8 *value;
2367 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2369 switch (hfinfo->type){
2371 value = get_string_value(scope, tvb, start, length, &length, encoding);
2374 value = get_stringz_value(scope, tree, tvb, start, length, &length, encoding);
2376 case FT_UINT_STRING:
2377 value = get_uint_string_value(scope, tree, tvb, start, length, &length, encoding);
2380 value = get_stringzpad_value(scope, tvb, start, length, &length, encoding);
2383 DISSECTOR_ASSERT_NOT_REACHED();
2389 CHECK_FOR_NULL_TREE(tree);
2391 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2393 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2395 proto_tree_set_string(new_fi, value);
2397 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2399 return proto_tree_add_node(tree, new_fi);
2404 * Validates that field length bytes are available starting from
2405 * start (pos/neg). Throws an exception if they aren't.
2408 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2409 gint start, gint length)
2416 if (hfinfo->type == FT_STRINGZ) {
2417 /* If we're fetching until the end of the TVB, only validate
2418 * that the offset is within range.
2424 tvb_ensure_bytes_exist(tvb, start, size);
2427 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2428 and returns proto_item* */
2430 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
2431 const guint encoding)
2434 header_field_info *hfinfo;
2438 offset = ptvc->offset;
2439 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2440 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
2443 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset,
2444 length, item_length, encoding);
2448 offset = ptvc->offset;
2449 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2450 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
2451 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2452 item_length, encoding);
2454 test_length(hfinfo, ptvc->tvb, offset, item_length);
2456 /* Coast clear. Try and fake it */
2457 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2459 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2461 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2462 offset, length, encoding);
2465 /* Add an item to a proto_tree, using the text label registered to that item;
2466 the item is extracted from the tvbuff handed to it. */
2468 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
2469 const gint start, gint length, const guint encoding)
2474 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2476 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2477 test_length(hfinfo, tvb, start, item_length);
2479 CHECK_FOR_NULL_TREE(tree);
2481 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2483 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2485 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2489 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2490 const gint start, gint length, const guint encoding)
2492 register header_field_info *hfinfo;
2494 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2495 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
2498 /* Add an item to a proto_tree, using the text label registered to that item;
2499 the item is extracted from the tvbuff handed to it.
2501 Return the length of the item through the pointer. */
2503 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
2504 tvbuff_t *tvb, const gint start,
2505 gint length, const guint encoding,
2512 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2514 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2515 test_length(hfinfo, tvb, start, item_length);
2519 * We need to get the correct item length here.
2520 * That's normally done by proto_tree_new_item(),
2521 * but we won't be calling it.
2523 *retval = get_full_length(hfinfo, tvb, start, length,
2524 item_length, encoding);
2528 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2530 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2532 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2533 *retval = new_fi->length;
2538 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2539 const gint start, gint length,
2540 const guint encoding, gint *retval)
2542 register header_field_info *hfinfo;
2544 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2545 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, retval);
2548 /* which FT_ types can use proto_tree_add_bytes_item() */
2549 static inline gboolean
2550 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
2552 return (type == FT_BYTES ||
2553 type == FT_UINT_BYTES ||
2555 type == FT_REL_OID ||
2556 type == FT_SYSTEM_ID );
2559 /* Note: this does no validation that the byte array of an FT_OID or
2560 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
2561 so I think it's ok to continue not validating it?
2564 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2565 const gint start, gint length, const guint encoding,
2566 GByteArray *retval, gint *endoff, gint *err)
2569 GByteArray *bytes = retval;
2570 GByteArray *created_bytes = NULL;
2573 header_field_info *hfinfo;
2574 gboolean generate = (bytes || tree) ? TRUE : FALSE;
2576 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2578 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2580 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
2581 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
2583 /* length has to be -1 or > 0 regardless of encoding */
2584 /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
2585 if (length < -1 || length == 0) {
2586 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2587 "Invalid length %d passed to proto_tree_add_bytes_item for %s",
2588 length, ftype_name(hfinfo->type)));
2591 if (encoding & ENC_STR_NUM) {
2592 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
2595 if (generate && (encoding & ENC_STR_HEX)) {
2596 if (hfinfo->type == FT_UINT_BYTES) {
2597 /* can't decode FT_UINT_BYTES from strings */
2598 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
2599 "FT_UINT_BYTES type, but as ENC_STR_HEX");
2603 /* caller doesn't care about return value, but we need it to
2604 call tvb_get_string_bytes() and set the tree later */
2605 bytes = created_bytes = g_byte_array_new();
2608 /* bytes might be NULL after this, but can't add expert error until later */
2609 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
2611 /* grab the errno now before it gets overwritten */
2614 else if (generate) {
2615 tvb_ensure_bytes_exist(tvb, start, length);
2618 /* caller doesn't care about return value, but we need it to
2619 call tvb_get_string_bytes() and set the tree later */
2620 bytes = created_bytes = g_byte_array_new();
2623 if (hfinfo->type == FT_UINT_BYTES) {
2624 n = length; /* n is now the "header" length */
2625 length = get_uint_value(tree, tvb, start, n, encoding);
2626 /* length is now the value's length; only store the value in the array */
2627 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
2629 else if (length > 0) {
2630 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
2634 *endoff = start + n + length;
2637 if (err) *err = saved_err;
2639 CHECK_FOR_NULL_TREE_AND_FREE(tree,
2642 g_byte_array_free(created_bytes, TRUE);
2643 created_bytes = NULL;
2647 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
2650 g_byte_array_free(created_bytes, TRUE);
2651 created_bytes = NULL;
2655 /* n will be zero except when it's a FT_UINT_BYTES */
2656 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
2658 if (encoding & ENC_STRING) {
2659 if (saved_err == ERANGE)
2660 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2661 else if (!bytes || saved_err != 0)
2662 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2665 proto_tree_set_bytes_gbytearray(new_fi, bytes);
2667 proto_tree_set_bytes(new_fi, NULL, 0);
2670 g_byte_array_free(created_bytes, TRUE);
2673 /* n will be zero except when it's a FT_UINT_BYTES */
2674 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
2677 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2680 return proto_tree_add_node(tree, new_fi);
2685 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2686 const gint start, gint length, const guint encoding,
2687 nstime_t *retval, gint *endoff, gint *err)
2690 nstime_t time_stamp;
2692 header_field_info *hfinfo;
2694 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2696 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2698 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
2700 /* length has to be -1 or > 0 regardless of encoding */
2701 if (length < -1 || length == 0) {
2702 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2703 "Invalid length %d passed to proto_tree_add_time_item", length));
2706 time_stamp.secs = 0;
2707 time_stamp.nsecs = 0;
2709 if (encoding & ENC_STR_TIME_MASK) {
2710 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
2711 /* grab the errno now before it gets overwritten */
2715 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
2717 if (length != 8 && length != 4) {
2718 const gboolean length_error = length < 4 ? TRUE : FALSE;
2720 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2722 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2725 tvb_ensure_bytes_exist(tvb, start, length);
2726 get_time_value(tvb, start, length, encoding, &time_stamp, is_relative);
2727 if (endoff) *endoff = length;
2730 if (err) *err = saved_err;
2733 retval->secs = time_stamp.secs;
2734 retval->nsecs = time_stamp.nsecs;
2737 CHECK_FOR_NULL_TREE(tree);
2739 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2741 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2743 proto_tree_set_time(new_fi, &time_stamp);
2745 if (encoding & ENC_STRING) {
2746 if (saved_err == ERANGE)
2747 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2748 else if (saved_err == EDOM)
2749 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2753 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2756 return proto_tree_add_node(tree, new_fi);
2759 /* Add a FT_NONE to a proto_tree */
2761 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
2762 const gint start, gint length, const char *format,
2767 header_field_info *hfinfo;
2769 CHECK_FOR_NULL_TREE(tree);
2771 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2773 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
2775 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2777 TRY_TO_FAKE_THIS_REPR(pi);
2779 va_start(ap, format);
2780 proto_tree_set_representation(pi, format, ap);
2783 /* no value to set for FT_NONE */
2787 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
2788 * offset, and returns proto_item* */
2790 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
2791 const guint encoding)
2795 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
2801 /* Advance the ptvcursor's offset within its tvbuff without
2802 * adding anything to the proto_tree. */
2804 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
2806 ptvc->offset += length;
2811 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
2813 fvalue_set_tvbuff(&fi->value, tvb);
2816 /* Add a FT_PROTOCOL to a proto_tree */
2818 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2819 gint start, gint length, const char *format, ...)
2823 header_field_info *hfinfo;
2825 CHECK_FOR_NULL_TREE(tree);
2827 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2829 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
2831 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2833 proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length)));
2835 TRY_TO_FAKE_THIS_REPR(pi);
2837 va_start(ap, format);
2838 proto_tree_set_representation(pi, format, ap);
2844 /* Add a FT_BYTES to a proto_tree */
2846 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2847 gint length, const guint8 *start_ptr)
2850 header_field_info *hfinfo;
2853 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2854 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2855 test_length(hfinfo, tvb, start, item_length);
2857 CHECK_FOR_NULL_TREE(tree);
2859 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2861 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2863 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2864 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
2869 /* Add a FT_BYTES to a proto_tree */
2871 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2872 gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
2875 header_field_info *hfinfo;
2878 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2879 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length);
2880 test_length(hfinfo, tvb, start, item_length);
2882 CHECK_FOR_NULL_TREE(tree);
2884 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2886 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2888 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
2889 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
2895 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2896 gint start, gint length,
2897 const guint8 *start_ptr,
2898 const char *format, ...)
2902 header_field_info *hfinfo;
2905 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2906 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2907 test_length(hfinfo, tvb, start, item_length);
2909 CHECK_FOR_NULL_TREE(tree);
2911 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2914 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2917 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2918 tvb_get_ptr(tvb, start, length));
2920 va_start(ap, format);
2921 proto_tree_set_representation_value(pi, format, ap);
2928 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2929 gint start, gint length, const guint8 *start_ptr,
2930 const char *format, ...)
2934 header_field_info *hfinfo;
2937 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2938 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2939 test_length(hfinfo, tvb, start, item_length);
2941 CHECK_FOR_NULL_TREE(tree);
2943 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2946 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2949 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2950 tvb_get_ptr(tvb, start, length));
2952 TRY_TO_FAKE_THIS_REPR(pi);
2954 va_start(ap, format);
2955 proto_tree_set_representation(pi, format, ap);
2962 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
2966 DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
2968 bytes = g_byte_array_new();
2970 g_byte_array_append(bytes, start_ptr, length);
2972 fvalue_set_byte_array(&fi->value, bytes);
2977 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
2979 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
2983 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
2987 DISSECTOR_ASSERT(value != NULL);
2989 bytes = byte_array_dup(value);
2991 fvalue_set_byte_array(&fi->value, bytes);
2994 /* Add a FT_*TIME to a proto_tree */
2996 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2997 gint length, const nstime_t *value_ptr)
3000 header_field_info *hfinfo;
3002 CHECK_FOR_NULL_TREE(tree);
3004 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3006 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3008 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3009 proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
3015 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3016 gint start, gint length, nstime_t *value_ptr,
3017 const char *format, ...)
3022 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3024 va_start(ap, format);
3025 proto_tree_set_representation_value(pi, format, ap);
3033 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3034 gint start, gint length, nstime_t *value_ptr,
3035 const char *format, ...)
3040 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3042 TRY_TO_FAKE_THIS_REPR(pi);
3044 va_start(ap, format);
3045 proto_tree_set_representation(pi, format, ap);
3052 /* Set the FT_*TIME value */
3054 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
3056 DISSECTOR_ASSERT(value_ptr != NULL);
3058 fvalue_set_time(&fi->value, value_ptr);
3061 /* Add a FT_IPXNET to a proto_tree */
3063 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3064 gint length, guint32 value)
3067 header_field_info *hfinfo;
3069 CHECK_FOR_NULL_TREE(tree);
3071 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3073 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
3075 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3076 proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
3082 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3083 gint start, gint length, guint32 value,
3084 const char *format, ...)
3089 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3091 va_start(ap, format);
3092 proto_tree_set_representation_value(pi, format, ap);
3100 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3101 gint start, gint length, guint32 value,
3102 const char *format, ...)
3107 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3109 TRY_TO_FAKE_THIS_REPR(pi);
3111 va_start(ap, format);
3112 proto_tree_set_representation(pi, format, ap);
3119 /* Set the FT_IPXNET value */
3121 proto_tree_set_ipxnet(field_info *fi, guint32 value)
3123 fvalue_set_uinteger(&fi->value, value);
3126 /* Add a FT_IPv4 to a proto_tree */
3128 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3129 gint length, guint32 value)
3132 header_field_info *hfinfo;
3134 CHECK_FOR_NULL_TREE(tree);
3136 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3138 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
3140 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3141 proto_tree_set_ipv4(PNODE_FINFO(pi), value);
3147 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3148 gint start, gint length, guint32 value,
3149 const char *format, ...)
3154 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3156 va_start(ap, format);
3157 proto_tree_set_representation_value(pi, format, ap);
3165 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3166 gint start, gint length, guint32 value,
3167 const char *format, ...)
3172 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3174 TRY_TO_FAKE_THIS_REPR(pi);
3176 va_start(ap, format);
3177 proto_tree_set_representation(pi, format, ap);
3184 /* Set the FT_IPv4 value */
3186 proto_tree_set_ipv4(field_info *fi, guint32 value)
3188 fvalue_set_uinteger(&fi->value, value);
3191 /* Add a FT_IPv6 to a proto_tree */
3193 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3194 gint length, const struct e_in6_addr *value_ptr)
3197 header_field_info *hfinfo;
3199 CHECK_FOR_NULL_TREE(tree);
3201 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3203 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
3205 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3206 proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
3212 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3213 gint start, gint length,
3214 const struct e_in6_addr *value_ptr,
3215 const char *format, ...)
3220 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3222 va_start(ap, format);
3223 proto_tree_set_representation_value(pi, format, ap);
3231 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3232 gint start, gint length,
3233 const struct e_in6_addr *value_ptr,
3234 const char *format, ...)
3239 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3241 TRY_TO_FAKE_THIS_REPR(pi);
3243 va_start(ap, format);
3244 proto_tree_set_representation(pi, format, ap);
3251 /* Set the FT_IPv6 value */
3253 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
3255 DISSECTOR_ASSERT(value_ptr != NULL);
3256 fvalue_set_bytes(&fi->value, value_ptr);
3260 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3262 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
3265 /* Set the FT_FCWWN value */
3267 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
3269 DISSECTOR_ASSERT(value_ptr != NULL);
3270 fvalue_set_bytes(&fi->value, value_ptr);
3274 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3276 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
3279 /* Add a FT_GUID to a proto_tree */
3281 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3282 gint length, const e_guid_t *value_ptr)
3285 header_field_info *hfinfo;
3287 CHECK_FOR_NULL_TREE(tree);
3289 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3291 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
3293 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3294 proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
3300 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3301 gint start, gint length,
3302 const e_guid_t *value_ptr,
3303 const char *format, ...)
3308 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3310 va_start(ap, format);
3311 proto_tree_set_representation_value(pi, format, ap);
3319 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3320 gint start, gint length, const e_guid_t *value_ptr,
3321 const char *format, ...)
3326 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3328 TRY_TO_FAKE_THIS_REPR(pi);
3330 va_start(ap, format);
3331 proto_tree_set_representation(pi, format, ap);
3338 /* Set the FT_GUID value */
3340 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
3342 DISSECTOR_ASSERT(value_ptr != NULL);
3343 fvalue_set_guid(&fi->value, value_ptr);
3347 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
3348 const guint encoding)
3352 tvb_get_guid(tvb, start, &guid, encoding);
3353 proto_tree_set_guid(fi, &guid);
3356 /* Add a FT_OID to a proto_tree */
3358 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3359 gint length, const guint8* value_ptr)
3362 header_field_info *hfinfo;
3364 CHECK_FOR_NULL_TREE(tree);
3366 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3368 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
3370 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3371 proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
3377 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3378 gint start, gint length,
3379 const guint8* value_ptr,
3380 const char *format, ...)
3385 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3387 va_start(ap, format);
3388 proto_tree_set_representation_value(pi, format, ap);
3396 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3397 gint start, gint length, const guint8* value_ptr,
3398 const char *format, ...)
3403 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3405 TRY_TO_FAKE_THIS_REPR(pi);
3407 va_start(ap, format);
3408 proto_tree_set_representation(pi, format, ap);
3415 /* Set the FT_OID value */
3417 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
3421 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3423 bytes = g_byte_array_new();
3425 g_byte_array_append(bytes, value_ptr, length);
3427 fvalue_set_byte_array(&fi->value, bytes);
3431 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3433 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
3436 /* Set the FT_SYSTEM_ID value */
3438 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
3442 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3444 bytes = g_byte_array_new();
3446 g_byte_array_append(bytes, value_ptr, length);
3448 fvalue_set_byte_array(&fi->value, bytes);
3452 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3454 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
3457 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
3458 * own copy of string, and frees it when the proto_tree is destroyed. */
3460 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3461 gint length, const char* value)
3464 header_field_info *hfinfo;
3466 CHECK_FOR_NULL_TREE(tree);
3468 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3470 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
3472 if (hfinfo->display == STR_UNICODE) {
3473 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
3476 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3477 DISSECTOR_ASSERT(length >= 0);
3478 proto_tree_set_string(PNODE_FINFO(pi), value);
3484 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3485 gint start, gint length, const char* value,
3492 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3494 va_start(ap, format);
3495 proto_tree_set_representation_value(pi, format, ap);
3503 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3504 gint start, gint length, const char* value,
3505 const char *format, ...)
3510 pi = proto_tree_add_string(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 /* Appends string data to a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD,
3523 * allowing progressive field info update instead of only updating the
3524 * representation as does proto_item_append_text()
3526 /* NOTE: this function will break with the TRY_TO_FAKE_THIS_ITEM()
3527 * speed optimization.
3528 * Currently only WSP use this function so it is not that bad but try to
3529 * avoid using this one if possible.
3530 * IF you must use this function you MUST also disable the
3531 * TRY_TO_FAKE_THIS_ITEM() optimization for your dissector/function
3532 * using proto_item_append_string().
3533 * Do that by faking that the tree is visible by calling
3534 * proto_tree_set_visible(tree, TRUE) (see packet-wsp.c)
3535 * BEFORE you create the item you are later going to use
3536 * proto_item_append_string() on.
3539 proto_item_append_string(proto_item *pi, const char *str)
3542 header_field_info *hfinfo;
3543 const gchar *old_str, *new_str;
3550 fi = PITEM_FINFO(pi);
3551 DISSECTOR_ASSERT_HINT(fi, "proto_tree_set_visible(tree, TRUE) should have been called previously");
3553 hfinfo = fi->hfinfo;
3554 if (hfinfo->type == FT_PROTOCOL) {
3555 /* TRY_TO_FAKE_THIS_ITEM() speed optimization: silently skip */
3558 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
3559 old_str = (guint8 *)fvalue_get(&fi->value);
3560 if (old_str && old_str[0])
3561 new_str = wmem_strconcat(wmem_packet_scope(), old_str, str, NULL);
3564 fvalue_set_string(&fi->value, new_str);
3567 /* Set the FT_STRING value */
3569 proto_tree_set_string(field_info *fi, const char* value)
3572 fvalue_set_string(&fi->value, value);
3574 fvalue_set_string(&fi->value, "[ Null ]");
3578 /* Set the FT_AX25 value */
3580 proto_tree_set_ax25(field_info *fi, const guint8* value)
3582 fvalue_set_bytes(&fi->value, value);
3586 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3588 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
3591 /* Set the FT_VINES value */
3593 proto_tree_set_vines(field_info *fi, const guint8* value)
3595 fvalue_set_bytes(&fi->value, value);
3599 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3601 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
3604 /* Add a FT_ETHER to a proto_tree */
3606 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3607 gint length, const guint8* value)
3610 header_field_info *hfinfo;
3612 CHECK_FOR_NULL_TREE(tree);
3614 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3616 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
3618 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3619 proto_tree_set_ether(PNODE_FINFO(pi), value);
3625 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3626 gint start, gint length, const guint8* value,
3627 const char *format, ...)
3632 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3634 va_start(ap, format);
3635 proto_tree_set_representation_value(pi, format, ap);
3643 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3644 gint start, gint length, const guint8* value,
3645 const char *format, ...)
3650 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3652 TRY_TO_FAKE_THIS_REPR(pi);
3654 va_start(ap, format);
3655 proto_tree_set_representation(pi, format, ap);
3662 /* Set the FT_ETHER value */
3664 proto_tree_set_ether(field_info *fi, const guint8* value)
3666 fvalue_set_bytes(&fi->value, value);
3670 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3672 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
3675 /* Add a FT_BOOLEAN to a proto_tree */
3677 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3678 gint length, guint32 value)
3681 header_field_info *hfinfo;
3683 CHECK_FOR_NULL_TREE(tree);
3685 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3687 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3689 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3690 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3696 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
3697 tvbuff_t *tvb, gint start, gint length,
3698 guint32 value, const char *format, ...)
3703 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3705 va_start(ap, format);
3706 proto_tree_set_representation_value(pi, format, ap);
3714 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3715 gint start, gint length, guint32 value,
3716 const char *format, ...)
3721 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3723 TRY_TO_FAKE_THIS_REPR(pi);
3725 va_start(ap, format);
3726 proto_tree_set_representation(pi, format, ap);
3734 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3735 gint length, guint64 value)
3738 header_field_info *hfinfo;
3740 CHECK_FOR_NULL_TREE(tree);
3742 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3744 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3746 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3747 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3752 /* Set the FT_BOOLEAN value */
3754 proto_tree_set_boolean(field_info *fi, guint64 value)
3756 proto_tree_set_uint64(fi, value);
3759 /* Generate, into "buf", a string showing the bits of a bitfield.
3760 Return a pointer to the character after that string. */
3761 /*XXX this needs a buf_len check */
3763 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3771 bit = G_GUINT64_CONSTANT(1) << (width - 1);
3774 /* This bit is part of the field. Show its value. */
3780 /* This bit is not part of the field. */
3795 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3799 p = other_decode_bitfield_value(buf, val, mask, width);
3800 p = g_stpcpy(p, " = ");
3805 /* Add a FT_FLOAT to a proto_tree */
3807 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3808 gint length, float value)
3811 header_field_info *hfinfo;
3813 CHECK_FOR_NULL_TREE(tree);
3815 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3817 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
3819 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3820 proto_tree_set_float(PNODE_FINFO(pi), value);
3826 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3827 gint start, gint length, float value,
3828 const char *format, ...)
3833 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3835 va_start(ap, format);
3836 proto_tree_set_representation_value(pi, format, ap);
3844 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3845 gint start, gint length, float value,
3846 const char *format, ...)
3851 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3853 TRY_TO_FAKE_THIS_REPR(pi);
3855 va_start(ap, format);
3856 proto_tree_set_representation(pi, format, ap);
3863 /* Set the FT_FLOAT value */
3865 proto_tree_set_float(field_info *fi, float value)
3867 fvalue_set_floating(&fi->value, value);
3870 /* Add a FT_DOUBLE to a proto_tree */
3872 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3873 gint length, double value)
3876 header_field_info *hfinfo;
3878 CHECK_FOR_NULL_TREE(tree);
3880 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3882 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
3884 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3885 proto_tree_set_double(PNODE_FINFO(pi), value);
3891 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3892 gint start, gint length, double value,
3893 const char *format, ...)
3898 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3900 va_start(ap, format);
3901 proto_tree_set_representation_value(pi, format, ap);
3909 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3910 gint start, gint length, double value,
3911 const char *format, ...)
3916 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3918 TRY_TO_FAKE_THIS_REPR(pi);
3920 va_start(ap, format);
3921 proto_tree_set_representation(pi, format, ap);
3928 /* Set the FT_DOUBLE value */
3930 proto_tree_set_double(field_info *fi, double value)
3932 fvalue_set_floating(&fi->value, value);
3935 /* Add FT_UINT{8,16,24,32} to a proto_tree */
3937 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3938 gint length, guint32 value)
3940 proto_item *pi = NULL;
3941 header_field_info *hfinfo;
3943 CHECK_FOR_NULL_TREE(tree);
3945 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3947 switch (hfinfo->type) {
3953 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3954 proto_tree_set_uint(PNODE_FINFO(pi), value);
3958 DISSECTOR_ASSERT_NOT_REACHED();
3965 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3966 gint start, gint length, guint32 value,
3967 const char *format, ...)
3972 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3974 va_start(ap, format);
3975 proto_tree_set_representation_value(pi, format, ap);
3983 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3984 gint start, gint length, guint32 value,
3985 const char *format, ...)
3990 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3992 TRY_TO_FAKE_THIS_REPR(pi);
3994 va_start(ap, format);
3995 proto_tree_set_representation(pi, format, ap);
4002 /* Set the FT_UINT{8,16,24,32} value */
4004 proto_tree_set_uint(field_info *fi, guint32 value)
4006 header_field_info *hfinfo;
4009 hfinfo = fi->hfinfo;
4012 if (hfinfo->bitmask) {
4013 /* Mask out irrelevant portions */
4014 integer &= (guint32)(hfinfo->bitmask);
4017 integer >>= hfinfo_bitshift(hfinfo);
4020 fvalue_set_uinteger(&fi->value, integer);
4023 /* Add FT_UINT{40,48,56,64} to a proto_tree */
4025 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4026 gint length, guint64 value)
4028 proto_item *pi = NULL;
4029 header_field_info *hfinfo;
4031 CHECK_FOR_NULL_TREE(tree);
4033 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4035 switch (hfinfo->type) {
4041 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4042 proto_tree_set_uint64(PNODE_FINFO(pi), value);
4046 DISSECTOR_ASSERT_NOT_REACHED();
4053 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4054 gint start, gint length, guint64 value,
4055 const char *format, ...)
4060 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4062 va_start(ap, format);
4063 proto_tree_set_representation_value(pi, format, ap);
4071 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4072 gint start, gint length, guint64 value,
4073 const char *format, ...)
4078 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4080 TRY_TO_FAKE_THIS_REPR(pi);
4082 va_start(ap, format);
4083 proto_tree_set_representation(pi, format, ap);
4090 /* Set the FT_UINT{40,48,56,64} value */
4092 proto_tree_set_uint64(field_info *fi, guint64 value)
4094 header_field_info *hfinfo;
4098 hfinfo = fi->hfinfo;
4101 if (hfinfo->bitmask) {
4102 /* Mask out irrelevant portions */
4103 integer &= hfinfo->bitmask;
4106 integer >>= hfinfo_bitshift(hfinfo);
4108 no_of_bits = ws_count_ones(hfinfo->bitmask);
4109 integer = ws_sign_ext64(integer, no_of_bits);
4112 fvalue_set_uinteger64(&fi->value, integer);
4115 /* Add FT_INT{8,16,24,32} to a proto_tree */
4117 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4118 gint length, gint32 value)
4120 proto_item *pi = NULL;
4121 header_field_info *hfinfo;
4123 CHECK_FOR_NULL_TREE(tree);
4125 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4127 switch (hfinfo->type) {
4132 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4133 proto_tree_set_int(PNODE_FINFO(pi), value);
4137 DISSECTOR_ASSERT_NOT_REACHED();
4144 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4145 gint start, gint length, gint32 value,
4146 const char *format, ...)
4151 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4153 va_start(ap, format);
4154 proto_tree_set_representation_value(pi, format, ap);
4162 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4163 gint start, gint length, gint32 value,
4164 const char *format, ...)
4169 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4171 TRY_TO_FAKE_THIS_REPR(pi);
4173 va_start(ap, format);
4174 proto_tree_set_representation(pi, format, ap);
4181 /* Set the FT_INT{8,16,24,32} value */
4183 proto_tree_set_int(field_info *fi, gint32 value)
4185 header_field_info *hfinfo;
4189 hfinfo = fi->hfinfo;
4190 integer = (guint32) value;
4192 if (hfinfo->bitmask) {
4193 /* Mask out irrelevant portions */
4194 integer &= (guint32)(hfinfo->bitmask);
4197 integer >>= hfinfo_bitshift(hfinfo);
4199 no_of_bits = ws_count_ones(hfinfo->bitmask);
4200 integer = ws_sign_ext32(integer, no_of_bits);
4203 fvalue_set_sinteger(&fi->value, integer);
4206 /* Add FT_INT{40,48,56,64} to a proto_tree */
4208 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4209 gint length, gint64 value)
4211 proto_item *pi = NULL;
4212 header_field_info *hfinfo;
4214 CHECK_FOR_NULL_TREE(tree);
4216 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4218 switch (hfinfo->type) {
4223 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4224 proto_tree_set_int64(PNODE_FINFO(pi), value);
4228 DISSECTOR_ASSERT_NOT_REACHED();
4235 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4236 gint start, gint length, gint64 value,
4237 const char *format, ...)
4242 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4244 va_start(ap, format);
4245 proto_tree_set_representation_value(pi, format, ap);
4252 /* Set the FT_INT{40,48,56,64} value */
4254 proto_tree_set_int64(field_info *fi, gint64 value)
4256 header_field_info *hfinfo;
4260 hfinfo = fi->hfinfo;
4263 if (hfinfo->bitmask) {
4264 /* Mask out irrelevant portions */
4265 integer &= hfinfo->bitmask;
4268 integer >>= hfinfo_bitshift(hfinfo);
4270 no_of_bits = ws_count_ones(hfinfo->bitmask);
4271 integer = ws_sign_ext64(integer, no_of_bits);
4274 fvalue_set_sinteger64(&fi->value, integer);
4278 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4279 gint start, gint length, gint64 value,
4280 const char *format, ...)
4285 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4287 TRY_TO_FAKE_THIS_REPR(pi);
4289 va_start(ap, format);
4290 proto_tree_set_representation(pi, format, ap);
4297 /* Add a FT_EUI64 to a proto_tree */
4299 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4300 gint length, const guint64 value)
4303 header_field_info *hfinfo;
4305 CHECK_FOR_NULL_TREE(tree);
4307 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4309 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
4311 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4312 proto_tree_set_eui64(PNODE_FINFO(pi), value);
4318 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4319 gint start, gint length, const guint64 value,
4320 const char *format, ...)
4325 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4327 va_start(ap, format);
4328 proto_tree_set_representation_value(pi, format, ap);
4336 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4337 gint start, gint length, const guint64 value,
4338 const char *format, ...)
4343 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4345 TRY_TO_FAKE_THIS_REPR(pi);
4347 va_start(ap, format);
4348 proto_tree_set_representation(pi, format, ap);
4355 /* Set the FT_EUI64 value */
4357 proto_tree_set_eui64(field_info *fi, const guint64 value)
4359 fvalue_set_uinteger64(&fi->value, value);
4362 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
4366 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
4368 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
4372 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
4374 proto_tree_add_node(proto_tree *tree, field_info *fi)
4376 proto_node *pnode, *tnode, *sibling;
4380 * Make sure "tree" is ready to have subtrees under it, by
4381 * checking whether it's been given an ett_ value.
4383 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
4384 * node of the protocol tree. That node is not displayed,
4385 * so it doesn't need an ett_ value to remember whether it
4389 tfi = PNODE_FINFO(tnode);
4390 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
4391 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4392 "\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
4393 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
4394 /* XXX - is it safe to continue here? */
4397 pnode = wmem_new(PNODE_POOL(tree), proto_node);
4398 PROTO_NODE_INIT(pnode);
4399 pnode->parent = tnode;
4400 PNODE_FINFO(pnode) = fi;
4401 pnode->tree_data = PTREE_DATA(tree);
4403 if (tnode->last_child != NULL) {
4404 sibling = tnode->last_child;
4405 DISSECTOR_ASSERT(sibling->next == NULL);
4406 sibling->next = pnode;
4408 tnode->first_child = pnode;
4409 tnode->last_child = pnode;
4411 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
4413 return (proto_item *)pnode;
4417 /* Generic way to allocate field_info and add to proto_tree.
4418 * Sets *pfi to address of newly-allocated field_info struct */
4420 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
4427 get_hfi_length(hfinfo, tvb, start, length, &item_length);
4428 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4429 pi = proto_tree_add_node(tree, fi);
4436 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
4439 gint length_remaining;
4442 * We only allow a null tvbuff if the item has a zero length,
4443 * i.e. if there's no data backing it.
4445 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
4448 * XXX - in some protocols, there are 32-bit unsigned length
4449 * fields, so lengths in protocol tree and tvbuff routines
4450 * should really be unsigned. We should have, for those
4451 * field types for which "to the end of the tvbuff" makes sense,
4452 * additional routines that take no length argument and
4453 * add fields that run to the end of the tvbuff.
4455 if (*length == -1) {
4457 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
4458 * FT_STRINGZPAD fields, a length of -1 means "set the
4459 * length to what remains in the tvbuff".
4461 * The assumption is either that
4463 * 1) the length of the item can only be determined
4464 * by dissection (typically true of items with
4465 * subitems, which are probably FT_NONE or
4470 * 2) if the tvbuff is "short" (either due to a short
4471 * snapshot length or due to lack of reassembly of
4472 * fragments/segments/whatever), we want to display
4473 * what's available in the field (probably FT_BYTES
4474 * or FT_STRING) and then throw an exception later
4478 * 3) the field is defined to be "what's left in the
4481 * so we set the length to what remains in the tvbuff so
4482 * that, if we throw an exception while dissecting, it
4483 * has what is probably the right value.
4485 * For FT_STRINGZ, it means "the string is null-terminated,
4486 * not null-padded; set the length to the actual length
4487 * of the string", and if the tvbuff if short, we just
4488 * throw an exception.
4490 * It's not valid for any other type of field. For those
4491 * fields, we treat -1 the same way we treat other
4492 * negative values - we assume the length is a Really
4493 * Big Positive Number, and throw a ReportedBoundsError
4494 * exception, under the assumption that the Really Big
4495 * Length would run past the end of the packet.
4497 switch (hfinfo->type) {
4505 * We allow FT_PROTOCOLs to be zero-length -
4506 * for example, an ONC RPC NULL procedure has
4507 * neither arguments nor reply, so the
4508 * payload for that protocol is empty.
4510 * We also allow the others to be zero-length -
4511 * because that's the way the code has been for a
4514 * However, we want to ensure that the start
4515 * offset is not *past* the byte past the end
4516 * of the tvbuff: we throw an exception in that
4519 *length = tvb_ensure_captured_length_remaining(tvb, start);
4520 DISSECTOR_ASSERT(*length >= 0);
4525 * Leave the length as -1, so our caller knows
4531 THROW(ReportedBoundsError);
4532 DISSECTOR_ASSERT_NOT_REACHED();
4534 *item_length = *length;
4536 *item_length = *length;
4537 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
4539 * These types are for interior nodes of the
4540 * tree, and don't have data associated with
4541 * them; if the length is negative (XXX - see
4542 * above) or goes past the end of the tvbuff,
4543 * cut it short at the end of the tvbuff.
4544 * That way, if this field is selected in
4545 * Wireshark, we don't highlight stuff past
4546 * the end of the data.
4548 /* XXX - what to do, if we don't have a tvb? */
4550 length_remaining = tvb_captured_length_remaining(tvb, start);
4551 if (*item_length < 0 ||
4552 (*item_length > 0 &&
4553 (length_remaining < *item_length)))
4554 *item_length = length_remaining;
4557 if (*item_length < 0) {
4558 THROW(ReportedBoundsError);
4564 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
4565 gint length, guint item_length, const gint encoding)
4570 * We need to get the correct item length here.
4571 * That's normally done by proto_tree_new_item(),
4572 * but we won't be calling it.
4574 switch (hfinfo->type) {
4580 * The length is the specified length.
4586 * Map all non-zero values to little-endian for
4587 * backwards compatibility.
4589 n = get_uint_value(NULL, tvb, start, length,
4590 encoding ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
4595 /* XXX - make these just FT_UINT? */
4604 /* XXX - make these just FT_INT? */
4629 * The length is the specified length.
4635 report_type_length_mismatch(NULL, "a string", length, TRUE);
4638 /* This can throw an exception */
4639 /* XXX - do this without fetching the string? */
4640 tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
4642 item_length = length;
4645 case FT_UINT_STRING:
4646 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
4651 case FT_ABSOLUTE_TIME:
4652 case FT_RELATIVE_TIME:
4653 case FT_IEEE_11073_SFLOAT:
4654 case FT_IEEE_11073_FLOAT:
4656 * The length is the specified length.
4661 g_error("hfinfo->type %d (%s) not handled\n",
4663 ftype_name(hfinfo->type));
4664 DISSECTOR_ASSERT_NOT_REACHED();
4671 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4672 const gint start, const gint item_length)
4676 FIELD_INFO_NEW(PNODE_POOL(tree), fi);
4678 fi->hfinfo = hfinfo;
4680 fi->start += (tvb)?tvb_raw_offset(tvb):0;
4681 fi->length = item_length;
4684 if (!PTREE_DATA(tree)->visible)
4685 FI_SET_FLAG(fi, FI_HIDDEN);
4686 fvalue_init(&fi->value, fi->hfinfo->type);
4689 /* add the data source tvbuff */
4690 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
4692 fi->appendix_start = 0;
4693 fi->appendix_length = 0;
4698 /* If the protocol tree is to be visible, set the representation of a
4699 proto_tree entry with the name of the field for the item and with
4700 the value formatted with the supplied printf-style format and
4703 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
4707 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
4708 * items string representation */
4709 if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
4711 field_info *fi = PITEM_FINFO(pi);
4712 header_field_info *hf;
4714 DISSECTOR_ASSERT(fi);
4718 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4719 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
4723 if (IS_FT_UINT(hf->type))
4724 val = fvalue_get_uinteger(&fi->value);
4726 val = fvalue_get_uinteger64(&fi->value);
4728 val <<= hfinfo_bitshift(hf);
4730 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
4731 ret = (int) (p - fi->rep->representation);
4734 /* put in the hf name */
4735 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
4737 /* If possible, Put in the value of the string */
4738 if (ret < ITEM_LABEL_LENGTH) {
4739 ret += g_vsnprintf(fi->rep->representation + ret,
4740 ITEM_LABEL_LENGTH - ret, format, ap);
4742 if (ret >= ITEM_LABEL_LENGTH) {
4743 /* Uh oh, we don't have enough room. Tell the user
4744 * that the field is truncated.
4746 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4751 /* If the protocol tree is to be visible, set the representation of a
4752 proto_tree entry with the representation formatted with the supplied
4753 printf-style format and argument list. */
4755 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
4757 int ret; /*tmp return value */
4758 field_info *fi = PITEM_FINFO(pi);
4760 DISSECTOR_ASSERT(fi);
4762 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4763 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4764 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
4766 if (ret >= ITEM_LABEL_LENGTH) {
4767 /* Uh oh, we don't have enough room. Tell the user
4768 * that the field is truncated.
4770 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4776 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
4778 switch (hfinfo->display) {
4780 return format_text(string, strlen(string));
4783 return format_text_wsp(string, strlen(string));
4786 /* XXX, format_unicode_text() */
4790 return format_text(string, strlen(string));
4794 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
4796 gsize res = g_strlcpy(dest, src, dest_size);
4798 if (res > dest_size)
4803 static header_field_info *
4804 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
4806 header_field_info *dup_hfinfo;
4808 if (hfinfo->same_name_prev_id == -1)
4810 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
4815 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
4817 g_free(last_field_name);
4818 last_field_name = NULL;
4820 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
4821 /* No hfinfo with the same name */
4822 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
4826 if (hfinfo->same_name_next) {
4827 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
4830 if (hfinfo->same_name_prev_id != -1) {
4831 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
4832 same_name_prev->same_name_next = hfinfo->same_name_next;
4833 if (!hfinfo->same_name_next) {
4834 /* It's always the latest added hfinfo which is stored in gpa_name_map */
4835 g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
4840 /* -------------------------- */
4842 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
4843 gchar *result, gchar *expr, const int size)
4848 ipv4_addr_and_mask *ipv4;
4849 struct e_in6_addr *ipv6;
4851 guint32 n_addr; /* network-order IPv4 address */
4853 const true_false_string *tfstring;
4855 int len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
4857 field_info *finfo = NULL;
4858 header_field_info* hfinfo;
4859 const gchar *abbrev = NULL;
4861 const char *hf_str_val;
4862 char number_buf[48];
4863 const char *number_out;
4869 g_assert(field_ids != NULL);
4870 while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
4871 field_id = *field_idx;
4872 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
4874 /* do we need to rewind ? */
4878 if (occurrence < 0) {
4879 /* Search other direction */
4880 while (hfinfo->same_name_prev_id != -1) {
4881 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
4886 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
4888 if (!finfos || !(len = g_ptr_array_len(finfos))) {
4889 if (occurrence < 0) {
4890 hfinfo = hfinfo->same_name_next;
4892 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4897 /* Are there enough occurrences of the field? */
4898 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
4899 if (occurrence < 0) {
4900 hfinfo = hfinfo->same_name_next;
4902 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4908 /* Calculate single index or set outer bounderies */
4909 if (occurrence < 0) {
4910 i = occurrence + len + prev_len;
4912 } else if (occurrence > 0) {
4913 i = occurrence - 1 - prev_len;
4920 prev_len += len; /* Count handled occurrences */
4923 finfo = (field_info *)g_ptr_array_index(finfos, i);
4925 if (offset_r && (offset_r < (size - 2)))
4926 result[offset_r++] = ',';
4928 if (offset_e && (offset_e < (size - 2)))
4929 expr[offset_e++] = ',';
4931 switch (hfinfo->type) {
4933 case FT_NONE: /* Nothing to add */
4934 if (offset_r == 0) {
4936 } else if (result[offset_r-1] == ',') {
4937 result[offset_r-1] = '\0';
4942 /* prevent multiple "yes" entries by setting result directly */
4943 g_strlcpy(result, "Yes", size);
4948 bytes = (guint8 *)fvalue_get(&finfo->value);
4950 switch(hfinfo->display)
4953 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
4956 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
4959 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
4962 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
4966 if (prefs.display_byte_fields_with_spaces)
4968 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
4972 str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
4976 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
4977 wmem_free(NULL, str);
4980 if (hfinfo->display & BASE_ALLOW_ZERO) {
4981 offset_r += protoo_strlcpy(result+offset_r, "<none>", size-offset_r);
4983 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
4988 case FT_ABSOLUTE_TIME:
4989 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
4990 offset_r += protoo_strlcpy(result+offset_r,
4993 wmem_free(NULL, tmpbuf);
4996 case FT_RELATIVE_TIME:
4997 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
4998 offset_r += protoo_strlcpy(result+offset_r,
5001 wmem_free(NULL, tmpbuf);
5005 number64 = fvalue_get_uinteger64(&finfo->value);
5006 tfstring = (const true_false_string *)&tfs_true_false;
5007 if (hfinfo->strings) {
5008 tfstring = (const struct true_false_string*) hfinfo->strings;
5010 offset_r += protoo_strlcpy(result+offset_r,
5012 tfstring->true_string :
5013 tfstring->false_string, size-offset_r);
5015 offset_e += protoo_strlcpy(expr+offset_e,
5016 number64 ? "1" : "0", size-offset_e);
5019 /* XXX - make these just FT_NUMBER? */
5030 number = IS_FT_INT(hfinfo->type) ?
5031 (guint32) fvalue_get_sinteger(&finfo->value) :
5032 fvalue_get_uinteger(&finfo->value);
5034 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5035 gchar tmp[ITEM_LABEL_LENGTH];
5036 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5038 DISSECTOR_ASSERT(fmtfunc);
5039 fmtfunc(tmp, number);
5041 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5043 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
5044 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5047 number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
5049 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5052 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
5054 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5057 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5058 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5060 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5062 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5065 offset_e = (int)strlen(expr);
5077 number64 = IS_FT_INT(hfinfo->type) ?
5078 (guint64) fvalue_get_sinteger64(&finfo->value) :
5079 fvalue_get_uinteger64(&finfo->value);
5081 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5082 gchar tmp[ITEM_LABEL_LENGTH];
5083 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
5085 DISSECTOR_ASSERT(fmtfunc64);
5086 fmtfunc64(tmp, number64);
5087 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5088 } else if (hfinfo->strings) {
5089 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
5092 number_out = hfinfo_number_value_format_display64(hfinfo, BASE_DEC, number_buf, number64);
5094 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5097 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
5099 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5102 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5103 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5105 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
5107 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5110 offset_e = (int)strlen(expr);
5114 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
5115 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5116 wmem_free(NULL, str);
5120 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&finfo->value);
5121 n_addr = ipv4_get_net_order_addr(ipv4);
5122 set_address (&addr, AT_IPv4, 4, &n_addr);
5123 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5124 offset_r = (int)strlen(result);
5128 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
5129 set_address (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
5130 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5131 offset_r = (int)strlen(result);
5135 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
5136 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5137 offset_r = (int)strlen(result);
5141 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
5142 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5143 offset_r = (int)strlen(result);
5147 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
5148 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5149 wmem_free(NULL, str);
5153 bytes = (guint8 *)fvalue_get(&finfo->value);
5154 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5155 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5156 wmem_free(NULL, str);
5158 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5159 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5160 wmem_free(NULL, str);
5164 bytes = (guint8 *)fvalue_get(&finfo->value);
5165 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5166 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5167 wmem_free(NULL, str);
5169 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5170 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5171 wmem_free(NULL, str);
5175 bytes = (guint8 *)fvalue_get(&finfo->value);
5176 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
5177 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5178 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5179 wmem_free(NULL, str);
5183 g_snprintf(result+offset_r, size-offset_r,
5184 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
5185 offset_r = (int)strlen(result);
5189 g_snprintf(result+offset_r, size-offset_r,
5190 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
5191 offset_r = (int)strlen(result);
5196 case FT_UINT_STRING:
5198 bytes = (guint8 *)fvalue_get(&finfo->value);
5199 offset_r += protoo_strlcpy(result+offset_r,
5200 hfinfo_format_text(hfinfo, bytes),
5204 case FT_IEEE_11073_SFLOAT:
5207 fvalue_to_string_repr(&finfo->value, FTREPR_DISPLAY, hfinfo->display, buf);
5208 g_snprintf(result+offset_r, size-offset_r,
5212 offset_r = (int)strlen(result);
5215 case FT_IEEE_11073_FLOAT:
5218 fvalue_to_string_repr(&finfo->value, FTREPR_DISPLAY, hfinfo->display, buf);
5219 g_snprintf(result+offset_r, size-offset_r,
5223 offset_r = (int)strlen(result);
5226 case FT_IPXNET: /*XXX really No column custom ?*/
5229 g_error("hfinfo->type %d (%s) not handled\n",
5231 ftype_name(hfinfo->type));
5232 DISSECTOR_ASSERT_NOT_REACHED();
5238 switch (hfinfo->type) {
5261 /* for these types, "expr" is filled in the loop above */
5265 /* for all others, just copy "result" to "expr" */
5266 g_strlcpy(expr, result, size);
5271 /* Store abbrev for return value */
5272 abbrev = hfinfo->abbrev;
5275 if (occurrence == 0) {
5276 /* Fetch next hfinfo with same name (abbrev) */
5277 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5284 return abbrev ? abbrev : "";
5288 /* Set text of proto_item after having already been created. */
5290 proto_item_set_text(proto_item *pi, const char *format, ...)
5292 field_info *fi = NULL;
5295 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5297 fi = PITEM_FINFO(pi);
5302 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
5306 va_start(ap, format);
5307 proto_tree_set_representation(pi, format, ap);
5311 /* Append to text of proto_item after having already been created. */
5313 proto_item_append_text(proto_item *pi, const char *format, ...)
5315 field_info *fi = NULL;
5319 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5321 fi = PITEM_FINFO(pi);
5326 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5328 * If we don't already have a representation,
5329 * generate the default representation.
5331 if (fi->rep == NULL) {
5332 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5333 proto_item_fill_label(fi, fi->rep->representation);
5336 curlen = strlen(fi->rep->representation);
5337 if (ITEM_LABEL_LENGTH > curlen) {
5338 va_start(ap, format);
5339 g_vsnprintf(fi->rep->representation + curlen,
5340 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
5346 /* Prepend to text of proto_item after having already been created. */
5348 proto_item_prepend_text(proto_item *pi, const char *format, ...)
5350 field_info *fi = NULL;
5351 char representation[ITEM_LABEL_LENGTH];
5354 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5356 fi = PITEM_FINFO(pi);
5361 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5363 * If we don't already have a representation,
5364 * generate the default representation.
5366 if (fi->rep == NULL) {
5367 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5368 proto_item_fill_label(fi, representation);
5370 g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
5372 va_start(ap, format);
5373 g_vsnprintf(fi->rep->representation,
5374 ITEM_LABEL_LENGTH, format, ap);
5376 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
5381 proto_item_set_len(proto_item *pi, const gint length)
5385 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5387 fi = PITEM_FINFO(pi);
5391 DISSECTOR_ASSERT(length >= 0);
5392 fi->length = length;
5395 * You cannot just make the "len" field of a GByteArray
5396 * larger, if there's no data to back that length;
5397 * you can only make it smaller.
5399 if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
5400 fi->value.value.bytes->len = length;
5404 * Sets the length of the item based on its start and on the specified
5405 * offset, which is the offset past the end of the item; as the start
5406 * in the item is relative to the beginning of the data source tvbuff,
5407 * we need to pass in a tvbuff - the end offset is relative to the beginning
5411 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
5415 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5417 fi = PITEM_FINFO(pi);
5421 end += tvb_raw_offset(tvb);
5422 DISSECTOR_ASSERT(end >= fi->start);
5423 fi->length = end - fi->start;
5427 proto_item_get_len(const proto_item *pi)
5429 field_info *fi = PITEM_FINFO(pi);
5430 return fi ? fi->length : -1;
5434 proto_tree_create_root(packet_info *pinfo)
5438 /* Initialize the proto_node */
5439 pnode = g_slice_new(proto_tree);
5440 PROTO_NODE_INIT(pnode);
5441 pnode->parent = NULL;
5442 PNODE_FINFO(pnode) = NULL;
5443 pnode->tree_data = g_slice_new(tree_data_t);
5445 /* Make sure we can access pinfo everywhere */
5446 pnode->tree_data->pinfo = pinfo;
5448 /* Don't initialize the tree_data_t. Wait until we know we need it */
5449 pnode->tree_data->interesting_hfids = NULL;
5451 /* Set the default to FALSE so it's easier to
5452 * find errors; if we expect to see the protocol tree
5453 * but for some reason the default 'visible' is not
5454 * changed, then we'll find out very quickly. */
5455 pnode->tree_data->visible = FALSE;
5457 /* Make sure that we fake protocols (if possible) */
5458 pnode->tree_data->fake_protocols = TRUE;
5460 /* Keep track of the number of children */
5461 pnode->tree_data->count = 0;
5463 return (proto_tree *)pnode;
5467 /* "prime" a proto_tree with a single hfid that a dfilter
5468 * is interested in. */
5470 proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
5472 header_field_info *hfinfo;
5474 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
5475 /* this field is referenced by a filter so increase the refcount.
5476 also increase the refcount for the parent, i.e the protocol.
5478 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
5479 /* only increase the refcount if there is a parent.
5480 if this is a protocol and not a field then parent will be -1
5481 and there is no parent to add any refcounting for.
5483 if (hfinfo->parent != -1) {
5484 header_field_info *parent_hfinfo;
5485 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
5487 /* Mark parent as indirectly referenced unless it is already directly
5488 * referenced, i.e. the user has specified the parent in a filter.
5490 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
5491 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
5496 proto_item_add_subtree(proto_item *pi, const gint idx) {
5502 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
5504 fi = PITEM_FINFO(pi);
5506 return (proto_tree *)pi;
5508 fi->tree_type = idx;
5510 return (proto_tree *)pi;
5514 proto_item_get_subtree(proto_item *pi) {
5519 fi = PITEM_FINFO(pi);
5520 if ( (!fi) || (fi->tree_type == -1) )
5522 return (proto_tree *)pi;
5526 proto_item_get_parent(const proto_item *ti) {
5533 proto_item_get_parent_nth(proto_item *ti, int gen) {
5546 proto_tree_get_parent(proto_tree *tree) {
5549 return (proto_item *)tree;
5553 proto_tree_get_parent_tree(proto_tree *tree) {
5557 /* we're the root tree, there's no parent
5558 return ourselves so the caller has at least a tree to attach to */
5562 return (proto_tree *)tree->parent;
5566 proto_tree_get_root(proto_tree *tree) {
5569 while (tree->parent) {
5570 tree = tree->parent;
5576 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
5577 proto_item *item_to_move)
5580 /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
5581 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
5583 /* This function doesn't generate any values. It only reorganizes the prococol tree
5584 * so we can bail out immediately if it isn't visible. */
5585 if (!tree || !PTREE_DATA(tree)->visible)
5588 DISSECTOR_ASSERT(item_to_move->parent == tree);
5589 DISSECTOR_ASSERT(fixed_item->parent == tree);
5591 /*** cut item_to_move out ***/
5593 /* is item_to_move the first? */
5594 if (tree->first_child == item_to_move) {
5595 /* simply change first child to next */
5596 tree->first_child = item_to_move->next;
5598 DISSECTOR_ASSERT(tree->last_child != item_to_move);
5600 proto_item *curr_item;
5601 /* find previous and change it's next */
5602 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
5603 if (curr_item->next == item_to_move) {
5608 DISSECTOR_ASSERT(curr_item);
5610 curr_item->next = item_to_move->next;
5612 /* fix last_child if required */
5613 if (tree->last_child == item_to_move) {
5614 tree->last_child = curr_item;
5618 /*** insert to_move after fixed ***/
5619 item_to_move->next = fixed_item->next;
5620 fixed_item->next = item_to_move;
5621 if (tree->last_child == fixed_item) {
5622 tree->last_child = item_to_move;
5627 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
5635 fi = PTREE_FINFO(tree);
5639 start += tvb_raw_offset(tvb);
5640 DISSECTOR_ASSERT(start >= 0);
5641 DISSECTOR_ASSERT(length >= 0);
5643 fi->appendix_start = start;
5644 fi->appendix_length = length;
5648 proto_register_protocol(const char *name, const char *short_name,
5649 const char *filter_name)
5651 protocol_t *protocol;
5652 const protocol_t *existing_protocol = NULL;
5653 header_field_info *hfinfo;
5655 const char *existing_name;
5659 gboolean found_invalid;
5662 * Make sure there's not already a protocol with any of those
5663 * names. Crash if there is, as that's an error in the code
5664 * or an inappropriate plugin.
5665 * This situation has to be fixed to not register more than one
5666 * protocol with the same name.
5668 * This is done by reducing the number of strcmp (and alike) calls
5669 * as much as possible, as this significally slows down startup time.
5671 * Drawback: As a hash value is used to reduce insert time,
5672 * this might lead to a hash collision.
5673 * However, although we have somewhat over 1000 protocols, we're using
5674 * a 32 bit int so this is very, very unlikely.
5677 key = (gint *)g_malloc (sizeof(gint));
5678 *key = wrs_str_hash(name);
5680 existing_name = (const char *)g_hash_table_lookup(proto_names, key);
5681 if (existing_name != NULL) {
5682 /* g_error will terminate the program */
5683 g_error("Duplicate protocol name \"%s\"!"
5684 " This might be caused by an inappropriate plugin or a development error.", name);
5686 g_hash_table_insert(proto_names, key, (gpointer)name);
5688 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5689 if (existing_protocol != NULL) {
5690 g_error("Duplicate protocol short_name \"%s\"!"
5691 " This might be caused by an inappropriate plugin or a development error.", short_name);
5694 found_invalid = FALSE;
5695 for (i = 0; filter_name[i]; i++) {
5697 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
5698 found_invalid = TRUE;
5701 if (found_invalid) {
5702 g_error("Protocol filter name \"%s\" has one or more invalid characters."
5703 " Allowed are lower characters, digits, '-', '_' and '.'."
5704 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5706 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5707 if (existing_protocol != NULL) {
5708 g_error("Duplicate protocol filter_name \"%s\"!"
5709 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5712 /* Add this protocol to the list of known protocols; the list
5713 is sorted by protocol short name. */
5714 protocol = g_new(protocol_t, 1);
5715 protocol->name = name;
5716 protocol->short_name = short_name;
5717 protocol->filter_name = filter_name;
5718 protocol->fields = g_ptr_array_new();
5719 protocol->is_enabled = TRUE; /* protocol is enabled by default */
5720 protocol->can_toggle = TRUE;
5721 protocol->heur_list = NULL;
5722 /* list will be sorted later by name, when all protocols completed registering */
5723 protocols = g_list_prepend(protocols, protocol);
5724 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
5725 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
5727 /* Here we allocate a new header_field_info struct */
5728 hfinfo = g_slice_new(header_field_info);
5729 hfinfo->name = name;
5730 hfinfo->abbrev = filter_name;
5731 hfinfo->type = FT_PROTOCOL;
5732 hfinfo->display = BASE_NONE;
5733 hfinfo->strings = protocol;
5734 hfinfo->bitmask = 0;
5735 hfinfo->ref_type = HF_REF_TYPE_NONE;
5736 hfinfo->blurb = NULL;
5737 hfinfo->parent = -1; /* this field differentiates protos and fields */
5739 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
5740 protocol->proto_id = proto_id;
5745 proto_deregister_protocol(const char *short_name)
5747 protocol_t *protocol;
5748 header_field_info *hfinfo;
5753 proto_id = proto_get_id_by_short_name(short_name);
5754 protocol = find_protocol_by_id(proto_id);
5755 if (protocol == NULL)
5758 key = wrs_str_hash(protocol->name);
5759 g_hash_table_remove(proto_names, &key);
5761 g_hash_table_remove(proto_short_names, (gpointer)short_name);
5762 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
5764 for (i = 0; i < protocol->fields->len; i++) {
5765 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
5766 hfinfo_remove_from_gpa_name_map(hfinfo);
5767 expert_deregister_expertinfo(hfinfo->abbrev);
5768 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
5770 g_ptr_array_free(protocol->fields, TRUE);
5771 protocol->fields = NULL;
5773 /* Remove this protocol from the list of known protocols */
5774 protocols = g_list_remove(protocols, protocol);
5776 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
5777 g_hash_table_steal(gpa_name_map, protocol->filter_name);
5779 g_free(last_field_name);
5780 last_field_name = NULL;
5786 * Routines to use to iterate over the protocols.
5787 * The argument passed to the iterator routines is an opaque cookie to
5788 * their callers; it's the GList pointer for the current element in
5790 * The ID of the protocol is returned, or -1 if there is no protocol.
5793 proto_get_first_protocol(void **cookie)
5795 protocol_t *protocol;
5797 if (protocols == NULL)
5799 *cookie = protocols;
5800 protocol = (protocol_t *)protocols->data;
5801 return protocol->proto_id;
5805 proto_get_data_protocol(void *cookie)
5807 GList *list_item = (GList *)cookie;
5809 protocol_t *protocol = (protocol_t *)list_item->data;
5810 return protocol->proto_id;
5814 proto_get_next_protocol(void **cookie)
5816 GList *list_item = (GList *)*cookie;
5817 protocol_t *protocol;
5819 list_item = g_list_next(list_item);
5820 if (list_item == NULL)
5822 *cookie = list_item;
5823 protocol = (protocol_t *)list_item->data;
5824 return protocol->proto_id;
5827 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
5828 assume that the cookie stored by
5829 proto_get_(first|next)_protocol_field() will never have a
5830 value of NULL. So, to preserve this semantic, the cookie value
5831 below is adjusted so that the cookie value stored is 1 + the
5832 current (zero-based) array index.
5835 proto_get_first_protocol_field(const int proto_id, void **cookie)
5837 protocol_t *protocol = find_protocol_by_id(proto_id);
5839 if ((protocol == NULL) || (protocol->fields->len == 0))
5842 *cookie = GUINT_TO_POINTER(0 + 1);
5843 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
5847 proto_get_next_protocol_field(const int proto_id, void **cookie)
5849 protocol_t *protocol = find_protocol_by_id(proto_id);
5850 guint i = GPOINTER_TO_UINT(*cookie) - 1;
5854 if (i >= protocol->fields->len)
5857 *cookie = GUINT_TO_POINTER(i + 1);
5858 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
5862 find_protocol_by_id(const int proto_id)
5864 header_field_info *hfinfo;
5869 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
5870 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
5871 return (protocol_t *)hfinfo->strings;
5875 proto_get_id(const protocol_t *protocol)
5877 return protocol->proto_id;
5881 proto_name_already_registered(const gchar *name)
5885 DISSECTOR_ASSERT_HINT(name, "No name present");
5887 key = wrs_str_hash(name);
5888 if (g_hash_table_lookup(proto_names, &key) != NULL)
5894 proto_get_id_by_filter_name(const gchar *filter_name)
5896 const protocol_t *protocol = NULL;
5898 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
5900 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5902 if (protocol == NULL)
5904 return protocol->proto_id;
5908 proto_get_id_by_short_name(const gchar *short_name)
5910 const protocol_t *protocol = NULL;
5912 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
5914 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5916 if (protocol == NULL)
5918 return protocol->proto_id;
5922 proto_get_protocol_name(const int proto_id)
5924 protocol_t *protocol;
5926 protocol = find_protocol_by_id(proto_id);
5928 if (protocol == NULL)
5930 return protocol->name;
5934 proto_get_protocol_short_name(const protocol_t *protocol)
5936 if (protocol == NULL)
5938 return protocol->short_name;
5942 proto_get_protocol_long_name(const protocol_t *protocol)
5944 if (protocol == NULL)
5946 return protocol->name;
5950 proto_get_protocol_filter_name(const int proto_id)
5952 protocol_t *protocol;
5954 protocol = find_protocol_by_id(proto_id);
5955 if (protocol == NULL)
5957 return protocol->filter_name;
5960 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
5962 heur_dtbl_entry_t* heuristic_dissector;
5964 if (protocol == NULL)
5967 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
5968 if (heuristic_dissector != NULL)
5970 protocol->heur_list = g_list_append (protocol->heur_list, heuristic_dissector);
5974 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
5976 if (protocol == NULL)
5979 g_list_foreach(protocol->heur_list, func, user_data);
5983 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
5984 gboolean *is_tcp, gboolean *is_udp,
5985 gboolean *is_sctp, gboolean *is_ssl,
5987 gboolean *is_lte_rlc)
5989 wmem_list_frame_t *protos = wmem_list_head(layers);
5991 const char *proto_name;
5993 /* Walk the list of a available protocols in the packet and
5994 find "major" ones. */
5995 /* It might make more sense to assemble and return a bitfield. */
5996 while (protos != NULL)
5998 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
5999 proto_name = proto_get_protocol_filter_name(proto_id);
6001 if (is_ip && ((!strcmp(proto_name, "ip")) ||
6002 (!strcmp(proto_name, "ipv6")))) {
6004 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
6006 } else if (is_udp && !strcmp(proto_name, "udp")) {
6008 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
6010 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
6012 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
6014 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
6018 protos = wmem_list_frame_next(protos);
6023 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
6025 wmem_list_frame_t *protos = wmem_list_head(layers);
6029 /* Walk the list of a available protocols in the packet and
6030 find "major" ones. */
6031 /* It might make more sense to assemble and return a bitfield. */
6032 while (protos != NULL)
6034 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6035 name = proto_get_protocol_filter_name(proto_id);
6037 if (!strcmp(name, proto_name))
6042 protos = wmem_list_frame_next(protos);
6050 proto_is_protocol_enabled(const protocol_t *protocol)
6052 return protocol->is_enabled;
6056 proto_can_toggle_protocol(const int proto_id)
6058 protocol_t *protocol;
6060 protocol = find_protocol_by_id(proto_id);
6061 return protocol->can_toggle;
6065 proto_set_decoding(const int proto_id, const gboolean enabled)
6067 protocol_t *protocol;
6069 protocol = find_protocol_by_id(proto_id);
6070 DISSECTOR_ASSERT(protocol->can_toggle);
6071 protocol->is_enabled = enabled;
6075 proto_enable_all(void)
6077 protocol_t *protocol;
6078 GList *list_item = protocols;
6080 if (protocols == NULL)
6084 protocol = (protocol_t *)list_item->data;
6085 if (protocol->can_toggle)
6086 protocol->is_enabled = TRUE;
6087 list_item = g_list_next(list_item);
6092 proto_set_cant_toggle(const int proto_id)
6094 protocol_t *protocol;
6096 protocol = find_protocol_by_id(proto_id);
6097 protocol->can_toggle = FALSE;
6101 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
6103 if (proto != NULL) {
6104 g_ptr_array_add(proto->fields, hfi);
6107 return proto_register_field_init(hfi, parent);
6110 /* for use with static arrays only, since we don't allocate our own copies
6111 of the header_field_info struct contained within the hf_register_info struct */
6113 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
6115 hf_register_info *ptr = hf;
6119 proto = find_protocol_by_id(parent);
6120 for (i = 0; i < num_records; i++, ptr++) {
6122 * Make sure we haven't registered this yet.
6123 * Most fields have variables associated with them
6124 * that are initialized to -1; some have array elements,
6125 * or possibly uninitialized variables, so we also allow
6126 * 0 (which is unlikely to be the field ID we get back
6127 * from "proto_register_field_init()").
6129 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
6131 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
6132 ptr->hfinfo.abbrev);
6136 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
6141 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
6146 proto = find_protocol_by_id(parent);
6147 for (i = 0; i < num_records; i++) {
6149 * Make sure we haven't registered this yet.
6151 if (hfi[i].id != -1) {
6153 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6158 proto_register_field_common(proto, &hfi[i], parent);
6163 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
6168 proto = find_protocol_by_id(parent);
6169 for (i = 0; i < num_records; i++) {
6171 * Make sure we haven't registered this yet.
6173 if (hfi[i]->id != -1) {
6175 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6180 proto_register_field_common(proto, hfi[i], parent);
6184 /* deregister already registered fields */
6186 proto_deregister_field (const int parent, gint hf_id)
6188 header_field_info *hfi;
6192 g_free(last_field_name);
6193 last_field_name = NULL;
6195 if (hf_id == -1 || hf_id == 0)
6198 proto = find_protocol_by_id (parent);
6199 if (!proto || proto->fields->len == 0) {
6203 for (i = 0; i < proto->fields->len; i++) {
6204 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
6205 if (hfi->id == hf_id) {
6206 /* Found the hf_id in this protocol */
6207 g_hash_table_steal(gpa_name_map, hfi->abbrev);
6208 g_ptr_array_remove_index_fast(proto->fields, i);
6209 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
6216 proto_add_deregistered_data (void *data)
6218 g_ptr_array_add(deregistered_data, data);
6222 free_deregistered_field (gpointer data, gpointer user_data _U_)
6224 header_field_info *hfi = (header_field_info *) data;
6225 gint hf_id = hfi->id;
6227 g_free((char *)hfi->name);
6228 g_free((char *)hfi->abbrev);
6229 g_free((char *)hfi->blurb);
6232 switch (hfi->type) {
6234 /* This is just an integer represented as a pointer */
6237 protocol_t *protocol = (protocol_t *)hfi->strings;
6238 g_free((gchar *)protocol->short_name);
6242 true_false_string *tf = (true_false_string *)hfi->strings;
6243 g_free ((gchar *)tf->true_string);
6244 g_free ((gchar *)tf->false_string);
6249 val64_string *vs64 = (val64_string *)hfi->strings;
6250 while (vs64->strptr) {
6251 g_free((gchar *)vs64->strptr);
6257 /* Other Integer types */
6258 value_string *vs = (value_string *)hfi->strings;
6259 while (vs->strptr) {
6260 g_free((gchar *)vs->strptr);
6266 if (hfi->type != FT_FRAMENUM) {
6267 g_free((void *)hfi->strings);
6271 if (hfi->parent == -1)
6272 g_slice_free(header_field_info, hfi);
6274 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
6278 free_deregistered_data (gpointer data, gpointer user_data _U_)
6283 /* free deregistered fields and data */
6285 proto_free_deregistered_fields (void)
6287 expert_free_deregistered_expertinfos();
6289 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
6290 g_ptr_array_free(deregistered_fields, TRUE);
6291 deregistered_fields = g_ptr_array_new();
6293 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
6294 g_ptr_array_free(deregistered_data, TRUE);
6295 deregistered_data = g_ptr_array_new();
6298 /* chars allowed in field abbrev */
6300 const guint8 fld_abbrev_chars[256] = {
6301 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
6302 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
6303 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
6304 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
6305 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
6306 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
6307 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
6308 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
6309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
6310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
6311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
6312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
6313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
6314 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
6315 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
6316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
6319 static const value_string hf_display[] = {
6320 { BASE_NONE, "BASE_NONE" },
6321 { BASE_DEC, "BASE_DEC" },
6322 { BASE_HEX, "BASE_HEX" },
6323 { BASE_OCT, "BASE_OCT" },
6324 { BASE_DEC_HEX, "BASE_DEC_HEX" },
6325 { BASE_HEX_DEC, "BASE_HEX_DEC" },
6326 { BASE_CUSTOM, "BASE_CUSTOM" },
6327 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
6328 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
6329 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
6330 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
6331 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
6332 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
6333 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
6334 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
6335 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
6336 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
6337 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
6338 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
6339 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
6340 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
6341 /* Alias: BASE_NONE { BASE_FLOAT, "BASE_FLOAT" }, */
6342 /* Alias: BASE_NONE { STR_ASCII, "STR_ASCII" }, */
6343 { STR_UNICODE, "STR_UNICODE" },
6344 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
6345 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
6346 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
6347 { BASE_PT_UDP, "BASE_PT_UDP" },
6348 { BASE_PT_TCP, "BASE_PT_TCP" },
6349 { BASE_PT_DCCP, "BASE_PT_DCCP" },
6350 { BASE_PT_SCTP, "BASE_PT_SCTP" },
6353 static inline port_type
6354 display_to_port_type(field_display_e e)
6371 /* temporary function containing assert part for easier profiling */
6373 tmp_fld_check_assert(header_field_info *hfinfo)
6377 /* The field must have a name (with length > 0) */
6378 if (!hfinfo->name || !hfinfo->name[0]) {
6380 /* Try to identify the field */
6381 g_error("Field (abbrev='%s') does not have a name\n",
6385 g_error("Field does not have a name (nor an abbreviation)\n");
6388 /* fields with an empty string for an abbreviation aren't filterable */
6389 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
6390 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
6392 /* These types of fields are allowed to have value_strings,
6393 * true_false_strings or a protocol_t struct
6395 if (hfinfo->strings != NULL && !(
6396 (hfinfo->type == FT_UINT8) ||
6397 (hfinfo->type == FT_UINT16) ||
6398 (hfinfo->type == FT_UINT24) ||
6399 (hfinfo->type == FT_UINT32) ||
6400 (hfinfo->type == FT_UINT40) ||
6401 (hfinfo->type == FT_UINT48) ||
6402 (hfinfo->type == FT_UINT56) ||
6403 (hfinfo->type == FT_UINT64) ||
6404 (hfinfo->type == FT_INT8) ||
6405 (hfinfo->type == FT_INT16) ||
6406 (hfinfo->type == FT_INT24) ||
6407 (hfinfo->type == FT_INT32) ||
6408 (hfinfo->type == FT_INT40) ||
6409 (hfinfo->type == FT_INT48) ||
6410 (hfinfo->type == FT_INT56) ||
6411 (hfinfo->type == FT_INT64) ||
6412 (hfinfo->type == FT_BOOLEAN) ||
6413 (hfinfo->type == FT_PROTOCOL) ||
6414 (hfinfo->type == FT_FRAMENUM) ))
6415 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
6416 " (which is not allowed to have strings)\n",
6417 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
6419 /* TODO: This check may slow down startup, and output quite a few warnings.
6420 It would be good to be able to enable this (and possibly other checks?)
6421 in non-release builds. */
6423 /* Check for duplicate value_string values.
6424 There are lots that have the same value *and* string, so for now only
6425 report those that have same value but different string. */
6426 if ((hfinfo->strings != NULL) &&
6427 !(hfinfo->display & BASE_RANGE_STRING) &&
6428 !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
6430 (hfinfo->type == FT_UINT8) ||
6431 (hfinfo->type == FT_UINT16) ||
6432 (hfinfo->type == FT_UINT24) ||
6433 (hfinfo->type == FT_UINT32) ||
6434 (hfinfo->type == FT_INT8) ||
6435 (hfinfo->type == FT_INT16) ||
6436 (hfinfo->type == FT_INT24) ||
6437 (hfinfo->type == FT_INT32) ||
6438 (hfinfo->type == FT_FRAMENUM) )) {
6441 const value_string *start_values;
6442 const value_string *current;
6444 if (hfinfo->display & BASE_EXT_STRING)
6445 start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
6447 start_values = (const value_string*)hfinfo->strings;
6448 current = start_values;
6450 for (n=0; current; n++, current++) {
6451 /* Drop out if we reached the end. */
6452 if ((current->value == 0) && (current->strptr == NULL)) {
6456 /* Check value against all previous */
6457 for (m=0; m < n; m++) {
6458 /* There are lots of duplicates with the same string,
6459 so only report if different... */
6460 if ((start_values[m].value == current->value) &&
6461 (strcmp(start_values[m].strptr, current->strptr) != 0)) {
6462 g_warning("Field '%s' (%s) has a conflicting entry in its"
6463 " value_string: %u is at indices %u (%s) and %u (%s))\n",
6464 hfinfo->name, hfinfo->abbrev,
6465 current->value, m, start_values[m].strptr, n, current->strptr);
6473 switch (hfinfo->type) {
6483 /* Hexadecimal and octal are, in printf() and everywhere
6484 * else, unsigned so don't allow dissectors to register a
6485 * signed field to be displayed unsigned. (Else how would
6486 * we display negative values?)
6488 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6493 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6494 g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
6495 hfinfo->name, hfinfo->abbrev,
6496 ftype_name(hfinfo->type), tmp_str);
6497 wmem_free(NULL, tmp_str);
6508 if (IS_BASE_PORT(hfinfo->display)) {
6509 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6510 if (hfinfo->type != FT_UINT16) {
6511 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
6512 hfinfo->name, hfinfo->abbrev,
6513 tmp_str, ftype_name(hfinfo->type));
6515 if (hfinfo->strings != NULL) {
6516 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
6517 hfinfo->name, hfinfo->abbrev,
6518 ftype_name(hfinfo->type), tmp_str);
6520 if (hfinfo->bitmask != 0) {
6521 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
6522 hfinfo->name, hfinfo->abbrev,
6523 ftype_name(hfinfo->type), tmp_str);
6525 wmem_free(NULL, tmp_str);
6528 /* Require integral types (other than frame number,
6529 * which is always displayed in decimal) to have a
6531 * If there is a strings value then this base is not
6532 * normally used except when constructing a display
6533 * filter for a value not found in the strings lookup.
6535 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6541 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6544 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6545 g_error("Field '%s' (%s) is an integral value (%s)"
6546 " but is being displayed as %s\n",
6547 hfinfo->name, hfinfo->abbrev,
6548 ftype_name(hfinfo->type), tmp_str);
6549 wmem_free(NULL, tmp_str);
6553 /* Require bytes to have a "display type" that could
6554 * add a character between displayed bytes.
6556 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6564 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6565 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",
6566 hfinfo->name, hfinfo->abbrev, tmp_str);
6567 wmem_free(NULL, tmp_str);
6569 if (hfinfo->bitmask != 0)
6570 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6571 hfinfo->name, hfinfo->abbrev,
6572 ftype_name(hfinfo->type));
6573 if (hfinfo->strings != NULL)
6574 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6575 hfinfo->name, hfinfo->abbrev,
6576 ftype_name(hfinfo->type));
6581 if (hfinfo->display != BASE_NONE) {
6582 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6583 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6584 hfinfo->name, hfinfo->abbrev,
6585 ftype_name(hfinfo->type), tmp_str);
6586 wmem_free(NULL, tmp_str);
6588 if (hfinfo->bitmask != 0)
6589 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6590 hfinfo->name, hfinfo->abbrev,
6591 ftype_name(hfinfo->type));
6597 case FT_ABSOLUTE_TIME:
6598 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
6599 hfinfo->display == ABSOLUTE_TIME_UTC ||
6600 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
6601 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6602 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
6603 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
6604 wmem_free(NULL, tmp_str);
6606 if (hfinfo->bitmask != 0)
6607 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6608 hfinfo->name, hfinfo->abbrev,
6609 ftype_name(hfinfo->type));
6614 case FT_UINT_STRING:
6616 switch (hfinfo->display) {
6622 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6623 g_error("Field '%s' (%s) is an string value (%s)"
6624 " but is being displayed as %s\n",
6625 hfinfo->name, hfinfo->abbrev,
6626 ftype_name(hfinfo->type), tmp_str);
6627 wmem_free(NULL, tmp_str);
6630 if (hfinfo->bitmask != 0)
6631 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6632 hfinfo->name, hfinfo->abbrev,
6633 ftype_name(hfinfo->type));
6634 if (hfinfo->strings != NULL)
6635 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6636 hfinfo->name, hfinfo->abbrev,
6637 ftype_name(hfinfo->type));
6641 switch (hfinfo->display) {
6647 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6648 g_error("Field '%s' (%s) is an IPv4 value (%s)"
6649 " but is being displayed as %s\n",
6650 hfinfo->name, hfinfo->abbrev,
6651 ftype_name(hfinfo->type), tmp_str);
6652 wmem_free(NULL, tmp_str);
6657 if (hfinfo->display != BASE_NONE) {
6658 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6659 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6660 hfinfo->name, hfinfo->abbrev,
6661 ftype_name(hfinfo->type),
6663 wmem_free(NULL, tmp_str);
6665 if (hfinfo->bitmask != 0)
6666 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6667 hfinfo->name, hfinfo->abbrev,
6668 ftype_name(hfinfo->type));
6669 if (hfinfo->strings != NULL)
6670 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6671 hfinfo->name, hfinfo->abbrev,
6672 ftype_name(hfinfo->type));
6677 #ifdef ENABLE_CHECK_FILTER
6679 _ftype_common(enum ftenum type)
6702 case FT_UINT_STRING:
6715 case FT_ABSOLUTE_TIME:
6716 case FT_RELATIVE_TIME:
6717 return FT_ABSOLUTE_TIME;
6726 register_type_length_mismatch(void)
6728 static ei_register_info ei[] = {
6729 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
6730 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
6733 expert_module_t* expert_type_length_mismatch;
6735 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
6737 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
6738 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
6740 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
6741 disabling them makes no sense. */
6742 proto_set_cant_toggle(proto_type_length_mismatch);
6746 register_number_string_decoding_error(void)
6748 static ei_register_info ei[] = {
6749 { &ei_number_string_decoding_failed_error,
6750 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
6751 "Failed to decode number from string", EXPFILL
6754 { &ei_number_string_decoding_erange_error,
6755 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
6756 "Decoded number from string is out of valid range", EXPFILL
6761 expert_module_t* expert_number_string_decoding_error;
6763 proto_number_string_decoding_error =
6764 proto_register_protocol("Number-String Decoding Error",
6765 "Number-string decoding error",
6766 "_ws.number_string.decoding_error");
6768 expert_number_string_decoding_error =
6769 expert_register_protocol(proto_number_string_decoding_error);
6770 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
6772 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
6773 disabling them makes no sense. */
6774 proto_set_cant_toggle(proto_number_string_decoding_error);
6777 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (178000+PRE_ALLOC_EXPERT_FIELDS_MEM)
6779 proto_register_field_init(header_field_info *hfinfo, const int parent)
6782 tmp_fld_check_assert(hfinfo);
6784 hfinfo->parent = parent;
6785 hfinfo->same_name_next = NULL;
6786 hfinfo->same_name_prev_id = -1;
6788 /* if we always add and never delete, then id == len - 1 is correct */
6789 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
6790 if (!gpa_hfinfo.hfi) {
6791 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
6792 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
6794 gpa_hfinfo.allocated_len += 1000;
6795 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
6796 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
6797 /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
6800 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
6802 hfinfo->id = gpa_hfinfo.len - 1;
6804 /* if we have real names, enter this field in the name tree */
6805 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
6807 header_field_info *same_name_next_hfinfo;
6810 /* Check that the filter name (abbreviation) is legal;
6811 * it must contain only alphanumerics, '-', "_", and ".". */
6812 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
6814 if (g_ascii_isprint(c))
6815 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
6817 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
6818 DISSECTOR_ASSERT_NOT_REACHED();
6821 /* We allow multiple hfinfo's to be registered under the same
6822 * abbreviation. This was done for X.25, as, depending
6823 * on whether it's modulo-8 or modulo-128 operation,
6824 * some bitfield fields may be in different bits of
6825 * a byte, and we want to be able to refer to that field
6826 * with one name regardless of whether the packets
6827 * are modulo-8 or modulo-128 packets. */
6829 same_name_hfinfo = NULL;
6831 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
6832 /* GLIB 2.x - if it is already present
6833 * the previous hfinfo with the same name is saved
6834 * to same_name_hfinfo by value destroy callback */
6835 if (same_name_hfinfo) {
6836 /* There's already a field with this name.
6837 * Put the current field *before* that field
6838 * in the list of fields with this name, Thus,
6839 * we end up with an effectively
6840 * doubly-linked-list of same-named hfinfo's,
6841 * with the head of the list (stored in the
6842 * hash) being the last seen hfinfo.
6844 same_name_next_hfinfo =
6845 same_name_hfinfo->same_name_next;
6847 hfinfo->same_name_next = same_name_next_hfinfo;
6848 if (same_name_next_hfinfo)
6849 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
6851 same_name_hfinfo->same_name_next = hfinfo;
6852 hfinfo->same_name_prev_id = same_name_hfinfo->id;
6853 #ifdef ENABLE_CHECK_FILTER
6854 while (same_name_hfinfo) {
6855 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
6856 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));
6857 same_name_hfinfo = same_name_hfinfo->same_name_next;
6867 proto_register_subtree_array(gint *const *indices, const int num_indices)
6870 gint *const *ptr = indices;
6873 * If we've already allocated the array of tree types, expand
6874 * it; this lets plugins such as mate add tree types after
6875 * the initial startup. (If we haven't already allocated it,
6876 * we don't allocate it; on the first pass, we just assign
6877 * ett values and keep track of how many we've assigned, and
6878 * when we're finished registering all dissectors we allocate
6879 * the array, so that we do only one allocation rather than
6880 * wasting CPU time and memory by growing the array for each
6881 * dissector that registers ett values.)
6883 if (tree_is_expanded != NULL) {
6884 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
6886 /* set new items to 0 */
6887 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
6888 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
6889 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
6893 * Assign "num_indices" subtree numbers starting at "num_tree_types",
6894 * returning the indices through the pointers in the array whose
6895 * first element is pointed to by "indices", and update
6896 * "num_tree_types" appropriately.
6898 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
6900 /* g_error will terminate the program */
6901 g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
6902 " This is a development error:"
6903 " Either the subtree item type has already been assigned or"
6904 " was not initialized to -1.");
6906 **ptr = num_tree_types;
6911 label_concat(char *label_str, gsize pos, const char *str)
6913 if (pos < ITEM_LABEL_LENGTH)
6914 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
6920 label_mark_truncated(char *label_str, gsize name_pos)
6922 static const char trunc_str[] = " [truncated]";
6923 const size_t trunc_len = sizeof(trunc_str)-1;
6926 /* ..... field_name: dataaaaaaaaaaaaa
6930 * ..... field_name [truncated]: dataaaaaaaaaaaaa
6932 * name_pos==0 means that we have only data or only a field_name
6935 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
6936 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
6937 memcpy(label_str + name_pos, trunc_str, trunc_len);
6939 /* in general, label_str is UTF-8
6940 we can truncate it only at the beginning of a new character
6941 we go backwards from the byte right after our buffer and
6942 find the next starting byte of a UTF-8 character, this is
6944 there's no need to use g_utf8_find_prev_char(), the search
6945 will always succeed since we copied trunc_str into the
6947 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH]);
6950 } else if (name_pos < ITEM_LABEL_LENGTH)
6951 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
6955 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
6959 /* "%s: %s", hfinfo->name, text */
6960 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
6961 pos = label_concat(label_str, pos, ": ");
6962 pos = label_concat(label_str, pos, text ? text : "(null)");
6964 if (pos >= ITEM_LABEL_LENGTH) {
6965 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
6966 label_mark_truncated(label_str, name_pos);
6973 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
6977 /* "%s: %s (%s)", hfinfo->name, text, descr */
6978 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
6979 pos = label_concat(label_str, pos, ": ");
6980 pos = label_concat(label_str, pos, text ? text : "(null)");
6981 pos = label_concat(label_str, pos, " (");
6982 pos = label_concat(label_str, pos, descr ? descr : "(null)");
6983 pos = label_concat(label_str, pos, ")");
6985 if (pos >= ITEM_LABEL_LENGTH) {
6986 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
6987 label_mark_truncated(label_str, name_pos);
6994 proto_item_fill_label(field_info *fi, gchar *label_str)
6996 header_field_info *hfinfo;
7000 ipv4_addr_and_mask *ipv4;
7002 guint32 n_addr; /* network-order IPv4 address */
7011 /* XXX: Check validity of hfinfo->type */
7015 hfinfo = fi->hfinfo;
7017 switch (hfinfo->type) {
7020 g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
7024 fill_label_boolean(fi, label_str);
7029 bytes = (guint8 *)fvalue_get(&fi->value);
7032 switch(hfinfo->display)
7035 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
7038 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
7041 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
7044 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7048 if (prefs.display_byte_fields_with_spaces)
7050 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7054 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
7058 label_fill(label_str, 0, hfinfo, str);
7059 wmem_free(NULL, str);
7061 if (hfinfo->display & BASE_ALLOW_ZERO) {
7062 label_fill(label_str, 0, hfinfo, "<none>");
7064 label_fill(label_str, 0, hfinfo, "<MISSING>");
7069 /* Four types of integers to take care of:
7070 * Bitfield, with val_string
7071 * Bitfield, w/o val_string
7072 * Non-bitfield, with val_string
7073 * Non-bitfield, w/o val_string
7079 if (hfinfo->bitmask) {
7080 fill_label_bitfield(fi, label_str, FALSE);
7082 fill_label_number(fi, label_str, FALSE);
7087 fill_label_number(fi, label_str, FALSE);
7094 if (hfinfo->bitmask) {
7095 fill_label_bitfield64(fi, label_str, FALSE);
7097 fill_label_number64(fi, label_str, FALSE);
7105 if (hfinfo->bitmask) {
7106 fill_label_bitfield(fi, label_str, TRUE);
7108 fill_label_number(fi, label_str, TRUE);
7116 if (hfinfo->bitmask) {
7117 fill_label_bitfield64(fi, label_str, TRUE);
7119 fill_label_number64(fi, label_str, TRUE);
7124 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7125 "%s: %." G_STRINGIFY(FLT_DIG) "g",
7126 hfinfo->name, fvalue_get_floating(&fi->value));
7130 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7131 "%s: %." G_STRINGIFY(DBL_DIG) "g",
7132 hfinfo->name, fvalue_get_floating(&fi->value));
7135 case FT_ABSOLUTE_TIME:
7136 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
7137 label_fill(label_str, 0, hfinfo, tmp);
7138 wmem_free(NULL, tmp);
7141 case FT_RELATIVE_TIME:
7142 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
7143 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7144 "%s: %s seconds", hfinfo->name, tmp);
7145 wmem_free(NULL, tmp);
7149 integer = fvalue_get_uinteger(&fi->value);
7150 tmp = get_ipxnet_name(NULL, integer);
7151 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7152 "%s: %s (0x%08X)", hfinfo->name,
7154 wmem_free(NULL, tmp);
7158 addr.type = AT_AX25;
7159 addr.len = AX25_ADDR_LEN;
7160 addr.data = (guint8 *)fvalue_get(&fi->value);
7162 addr_str = (char*)address_to_str(NULL, &addr);
7163 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7164 "%s: %s", hfinfo->name, addr_str);
7165 wmem_free(NULL, addr_str);
7169 addr.type = AT_VINES;
7170 addr.len = VINES_ADDR_LEN;
7171 addr.data = (guint8 *)fvalue_get(&fi->value);
7173 addr_str = (char*)address_to_str(NULL, &addr);
7174 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7175 "%s: %s", hfinfo->name, addr_str);
7176 wmem_free(NULL, addr_str);
7180 bytes = (guint8 *)fvalue_get(&fi->value);
7182 addr.type = AT_ETHER;
7186 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7187 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7188 "%s: %s", hfinfo->name, addr_str);
7189 wmem_free(NULL, addr_str);
7193 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&fi->value);
7194 n_addr = ipv4_get_net_order_addr(ipv4);
7196 addr.type = AT_IPv4;
7198 addr.data = &n_addr;
7200 if (hfinfo->display == BASE_NETMASK)
7202 addr_str = (char*)address_to_str(NULL, &addr);
7206 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7208 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7209 "%s: %s", hfinfo->name, addr_str);
7210 wmem_free(NULL, addr_str);
7214 bytes = (guint8 *)fvalue_get(&fi->value);
7216 addr.type = AT_IPv6;
7220 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7221 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7222 "%s: %s", hfinfo->name, addr_str);
7223 wmem_free(NULL, addr_str);
7227 addr.type = AT_FCWWN;
7228 addr.len = FCWWN_ADDR_LEN;
7229 addr.data = (guint8 *)fvalue_get(&fi->value);
7231 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7232 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7233 "%s: %s", hfinfo->name, addr_str);
7234 wmem_free(NULL, addr_str);
7238 guid = (e_guid_t *)fvalue_get(&fi->value);
7239 tmp = guid_to_str(NULL, guid);
7240 label_fill(label_str, 0, hfinfo, tmp);
7241 wmem_free(NULL, tmp);
7245 bytes = (guint8 *)fvalue_get(&fi->value);
7246 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7247 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7249 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7250 wmem_free(NULL, name);
7252 label_fill(label_str, 0, hfinfo, tmp);
7254 wmem_free(NULL, tmp);
7258 bytes = (guint8 *)fvalue_get(&fi->value);
7259 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7260 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7262 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7263 wmem_free(NULL, name);
7265 label_fill(label_str, 0, hfinfo, tmp);
7267 wmem_free(NULL, tmp);
7271 bytes = (guint8 *)fvalue_get(&fi->value);
7272 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
7273 label_fill(label_str, 0, hfinfo, tmp);
7274 wmem_free(NULL, tmp);
7278 integer64 = fvalue_get_uinteger64(&fi->value);
7279 addr_str = eui64_to_str(NULL, integer64);
7280 tmp = (char*)eui64_to_display(NULL, integer64);
7281 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
7282 wmem_free(NULL, tmp);
7283 wmem_free(NULL, addr_str);
7287 case FT_UINT_STRING:
7289 bytes = (guint8 *)fvalue_get(&fi->value);
7290 label_fill(label_str, 0, hfinfo, hfinfo_format_text(hfinfo, bytes));
7293 case FT_IEEE_11073_SFLOAT:
7296 fvalue_to_string_repr(&fi->value, FTREPR_DISPLAY, hfinfo->display, buf);
7297 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7302 case FT_IEEE_11073_FLOAT:
7305 fvalue_to_string_repr(&fi->value, FTREPR_DISPLAY, hfinfo->display, buf);
7306 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7313 g_error("hfinfo->type %d (%s) not handled\n",
7314 hfinfo->type, ftype_name(hfinfo->type));
7315 DISSECTOR_ASSERT_NOT_REACHED();
7321 fill_label_boolean(field_info *fi, gchar *label_str)
7323 char *p = label_str;
7324 int bitfield_byte_length = 0, bitwidth;
7325 guint64 unshifted_value;
7328 header_field_info *hfinfo = fi->hfinfo;
7329 const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
7331 if (hfinfo->strings) {
7332 tfstring = (const struct true_false_string*) hfinfo->strings;
7335 value = fvalue_get_uinteger64(&fi->value);
7336 if (hfinfo->bitmask) {
7337 /* Figure out the bit width */
7338 bitwidth = hfinfo_container_bitwidth(hfinfo);
7341 unshifted_value = value;
7342 unshifted_value <<= hfinfo_bitshift(hfinfo);
7344 /* Create the bitfield first */
7345 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7346 bitfield_byte_length = (int) (p - label_str);
7349 /* Fill in the textual info */
7350 label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
7354 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
7356 if (hfinfo->display & BASE_RANGE_STRING)
7357 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
7359 if (hfinfo->display & BASE_EXT_STRING)
7360 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
7362 if (hfinfo->display & BASE_VAL64_STRING)
7363 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7365 return try_val_to_str(value, (const value_string *) hfinfo->strings);
7369 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
7371 if (hfinfo->display & BASE_VAL64_STRING)
7372 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7374 /* If this is reached somebody registered a 64-bit field with a 32-bit
7375 * value-string, which isn't right. */
7376 DISSECTOR_ASSERT_NOT_REACHED();
7378 /* This is necessary to squelch MSVC errors; is there
7379 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
7385 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
7387 const char *str = hf_try_val_to_str(value, hfinfo);
7389 return (str) ? str : unknown_str;
7393 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
7395 const char *str = hf_try_val64_to_str(value, hfinfo);
7397 return (str) ? str : unknown_str;
7400 /* Fills data for bitfield ints with val_strings */
7402 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
7405 int bitfield_byte_length, bitwidth;
7406 guint32 unshifted_value;
7412 header_field_info *hfinfo = fi->hfinfo;
7414 /* Figure out the bit width */
7415 bitwidth = hfinfo_container_bitwidth(hfinfo);
7419 value = fvalue_get_sinteger(&fi->value);
7421 value = fvalue_get_uinteger(&fi->value);
7423 unshifted_value = value;
7424 if (hfinfo->bitmask) {
7425 unshifted_value <<= hfinfo_bitshift(hfinfo);
7428 /* Create the bitfield first */
7429 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7430 bitfield_byte_length = (int) (p - label_str);
7432 /* Fill in the textual info using stored (shifted) value */
7433 if (hfinfo->display == BASE_CUSTOM) {
7434 gchar tmp[ITEM_LABEL_LENGTH];
7435 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7437 DISSECTOR_ASSERT(fmtfunc);
7438 fmtfunc(tmp, value);
7439 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7441 else if (hfinfo->strings) {
7442 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7444 out = hfinfo_number_vals_format(hfinfo, buf, value);
7445 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7446 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7448 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7451 out = hfinfo_number_value_format(hfinfo, buf, value);
7453 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7458 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
7461 int bitfield_byte_length, bitwidth;
7462 guint64 unshifted_value;
7468 header_field_info *hfinfo = fi->hfinfo;
7470 /* Figure out the bit width */
7471 bitwidth = hfinfo_container_bitwidth(hfinfo);
7475 value = fvalue_get_sinteger64(&fi->value);
7477 value = fvalue_get_uinteger64(&fi->value);
7479 unshifted_value = value;
7480 if (hfinfo->bitmask) {
7481 unshifted_value <<= hfinfo_bitshift(hfinfo);
7484 /* Create the bitfield first */
7485 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7486 bitfield_byte_length = (int) (p - label_str);
7488 /* Fill in the textual info using stored (shifted) value */
7489 if (hfinfo->display == BASE_CUSTOM) {
7490 gchar tmp[ITEM_LABEL_LENGTH];
7491 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7493 DISSECTOR_ASSERT(fmtfunc64);
7494 fmtfunc64(tmp, value);
7495 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7497 else if (hfinfo->strings) {
7498 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7500 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7501 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7502 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7504 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7507 out = hfinfo_number_value_format64(hfinfo, buf, value);
7509 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7514 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
7516 header_field_info *hfinfo = fi->hfinfo;
7523 value = fvalue_get_sinteger(&fi->value);
7525 value = fvalue_get_uinteger(&fi->value);
7527 /* Fill in the textual info */
7528 if (hfinfo->display == BASE_CUSTOM) {
7529 gchar tmp[ITEM_LABEL_LENGTH];
7530 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7532 DISSECTOR_ASSERT(fmtfunc);
7533 fmtfunc(tmp, value);
7534 label_fill(label_str, 0, hfinfo, tmp);
7536 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) { /* Add fill_label_framenum? */
7537 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7539 out = hfinfo_number_vals_format(hfinfo, buf, value);
7540 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7541 label_fill(label_str, 0, hfinfo, val_str);
7543 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7545 else if (IS_BASE_PORT(hfinfo->display)) {
7546 gchar tmp[ITEM_LABEL_LENGTH];
7548 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
7549 display_to_port_type((field_display_e)hfinfo->display), value);
7550 label_fill(label_str, 0, hfinfo, tmp);
7553 out = hfinfo_number_value_format(hfinfo, buf, value);
7555 label_fill(label_str, 0, hfinfo, out);
7560 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
7562 header_field_info *hfinfo = fi->hfinfo;
7569 value = fvalue_get_sinteger64(&fi->value);
7571 value = fvalue_get_uinteger64(&fi->value);
7573 /* Fill in the textual info */
7574 if (hfinfo->display == BASE_CUSTOM) {
7575 gchar tmp[ITEM_LABEL_LENGTH];
7576 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7578 DISSECTOR_ASSERT(fmtfunc64);
7579 fmtfunc64(tmp, value);
7580 label_fill(label_str, 0, hfinfo, tmp);
7582 else if (hfinfo->strings) {
7583 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7585 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7586 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7587 label_fill(label_str, 0, hfinfo, val_str);
7589 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7592 out = hfinfo_number_value_format64(hfinfo, buf, value);
7594 label_fill(label_str, 0, hfinfo, out);
7599 hfinfo_bitshift(const header_field_info *hfinfo)
7601 return ws_ctz(hfinfo->bitmask);
7605 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
7607 if (!hfinfo->bitmask) {
7611 /* ilog2 = first set bit, ctz = last set bit */
7612 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
7616 hfinfo_type_bitwidth(enum ftenum type)
7654 DISSECTOR_ASSERT_NOT_REACHED();
7662 hfinfo_container_bitwidth(const header_field_info *hfinfo)
7664 if (!hfinfo->bitmask) {
7668 if (hfinfo->type == FT_BOOLEAN) {
7669 return hfinfo->display; /* hacky? :) */
7672 return hfinfo_type_bitwidth(hfinfo->type);
7676 hfinfo_hex_digits(const header_field_info *hfinfo)
7680 /* If we have a bitmask, hfinfo->type is the width of the container, so not
7681 * appropriate to determine the number of hex digits for the field.
7682 * So instead, we compute it from the bitmask.
7684 if (hfinfo->bitmask != 0) {
7685 bitwidth = hfinfo_mask_bitwidth(hfinfo);
7687 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
7690 /* Divide by 4, rounding up, to get number of hex digits. */
7691 return (bitwidth + 3) / 4;
7695 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
7697 char *ptr = &buf[31];
7698 gboolean isint = IS_FT_INT(hfinfo->type);
7701 /* Properly format value */
7702 switch (display & FIELD_DISPLAY_E_MASK) {
7704 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7708 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7711 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7715 return oct_to_str_back(ptr, value);
7718 return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7722 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7725 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7732 port_with_resolution_to_str_buf(buf, 32,
7733 display_to_port_type((field_display_e)display), value);
7737 g_assert_not_reached();
7743 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
7745 char *ptr = &buf[47];
7746 gboolean isint = IS_FT_INT(hfinfo->type);
7749 /* Properly format value */
7752 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7756 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7759 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7763 return oct64_to_str_back(ptr, value);
7766 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7770 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7773 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7777 g_assert_not_reached();
7783 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7785 int display = hfinfo->display;
7787 if (hfinfo->type == FT_FRAMENUM) {
7789 * Frame numbers are always displayed in decimal.
7794 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7798 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7800 int display = hfinfo->display;
7802 if (hfinfo->type == FT_FRAMENUM) {
7804 * Frame numbers are always displayed in decimal.
7809 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7813 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7815 /* Get the underlying BASE_ value */
7816 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7818 if (hfinfo->type == FT_FRAMENUM) {
7820 * Frame numbers are always displayed in decimal.
7825 if (IS_BASE_PORT(display)) {
7831 /* case BASE_DEC: */
7833 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
7838 /* case BASE_HEX: */
7844 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7848 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7850 /* Get the underlying BASE_ value */
7851 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7853 if (hfinfo->type == FT_FRAMENUM) {
7855 * Frame numbers are always displayed in decimal.
7862 /* case BASE_DEC: */
7864 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
7869 /* case BASE_HEX: */
7875 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7879 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7881 /* Get the underlying BASE_ value */
7882 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7884 if (display == BASE_NONE)
7887 if (display == BASE_DEC_HEX)
7889 if (display == BASE_HEX_DEC)
7892 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7896 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7898 /* Get the underlying BASE_ value */
7899 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7901 if (display == BASE_NONE)
7904 if (display == BASE_DEC_HEX)
7906 if (display == BASE_HEX_DEC)
7909 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7913 proto_registrar_get_name(const int n)
7915 header_field_info *hfinfo;
7917 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7918 return hfinfo->name;
7922 proto_registrar_get_abbrev(const int n)
7924 header_field_info *hfinfo;
7926 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7927 return hfinfo->abbrev;
7931 proto_registrar_get_ftype(const int n)
7933 header_field_info *hfinfo;
7935 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7936 return hfinfo->type;
7940 proto_registrar_get_parent(const int n)
7942 header_field_info *hfinfo;
7944 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7945 return hfinfo->parent;
7949 proto_registrar_is_protocol(const int n)
7951 header_field_info *hfinfo;
7953 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7954 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
7957 /* Returns length of field in packet (not necessarily the length
7958 * in our internal representation, as in the case of IPv4).
7959 * 0 means undeterminable at time of registration
7960 * -1 means the field is not registered. */
7962 proto_registrar_get_length(const int n)
7964 header_field_info *hfinfo;
7966 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7967 return ftype_length(hfinfo->type);
7970 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
7971 * it exists anywhere, or FALSE if it exists nowhere. */
7973 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
7975 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
7977 if (g_ptr_array_len(ptrs) > 0) {
7985 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
7986 * This only works if the hfindex was "primed" before the dissection
7987 * took place, as we just pass back the already-created GPtrArray*.
7988 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
7991 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
7996 if (PTREE_DATA(tree)->interesting_hfids != NULL)
7997 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
7998 GINT_TO_POINTER(id));
8004 proto_tracking_interesting_fields(const proto_tree *tree)
8006 GHashTable *interesting_hfids;
8011 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
8013 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
8016 /* Helper struct for proto_find_info() and proto_all_finfos() */
8022 /* Helper function for proto_find_info() */
8024 find_finfo(proto_node *node, gpointer data)
8026 field_info *fi = PNODE_FINFO(node);
8027 if (fi && fi->hfinfo) {
8028 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8029 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8033 /* Don't stop traversing. */
8037 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
8038 * This works on any proto_tree, primed or unprimed, but actually searches
8039 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8040 * The caller does need to free the returned GPtrArray with
8041 * g_ptr_array_free(<array>, TRUE).
8044 proto_find_finfo(proto_tree *tree, const int id)
8048 ffdata.array = g_ptr_array_new();
8051 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
8053 return ffdata.array;
8056 /* Helper function for proto_all_finfos() */
8058 every_finfo(proto_node *node, gpointer data)
8060 field_info *fi = PNODE_FINFO(node);
8061 if (fi && fi->hfinfo) {
8062 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8065 /* Don't stop traversing. */
8069 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
8071 proto_all_finfos(proto_tree *tree)
8075 ffdata.array = g_ptr_array_new();
8078 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
8080 return ffdata.array;
8091 check_for_offset(proto_node *node, gpointer data)
8093 field_info *fi = PNODE_FINFO(node);
8094 offset_search_t *offsearch = (offset_search_t *)data;
8096 /* !fi == the top most container node which holds nothing */
8097 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
8098 if (offsearch->offset >= (guint) fi->start &&
8099 offsearch->offset < (guint) (fi->start + fi->length)) {
8101 offsearch->finfo = fi;
8102 return FALSE; /* keep traversing */
8105 return FALSE; /* keep traversing */
8108 /* Search a proto_tree backwards (from leaves to root) looking for the field
8109 * whose start/length occupies 'offset' */
8110 /* XXX - I couldn't find an easy way to search backwards, so I search
8111 * forwards, w/o stopping. Therefore, the last finfo I find will the be
8112 * the one I want to return to the user. This algorithm is inefficient
8113 * and could be re-done, but I'd have to handle all the children and
8114 * siblings of each node myself. When I have more time I'll do that.
8117 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
8119 offset_search_t offsearch;
8121 offsearch.offset = offset;
8122 offsearch.finfo = NULL;
8123 offsearch.tvb = tvb;
8125 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
8127 return offsearch.finfo;
8132 check_for_undecoded(proto_node *node, gpointer data)
8134 field_info *fi = PNODE_FINFO(node);
8135 gchar* decoded = (gchar*)data;
8140 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
8141 for (i = fi->start; i < fi->start + fi->length; i++) {
8144 decoded[byte] |= (1 << bit);
8152 proto_find_undecoded_data(proto_tree *tree, guint length)
8154 gchar* decoded = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
8156 proto_tree_traverse_pre_order(tree, check_for_undecoded, decoded);
8160 /* Dumps the protocols in the registration database to stdout. An independent
8161 * program can take this output and format it into nice tables or HTML or
8164 * There is one record per line. The fields are tab-delimited.
8166 * Field 1 = protocol name
8167 * Field 2 = protocol short name
8168 * Field 3 = protocol filter name
8171 proto_registrar_dump_protocols(void)
8173 protocol_t *protocol;
8175 void *cookie = NULL;
8178 i = proto_get_first_protocol(&cookie);
8180 protocol = find_protocol_by_id(i);
8181 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
8182 protocol->filter_name);
8183 i = proto_get_next_protocol(&cookie);
8187 /* Dumps the value_strings, extended value string headers, range_strings
8188 * or true/false strings for fields that have them.
8189 * There is one record per line. Fields are tab-delimited.
8190 * There are four types of records: Value String, Extended Value String Header,
8191 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
8192 * the type of record.
8194 * Note that a record will be generated only if the value_string,... is referenced
8195 * in a registered hfinfo entry.
8201 * Field 2 = Field abbreviation to which this value string corresponds
8202 * Field 3 = Integer value
8205 * Extended Value String Headers
8206 * -----------------------------
8208 * Field 2 = Field abbreviation to which this extended value string header corresponds
8209 * Field 3 = Extended Value String "Name"
8210 * Field 4 = Number of entries in the associated value_string array
8211 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
8216 * Field 2 = Field abbreviation to which this range string corresponds
8217 * Field 3 = Integer value: lower bound
8218 * Field 4 = Integer value: upper bound
8221 * True/False Strings
8222 * ------------------
8224 * Field 2 = Field abbreviation to which this true/false string corresponds
8225 * Field 3 = True String
8226 * Field 4 = False String
8229 proto_registrar_dump_values(void)
8231 header_field_info *hfinfo;
8233 const value_string *vals;
8234 const val64_string *vals64;
8235 const range_string *range;
8236 const true_false_string *tfs;
8238 len = gpa_hfinfo.len;
8239 for (i = 0; i < len ; i++) {
8240 if (gpa_hfinfo.hfi[i] == NULL)
8241 continue; /* This is a deregistered protocol or field */
8243 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8245 if (hfinfo->id == hf_text_only) {
8249 /* ignore protocols */
8250 if (proto_registrar_is_protocol(i)) {
8253 /* process header fields */
8254 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
8256 * If this field isn't at the head of the list of
8257 * fields with this name, skip this field - all
8258 * fields with the same name are really just versions
8259 * of the same field stored in different bits, and
8260 * should have the same type/radix/value list, and
8261 * just differ in their bit masks. (If a field isn't
8262 * a bitfield, but can be, say, 1 or 2 bytes long,
8263 * it can just be made FT_UINT16, meaning the
8264 * *maximum* length is 2 bytes, and be used
8267 if (hfinfo->same_name_prev_id != -1)
8275 if (hfinfo->strings != NULL) {
8276 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) != BASE_CUSTOM &&
8277 (hfinfo->type == FT_UINT8 ||
8278 hfinfo->type == FT_UINT16 ||
8279 hfinfo->type == FT_UINT24 ||
8280 hfinfo->type == FT_UINT32 ||
8281 hfinfo->type == FT_UINT40 ||
8282 hfinfo->type == FT_UINT48 ||
8283 hfinfo->type == FT_UINT56 ||
8284 hfinfo->type == FT_UINT64 ||
8285 hfinfo->type == FT_INT8 ||
8286 hfinfo->type == FT_INT16 ||
8287 hfinfo->type == FT_INT24 ||
8288 hfinfo->type == FT_INT32 ||
8289 hfinfo->type == FT_INT40 ||
8290 hfinfo->type == FT_INT48 ||
8291 hfinfo->type == FT_INT56 ||
8292 hfinfo->type == FT_INT64)) {
8294 if (hfinfo->display & BASE_RANGE_STRING) {
8295 range = (const range_string *)hfinfo->strings;
8296 } else if (hfinfo->display & BASE_EXT_STRING) {
8297 vals = VALUE_STRING_EXT_VS_P((value_string_ext *)hfinfo->strings);
8298 } else if (hfinfo->display & BASE_VAL64_STRING) {
8299 vals64 = (const val64_string *)hfinfo->strings;
8301 vals = (const value_string *)hfinfo->strings;
8304 else if (hfinfo->type == FT_BOOLEAN) {
8305 tfs = (const struct true_false_string *)hfinfo->strings;
8309 /* Print value strings? */
8311 if (hfinfo->display & BASE_EXT_STRING) {
8312 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
8313 if (!value_string_ext_validate(vse_p)) {
8314 g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
8317 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
8318 printf("E\t%s\t%u\t%s\t%s\n",
8320 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
8321 VALUE_STRING_EXT_VS_NAME(vse_p),
8322 value_string_ext_match_type_str(vse_p));
8325 while (vals[vi].strptr) {
8326 /* Print in the proper base */
8327 if (hfinfo->display == BASE_HEX) {
8328 printf("V\t%s\t0x%x\t%s\n",
8334 printf("V\t%s\t%u\t%s\n",
8344 while (vals64[vi].strptr) {
8345 printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
8353 /* print range strings? */
8356 while (range[vi].strptr) {
8357 /* Print in the proper base */
8358 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_HEX) {
8359 printf("R\t%s\t0x%x\t0x%x\t%s\n",
8361 range[vi].value_min,
8362 range[vi].value_max,
8366 printf("R\t%s\t%u\t%u\t%s\n",
8368 range[vi].value_min,
8369 range[vi].value_max,
8376 /* Print true/false strings? */
8378 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
8379 tfs->true_string, tfs->false_string);
8384 /* Prints the number of registered fields.
8385 * Useful for determining an appropriate value for
8386 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
8388 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
8389 * the number of fields, TRUE otherwise.
8392 proto_registrar_dump_fieldcount(void)
8395 header_field_info *hfinfo;
8396 guint32 deregistered_count = 0;
8397 guint32 same_name_count = 0;
8398 guint32 protocol_count = 0;
8400 for (i = 0; i < gpa_hfinfo.len; i++) {
8401 if (gpa_hfinfo.hfi[i] == NULL) {
8402 deregistered_count++;
8403 continue; /* This is a deregistered protocol or header field */
8406 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8408 if (proto_registrar_is_protocol(i))
8411 if (hfinfo->same_name_prev_id != -1)
8415 printf ("There are %d header fields registered, of which:\n"
8416 "\t%d are deregistered\n"
8417 "\t%d are protocols\n"
8418 "\t%d have the same name as another field\n\n",
8419 gpa_hfinfo.len, deregistered_count, protocol_count,
8422 printf ("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
8423 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
8424 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
8427 printf ("The header field table consumes %d KiB of memory.\n",
8428 (int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
8429 printf ("The fields themselves consume %d KiB of memory.\n",
8430 (int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
8432 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8436 /* Dumps the contents of the registration database to stdout. An independent
8437 * program can take this output and format it into nice tables or HTML or
8440 * There is one record per line. Each record is either a protocol or a header
8441 * field, differentiated by the first field. The fields are tab-delimited.
8446 * Field 2 = descriptive protocol name
8447 * Field 3 = protocol abbreviation
8452 * Field 2 = descriptive field name
8453 * Field 3 = field abbreviation
8454 * Field 4 = type ( textual representation of the the ftenum type )
8455 * Field 5 = parent protocol abbreviation
8456 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
8457 * Field 7 = bitmask: format: hex: 0x....
8458 * Field 8 = blurb describing field
8461 proto_registrar_dump_fields(void)
8463 header_field_info *hfinfo, *parent_hfinfo;
8465 const char *enum_name;
8466 const char *base_name;
8470 len = gpa_hfinfo.len;
8471 for (i = 0; i < len ; i++) {
8472 if (gpa_hfinfo.hfi[i] == NULL)
8473 continue; /* This is a deregistered protocol or header field */
8475 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8478 * Skip the pseudo-field for "proto_tree_add_text()" since
8479 * we don't want it in the list of filterable fields.
8481 if (hfinfo->id == hf_text_only)
8484 /* format for protocols */
8485 if (proto_registrar_is_protocol(i)) {
8486 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
8488 /* format for header fields */
8491 * If this field isn't at the head of the list of
8492 * fields with this name, skip this field - all
8493 * fields with the same name are really just versions
8494 * of the same field stored in different bits, and
8495 * should have the same type/radix/value list, and
8496 * just differ in their bit masks. (If a field isn't
8497 * a bitfield, but can be, say, 1 or 2 bytes long,
8498 * it can just be made FT_UINT16, meaning the
8499 * *maximum* length is 2 bytes, and be used
8502 if (hfinfo->same_name_prev_id != -1)
8505 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
8507 enum_name = ftype_name(hfinfo->type);
8510 if (hfinfo->type == FT_UINT8 ||
8511 hfinfo->type == FT_UINT16 ||
8512 hfinfo->type == FT_UINT24 ||
8513 hfinfo->type == FT_UINT32 ||
8514 hfinfo->type == FT_UINT40 ||
8515 hfinfo->type == FT_UINT48 ||
8516 hfinfo->type == FT_UINT56 ||
8517 hfinfo->type == FT_UINT64 ||
8518 hfinfo->type == FT_INT8 ||
8519 hfinfo->type == FT_INT16 ||
8520 hfinfo->type == FT_INT24 ||
8521 hfinfo->type == FT_INT32 ||
8522 hfinfo->type == FT_INT40 ||
8523 hfinfo->type == FT_INT48 ||
8524 hfinfo->type == FT_INT56 ||
8525 hfinfo->type == FT_INT64) {
8527 switch (FIELD_DISPLAY(hfinfo->display)) {
8539 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
8545 } else if (hfinfo->type == FT_BOOLEAN) {
8546 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
8547 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
8551 blurb = hfinfo->blurb;
8554 else if (strlen(blurb) == 0)
8557 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
8558 hfinfo->name, hfinfo->abbrev, enum_name,
8559 parent_hfinfo->abbrev, base_name,
8560 hfinfo->bitmask, blurb);
8565 /* Dumps field types and descriptive names to stdout. An independent
8566 * program can take this output and format it into nice tables or HTML or
8569 * There is one record per line. The fields are tab-delimited.
8571 * Field 1 = field type name, e.g. FT_UINT8
8572 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
8575 proto_registrar_dump_ftypes(void)
8579 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
8580 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
8584 /* This function indicates whether it's possible to construct a
8585 * "match selected" display filter string for the specified field,
8586 * returns an indication of whether it's possible, and, if it's
8587 * possible and "filter" is non-null, constructs the filter and
8588 * sets "*filter" to point to it.
8589 * You do not need to [g_]free() this string since it will be automatically
8590 * freed once the next packet is dissected.
8593 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
8596 header_field_info *hfinfo;
8601 gint start, length, length_remaining;
8603 gchar is_signed_num = FALSE;
8608 hfinfo = finfo->hfinfo;
8609 DISSECTOR_ASSERT(hfinfo);
8610 abbrev_len = (int) strlen(hfinfo->abbrev);
8612 if (hfinfo->strings && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
8613 const gchar *str = NULL;
8615 switch (hfinfo->type) {
8621 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
8628 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
8635 if (str != NULL && filter != NULL) {
8636 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
8642 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
8643 * functions for FT_UINT and FT_INT types, as we choose the base in
8644 * the string expression based on the display base of the field.
8646 * Note that the base does matter, as this is also used for
8647 * the protocolinfo tap.
8649 * It might be nice to use them in "proto_item_fill_label()"
8650 * as well, although, there, you'd have to deal with the base
8651 * *and* with resolved values for addresses.
8653 * Perhaps we need two different val_to_string routines, one
8654 * to generate items for display filters and one to generate
8655 * strings for display, and pass to both of them the
8656 * "display" and "strings" values in the header_field_info
8657 * structure for the field, so they can get the base and,
8658 * if the field is Boolean or an enumerated integer type,
8659 * the tables used to generate human-readable values.
8661 switch (hfinfo->type) {
8667 is_signed_num = TRUE;
8674 if (filter != NULL) {
8681 number = fvalue_get_sinteger(&finfo->value);
8683 number = fvalue_get_uinteger(&finfo->value);
8685 out = hfinfo_numeric_value_format(hfinfo, buf, number);
8687 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
8695 is_signed_num = TRUE;
8701 if (filter != NULL) {
8708 number = fvalue_get_sinteger64(&finfo->value);
8710 number = fvalue_get_uinteger64(&finfo->value);
8712 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
8714 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
8720 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
8725 * If the length is 0, just match the name of the
8728 * (Also check for negative values, just in case,
8729 * as we'll cast it to an unsigned value later.)
8731 length = finfo->length;
8734 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
8741 * This doesn't have a value, so we'd match
8742 * on the raw bytes at this address.
8744 * Should we be allowed to access to the raw bytes?
8745 * If "edt" is NULL, the answer is "no".
8751 * Is this field part of the raw frame tvbuff?
8752 * If not, we can't use "frame[N:M]" to match
8755 * XXX - should this be frame-relative, or
8756 * protocol-relative?
8758 * XXX - does this fallback for non-registered
8759 * fields even make sense?
8761 if (finfo->ds_tvb != edt->tvb)
8762 return FALSE; /* you lose */
8765 * Don't go past the end of that tvbuff.
8767 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
8768 if (length > length_remaining)
8769 length = length_remaining;
8773 if (filter != NULL) {
8774 start = finfo->start;
8775 buf_len = 32 + length * 3;
8776 *filter = (char *)wmem_alloc0(NULL, buf_len);
8779 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
8780 "frame[%d:%d] == ", finfo->start, length);
8781 for (i=0; i<length; i++) {
8782 c = tvb_get_guint8(finfo->ds_tvb, start);
8785 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
8788 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
8795 /* FT_PCRE never appears as a type for a registered field. It is
8796 * only used internally. */
8797 DISSECTOR_ASSERT_NOT_REACHED();
8800 /* By default, use the fvalue's "to_string_repr" method. */
8802 /* Figure out the string length needed.
8803 * The ft_repr length.
8804 * 4 bytes for " == ".
8805 * 1 byte for trailing NUL.
8807 if (filter != NULL) {
8808 dfilter_len = fvalue_string_repr_len(&finfo->value,
8809 FTREPR_DFILTER, finfo->hfinfo->display);
8810 dfilter_len += abbrev_len + 4 + 1;
8811 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
8813 /* Create the string */
8814 g_snprintf(*filter, dfilter_len, "%s == ",
8816 fvalue_to_string_repr(&finfo->value,
8817 FTREPR_DFILTER, finfo->hfinfo->display,
8818 &(*filter)[abbrev_len + 4]);
8827 * Returns TRUE if we can do a "match selected" on the field, FALSE
8831 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
8833 return construct_match_selected_string(finfo, edt, NULL);
8836 /* This function attempts to construct a "match selected" display filter
8837 * string for the specified field; if it can do so, it returns a pointer
8838 * to the string, otherwise it returns NULL.
8840 * The string is allocated with packet lifetime scope.
8841 * You do not need to [g_]free() this string since it will be automatically
8842 * freed once the next packet is dissected.
8845 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
8847 char *filter = NULL;
8849 if (!construct_match_selected_string(finfo, edt, &filter))
8851 wmem_free(NULL, filter);
8857 /* This function is common code for all proto_tree_add_bitmask... functions.
8861 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
8862 const int len, const gint ett, const int **fields,
8863 const int flags, gboolean first,
8864 gboolean use_parent_tree,
8865 proto_tree* tree, guint64 value)
8868 guint64 available_bits = 0;
8870 header_field_info *hf;
8872 if (len <= 0 || len > 8)
8873 g_assert_not_reached();
8874 bitshift = (8 - (guint)len)*8;
8875 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
8877 if (use_parent_tree == FALSE)
8878 tree = proto_item_add_subtree(item, ett);
8881 guint64 present_bits;
8882 PROTO_REGISTRAR_GET_NTH(**fields,hf);
8883 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
8885 /* Skip fields that aren't fully present */
8886 present_bits = available_bits & hf->bitmask;
8887 if (present_bits != hf->bitmask) {
8901 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
8912 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
8916 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
8920 DISSECTOR_ASSERT_NOT_REACHED();
8923 if (flags & BMT_NO_APPEND) {
8927 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
8946 if (hf->display == BASE_CUSTOM) {
8947 gchar lbl[ITEM_LABEL_LENGTH];
8948 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
8950 DISSECTOR_ASSERT(fmtfunc);
8951 fmtfunc(lbl, (guint32) tmpval);
8952 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8956 else if (hf->strings) {
8957 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8958 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
8961 else if (!(flags & BMT_NO_INT)) {
8966 proto_item_append_text(item, ", ");
8969 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
8970 proto_item_append_text(item, "%s: %s", hf->name, out);
8976 if (hf->strings && !(flags & BMT_NO_TFS)) {
8977 /* If we have true/false strings, emit full - otherwise messages
8979 const struct true_false_string *tfs =
8980 (const struct true_false_string *)hf->strings;
8983 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8984 hf->name, tfs->true_string);
8986 } else if (!(flags & BMT_NO_FALSE)) {
8987 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8988 hf->name, tfs->false_string);
8991 } else if (hf->bitmask & value) {
8992 /* If the flag is set, show the name */
8993 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
8998 DISSECTOR_ASSERT_NOT_REACHED();
9008 /* This function will dissect a sequence of bytes that describe a
9009 * bitmask and supply the value of that sequence through a pointer.
9010 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9012 * This field will form an expansion under which the individual fields of the
9013 * bitmask is dissected and displayed.
9014 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9016 * fields is an array of pointers to int that lists all the fields of the
9017 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9018 * or another integer of the same type/size as hf_hdr with a mask specified.
9019 * This array is terminated by a NULL entry.
9021 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9022 * FT_integer fields that have a value_string attached will have the
9023 * matched string displayed on the expansion line.
9026 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
9027 const guint offset, const int hf_hdr,
9028 const gint ett, const int **fields,
9029 const guint encoding, guint64 *retval)
9031 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);
9034 /* This function will dissect a sequence of bytes that describe a
9036 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9038 * This field will form an expansion under which the individual fields of the
9039 * bitmask is dissected and displayed.
9040 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9042 * fields is an array of pointers to int that lists all the fields of the
9043 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9044 * or another integer of the same type/size as hf_hdr with a mask specified.
9045 * This array is terminated by a NULL entry.
9047 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9048 * FT_integer fields that have a value_string attached will have the
9049 * matched string displayed on the expansion line.
9052 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
9053 const guint offset, const int hf_hdr,
9054 const gint ett, const int **fields,
9055 const guint encoding)
9057 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
9060 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9061 * what data is appended to the header.
9064 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9065 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
9068 proto_item *item = NULL;
9069 header_field_info *hf;
9073 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9074 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9075 len = ftype_length(hf->type);
9076 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9079 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9080 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9081 flags, FALSE, FALSE, NULL, value);
9088 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9089 * what data is appended to the header.
9092 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9093 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
9095 proto_item *item = NULL;
9096 header_field_info *hf;
9100 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9101 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9104 len = ftype_length(hf->type);
9105 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9106 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9107 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9108 flags, FALSE, FALSE, NULL, value);
9114 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
9115 can't be retrieved directly from tvb) */
9117 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9118 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
9120 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
9121 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
9124 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
9125 WS_DLL_PUBLIC proto_item *
9126 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9127 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
9129 proto_item *item = NULL;
9130 header_field_info *hf;
9133 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9134 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9135 len = ftype_length(hf->type);
9139 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
9141 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
9143 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9144 flags, FALSE, FALSE, NULL, value);
9150 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
9152 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9153 const int len, const int **fields, const guint encoding)
9158 value = get_uint64_value(tree, tvb, offset, len, encoding);
9159 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9160 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9165 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
9166 * This is intended to support bitmask fields whose lengths can vary, perhaps
9167 * as the underlying standard evolves over time.
9168 * With this API there is the possibility of being called to display more or
9169 * less data than the dissector was coded to support.
9170 * In such cases, it is assumed that bitmasks are extended on the MSb end.
9171 * Thus when presented with "too much" or "too little" data, MSbits will be
9172 * ignored or MSfields sacrificed.
9174 * Only fields for which all defined bits are available are displayed.
9177 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
9178 const guint offset, const guint len, const int hf_hdr,
9179 const gint ett, const int **fields, struct expert_field* exp,
9180 const guint encoding)
9182 proto_item *item = NULL;
9183 header_field_info *hf;
9184 guint decodable_len;
9185 guint decodable_offset;
9186 guint32 decodable_value;
9189 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
9190 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9192 decodable_offset = offset;
9193 decodable_len = MIN(len, (guint) ftype_length(hf->type));
9195 /* If we are ftype_length-limited,
9196 * make sure we decode as many LSBs as possible.
9198 if (encoding == ENC_BIG_ENDIAN) {
9199 decodable_offset += (len - decodable_len);
9203 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
9204 decodable_len, encoding);
9206 /* The root item covers all the bytes even if we can't decode them all */
9207 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
9211 if (decodable_len < len) {
9212 /* Dissector likely requires updating for new protocol revision */
9213 expert_add_info_format(NULL, item, exp,
9214 "Only least-significant %d of %d bytes decoded",
9215 decodable_len, len);
9219 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
9220 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
9221 ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
9227 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
9229 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
9230 const guint offset, const guint len,
9231 const char *name, const char *fallback,
9232 const gint ett, const int **fields,
9233 const guint encoding, const int flags)
9235 proto_item *item = NULL;
9239 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
9240 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9241 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9242 flags, TRUE, FALSE, NULL, value) && fallback) {
9243 /* Still at first item - append 'fallback' text if any */
9244 proto_item_append_text(item, "%s", fallback);
9252 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9253 const guint bit_offset, const gint no_of_bits,
9254 const guint encoding)
9256 header_field_info *hfinfo;
9260 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9262 octet_length = (no_of_bits + 7) >> 3;
9263 octet_offset = bit_offset >> 3;
9264 test_length(hfinfo, tvb, octet_offset, octet_length);
9266 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
9267 * but only after doing a bunch more work (which we can, in the common
9268 * case, shortcut here).
9270 CHECK_FOR_NULL_TREE(tree);
9271 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9273 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
9277 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
9278 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
9279 * Offset should be given in bits from the start of the tvb.
9283 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9284 const guint bit_offset, const gint no_of_bits,
9285 guint64 *return_value, const guint encoding)
9291 char lbl_str[ITEM_LABEL_LENGTH];
9295 header_field_info *hf_field;
9297 const true_false_string *tfstring;
9299 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
9300 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
9302 if (hf_field->bitmask != 0) {
9303 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9304 "Incompatible use of proto_tree_add_bits_ret_val"
9305 " with field '%s' (%s) with bitmask != 0",
9306 hf_field->abbrev, hf_field->name));
9309 DISSECTOR_ASSERT(no_of_bits > 0);
9311 /* Byte align offset */
9312 offset = bit_offset>>3;
9315 * Calculate the number of octets used to hold the bits
9317 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
9318 length = (tot_no_bits + 7) >> 3;
9320 if (no_of_bits < 65) {
9321 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
9323 DISSECTOR_ASSERT_NOT_REACHED();
9327 /* Sign extend for signed types */
9328 switch (hf_field->type) {
9337 value = ws_sign_ext64(value, no_of_bits);
9345 *return_value = value;
9348 /* Coast clear. Try and fake it */
9349 CHECK_FOR_NULL_TREE(tree);
9350 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9352 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
9354 switch (hf_field->type) {
9357 tfstring = (const true_false_string *) &tfs_true_false;
9358 if (hf_field->strings)
9359 tfstring = (const true_false_string *)hf_field->strings;
9360 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
9362 bf_str, hf_field->name,
9363 (guint64)value ? tfstring->true_string : tfstring->false_string);
9370 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
9371 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
9378 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
9379 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
9386 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
9387 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
9394 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
9395 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
9399 DISSECTOR_ASSERT_NOT_REACHED();
9404 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
9409 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9410 const guint bit_offset, const crumb_spec_t *crumb_spec,
9411 guint64 *return_value)
9416 guint mask_initial_bit_offset;
9417 guint mask_greatest_bit_offset;
9421 char lbl_str[ITEM_LABEL_LENGTH];
9423 guint64 composite_bitmask;
9424 guint64 composite_bitmap;
9426 header_field_info *hf_field;
9427 const true_false_string *tfstring;
9429 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
9430 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
9432 if (hf_field->bitmask != 0) {
9433 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9434 "Incompatible use of proto_tree_add_split_bits_item_ret_val"
9435 " with field '%s' (%s) with bitmask != 0",
9436 hf_field->abbrev, hf_field->name));
9439 mask_initial_bit_offset = bit_offset % 8;
9444 mask_greatest_bit_offset = 0;
9445 composite_bitmask = 0;
9446 composite_bitmap = 0;
9448 while (crumb_spec[i].crumb_bit_length != 0) {
9449 guint64 crumb_mask, crumb_value;
9450 guint8 crumb_end_bit_offset;
9452 DISSECTOR_ASSERT(i < 64);
9453 crumb_value = tvb_get_bits64(tvb,
9454 bit_offset + crumb_spec[i].crumb_bit_offset,
9455 crumb_spec[i].crumb_bit_length,
9457 value += crumb_value;
9458 no_of_bits += crumb_spec[i].crumb_bit_length;
9460 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
9461 octet containing the initial offset.
9462 If the mask is beyond 32 bits, then give up on bit map display.
9463 This could be improved in future, probably showing a table
9464 of 32 or 64 bits per row */
9465 if (mask_greatest_bit_offset < 32) {
9466 crumb_end_bit_offset = mask_initial_bit_offset
9467 + crumb_spec[i].crumb_bit_offset
9468 + crumb_spec[i].crumb_bit_length;
9469 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
9471 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
9472 mask_greatest_bit_offset = crumb_end_bit_offset;
9474 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
9475 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
9477 /* Shift left for the next segment */
9478 value <<= crumb_spec[++i].crumb_bit_length;
9481 /* Sign extend for signed types */
9482 switch (hf_field->type) {
9491 value = ws_sign_ext64(value, no_of_bits);
9498 *return_value = value;
9501 /* Coast clear. Try and fake it */
9502 CHECK_FOR_NULL_TREE(tree);
9503 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9505 /* initialise the format string */
9508 octet_offset = bit_offset >> 3;
9510 /* Round up mask length to nearest octet */
9511 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
9512 mask_greatest_bit_offset = octet_length << 3;
9514 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
9515 It would be a useful enhancement to eliminate this restriction. */
9516 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
9517 other_decode_bitfield_value(bf_str,
9518 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
9519 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
9520 mask_greatest_bit_offset);
9523 switch (hf_field->type) {
9524 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
9526 tfstring = (const true_false_string *) &tfs_true_false;
9527 if (hf_field->strings)
9528 tfstring = (const true_false_string *) hf_field->strings;
9529 return proto_tree_add_boolean_format(tree, hfindex,
9530 tvb, octet_offset, octet_length, (guint32)value,
9532 bf_str, hf_field->name,
9533 (guint64)value ? tfstring->true_string : tfstring->false_string);
9540 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
9541 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
9548 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
9549 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
9556 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
9557 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
9564 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
9565 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
9569 DISSECTOR_ASSERT_NOT_REACHED();
9573 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
9578 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
9579 const crumb_spec_t *crumb_spec, guint16 crumb_index)
9581 header_field_info *hfinfo;
9583 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9584 proto_tree_add_text_internal(tree, tvb,
9586 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
9587 "%s crumb %d of %s (decoded above)",
9588 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
9591 crumb_spec[crumb_index].crumb_bit_length,
9598 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9599 const guint bit_offset, const gint no_of_bits,
9600 guint64 *return_value, const guint encoding)
9604 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
9605 bit_offset, no_of_bits,
9606 return_value, encoding))) {
9607 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
9608 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
9614 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
9615 tvbuff_t *tvb, const guint bit_offset,
9616 const gint no_of_bits, void *value_ptr,
9624 header_field_info *hf_field;
9626 /* We do not have to return a value, try to fake it as soon as possible */
9627 CHECK_FOR_NULL_TREE(tree);
9628 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9630 if (hf_field->bitmask != 0) {
9631 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9632 "Incompatible use of proto_tree_add_bits_format_value"
9633 " with field '%s' (%s) with bitmask != 0",
9634 hf_field->abbrev, hf_field->name));
9637 DISSECTOR_ASSERT(no_of_bits > 0);
9639 /* Byte align offset */
9640 offset = bit_offset>>3;
9643 * Calculate the number of octets used to hold the bits
9645 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
9646 length = tot_no_bits>>3;
9647 /* If we are using part of the next octet, increase length by 1 */
9648 if (tot_no_bits & 0x07)
9651 if (no_of_bits < 65) {
9652 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
9654 DISSECTOR_ASSERT_NOT_REACHED();
9658 str = decode_bits_in_field(bit_offset, no_of_bits, value);
9660 g_strlcat(str, " = ", 256+64);
9661 g_strlcat(str, hf_field->name, 256+64);
9664 * This function does not receive an actual value but a dimensionless pointer to that value.
9665 * For this reason, the type of the header field is examined in order to determine
9666 * what kind of value we should read from this address.
9667 * The caller of this function must make sure that for the specific header field type the address of
9668 * a compatible value is provided.
9670 switch (hf_field->type) {
9672 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
9673 "%s: %s", str, value_str);
9680 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
9681 "%s: %s", str, value_str);
9688 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
9689 "%s: %s", str, value_str);
9696 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
9697 "%s: %s", str, value_str);
9704 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
9705 "%s: %s", str, value_str);
9709 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
9710 "%s: %s", str, value_str);
9714 DISSECTOR_ASSERT_NOT_REACHED();
9721 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
9722 tvbuff_t *tvb, const guint bit_offset,
9723 const gint no_of_bits, void *value_ptr,
9728 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
9729 tvb, bit_offset, no_of_bits,
9730 value_ptr, value_str))) {
9731 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
9732 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
9737 #define CREATE_VALUE_STRING(dst,format,ap) \
9738 va_start(ap, format); \
9739 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
9743 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
9744 tvbuff_t *tvb, const guint bit_offset,
9745 const gint no_of_bits, guint32 value,
9746 const char *format, ...)
9750 header_field_info *hf_field;
9752 CHECK_FOR_NULL_TREE(tree);
9754 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9756 switch (hf_field->type) {
9764 DISSECTOR_ASSERT_NOT_REACHED();
9769 CREATE_VALUE_STRING(dst, format, ap);
9771 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9775 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
9776 tvbuff_t *tvb, const guint bit_offset,
9777 const gint no_of_bits, guint64 value,
9778 const char *format, ...)
9782 header_field_info *hf_field;
9784 CHECK_FOR_NULL_TREE(tree);
9786 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9788 switch (hf_field->type) {
9796 DISSECTOR_ASSERT_NOT_REACHED();
9801 CREATE_VALUE_STRING(dst, format, ap);
9803 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9807 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
9808 tvbuff_t *tvb, const guint bit_offset,
9809 const gint no_of_bits, float value,
9810 const char *format, ...)
9814 header_field_info *hf_field;
9816 CHECK_FOR_NULL_TREE(tree);
9818 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9820 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
9822 CREATE_VALUE_STRING(dst, format, ap);
9824 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9828 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
9829 tvbuff_t *tvb, const guint bit_offset,
9830 const gint no_of_bits, gint32 value,
9831 const char *format, ...)
9835 header_field_info *hf_field;
9837 CHECK_FOR_NULL_TREE(tree);
9839 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9841 switch (hf_field->type) {
9849 DISSECTOR_ASSERT_NOT_REACHED();
9854 CREATE_VALUE_STRING(dst, format, ap);
9856 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9860 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
9861 tvbuff_t *tvb, const guint bit_offset,
9862 const gint no_of_bits, gint64 value,
9863 const char *format, ...)
9867 header_field_info *hf_field;
9869 CHECK_FOR_NULL_TREE(tree);
9871 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9873 switch (hf_field->type) {
9881 DISSECTOR_ASSERT_NOT_REACHED();
9886 CREATE_VALUE_STRING(dst, format, ap);
9888 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9892 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
9893 tvbuff_t *tvb, const guint bit_offset,
9894 const gint no_of_bits, guint32 value,
9895 const char *format, ...)
9899 header_field_info *hf_field;
9901 CHECK_FOR_NULL_TREE(tree);
9903 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9905 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
9907 CREATE_VALUE_STRING(dst, format, ap);
9909 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9913 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
9914 tvbuff_t *tvb, const guint bit_offset,
9915 const gint no_of_bits, guint64 value,
9916 const char *format, ...)
9920 header_field_info *hf_field;
9922 CHECK_FOR_NULL_TREE(tree);
9924 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9926 DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
9928 CREATE_VALUE_STRING(dst, format, ap);
9930 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9934 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9935 const guint bit_offset, const gint no_of_chars)
9938 header_field_info *hfinfo;
9943 CHECK_FOR_NULL_TREE(tree);
9945 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9947 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
9949 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
9950 byte_offset = bit_offset >> 3;
9952 string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
9954 if (hfinfo->display == STR_UNICODE) {
9955 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
9958 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
9959 DISSECTOR_ASSERT(byte_length >= 0);
9960 proto_tree_set_string(PNODE_FINFO(pi), string);
9966 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9967 const guint bit_offset, const gint no_of_chars)
9970 header_field_info *hfinfo;
9975 CHECK_FOR_NULL_TREE(tree);
9977 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9979 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
9981 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
9982 byte_offset = bit_offset >> 3;
9984 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
9986 if (hfinfo->display == STR_UNICODE) {
9987 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
9990 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
9991 DISSECTOR_ASSERT(byte_length >= 0);
9992 proto_tree_set_string(PNODE_FINFO(pi), string);
9998 proto_check_field_name(const gchar *field_name)
10000 return wrs_check_charset(fld_abbrev_chars, field_name);
10004 tree_expanded(int tree_type)
10006 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10007 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
10011 tree_expanded_set(int tree_type, gboolean value)
10013 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10016 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
10018 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
10022 * Editor modelines - http://www.wireshark.org/tools/modelines.html
10025 * c-basic-offset: 8
10027 * indent-tabs-mode: t
10030 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
10031 * :indentSize=8:tabSize=8:noTabs=false: