2 * Routines for protocol tree
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include <wsutil/bits_ctz.h>
32 #include <wsutil/bits_count_ones.h>
33 #include <wsutil/sign_ext.h>
35 #include <ftypes/ftypes-int.h>
38 #include "exceptions.h"
39 #include "ptvcursor.h"
41 #include "addr_resolv.h"
42 #include "address_types.h"
45 #include "epan_dissect.h"
47 #include "wmem/wmem.h"
49 #include "asm_utils.h"
50 #include "column-utils.h"
51 #include "to_str-int.h"
53 #include "osi-utils.h"
55 #include "show_exception.h"
58 #include <wsutil/plugins.h>
59 #include <wsutil/ws_printf.h> /* ws_debug_printf/ws_g_warning */
61 /* Ptvcursor limits */
62 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
63 #define SUBTREE_MAX_LEVELS 256
65 /* Throw an exception if our tree exceeds these. */
66 /* XXX - These should probably be preferences */
67 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
68 #define MAX_TREE_LEVELS (5 * 100)
70 typedef struct __subtree_lvl {
77 subtree_lvl *pushed_tree;
78 guint8 pushed_tree_index;
79 guint8 pushed_tree_max;
85 #define cVALS(x) (const value_string*)(x)
87 /** See inlined comments.
88 @param tree the tree to append this item to
89 @param free_block a code block to call to free resources if this returns
90 @return NULL if 'tree' is null */
91 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block) \
97 /** See inlined comments.
98 @param tree the tree to append this item to
99 @param free_block a code block to call to free resources if this returns
100 @return NULL if 'tree' is null */
101 #define CHECK_FOR_NULL_TREE(tree) \
102 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
104 /** See inlined comments.
105 @param tree the tree to append this item to
106 @param hfindex field index
107 @param hfinfo header_field
108 @param free_block a code block to call to free resources if this returns
109 @return the header field matching 'hfinfo' */
110 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
111 /* If this item is not referenced we don't have to do much work \
112 at all but we should still return a node so that field items \
113 below this node (think proto_item_add_subtree()) will still \
114 have somewhere to attach to or else filtering will not work \
115 (they would be ignored since tree would be NULL). \
116 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
117 since dissectors that want to do proto_item_set_len() or \
118 other operations that dereference this would crash. \
119 We fake FT_PROTOCOL unless some clients have requested us \
122 PTREE_DATA(tree)->count++; \
123 if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
125 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
126 g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
127 /* Let the exception handler add items to the tree */ \
128 PTREE_DATA(tree)->count = 0; \
129 THROW_MESSAGE(DissectorError, \
130 wmem_strdup_printf(wmem_packet_scope(), "More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
132 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
133 if (!(PTREE_DATA(tree)->visible)) { \
134 if (PTREE_FINFO(tree)) { \
135 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
136 && (hfinfo->type != FT_PROTOCOL || \
137 PTREE_DATA(tree)->fake_protocols)) { \
139 /* just return tree back to the caller */\
145 /** See inlined comments.
146 @param tree the tree to append this item to
147 @param hfindex field index
148 @param hfinfo header_field
149 @return the header field matching 'hfinfo' */
150 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
151 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
154 /** See inlined comments.
155 @param pi the created protocol item we're about to return */
156 #define TRY_TO_FAKE_THIS_REPR(pi) \
158 if (!(PTREE_DATA(pi)->visible)) { \
159 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
160 * items string representation */ \
163 /* Same as above but returning void */
164 #define TRY_TO_FAKE_THIS_REPR_VOID(pi) \
167 if (!(PTREE_DATA(pi)->visible)) { \
168 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
169 * items string representation */ \
173 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
174 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
175 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
177 static void label_mark_truncated(char *label_str, gsize name_pos);
178 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
180 static void fill_label_boolean(field_info *fi, gchar *label_str);
181 static void fill_label_bitfield_char(field_info *fi, gchar *label_str);
182 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
183 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
184 static void fill_label_char(field_info *fi, gchar *label_str);
185 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
186 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
188 static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value);
189 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
190 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
191 static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
192 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
193 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
194 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
195 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
196 static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
197 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
198 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
201 proto_tree_add_node(proto_tree *tree, field_info *fi);
204 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
208 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
209 gint length, guint item_length, const gint encoding);
212 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
213 const gint start, const gint item_length);
216 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
217 gint start, gint *length);
220 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
222 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
225 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
227 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
229 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
231 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
233 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
235 proto_tree_set_string(field_info *fi, const char* value);
237 proto_tree_set_ax25(field_info *fi, const guint8* value);
239 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
241 proto_tree_set_vines(field_info *fi, const guint8* value);
243 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
245 proto_tree_set_ether(field_info *fi, const guint8* value);
247 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
249 proto_tree_set_ipxnet(field_info *fi, guint32 value);
251 proto_tree_set_ipv4(field_info *fi, guint32 value);
253 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
255 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
257 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
259 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
261 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
263 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
265 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
267 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
269 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
271 proto_tree_set_boolean(field_info *fi, guint64 value);
273 proto_tree_set_float(field_info *fi, float value);
275 proto_tree_set_double(field_info *fi, double value);
277 proto_tree_set_uint(field_info *fi, guint32 value);
279 proto_tree_set_int(field_info *fi, gint32 value);
281 proto_tree_set_uint64(field_info *fi, guint64 value);
283 proto_tree_set_int64(field_info *fi, gint64 value);
285 proto_tree_set_eui64(field_info *fi, const guint64 value);
287 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
289 /* Handle type length mismatch (now filterable) expert info */
290 static int proto_type_length_mismatch = -1;
291 static expert_field ei_type_length_mismatch_error = EI_INIT;
292 static expert_field ei_type_length_mismatch_warn = EI_INIT;
293 static void register_type_length_mismatch(void);
295 /* Handle number string decoding errors with expert info */
296 static int proto_number_string_decoding_error = -1;
297 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
298 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
299 static void register_number_string_decoding_error(void);
301 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
303 /* special-case header field used within proto.c */
304 static header_field_info hfi_text_only =
305 { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
306 int hf_text_only = -1;
308 /* Structure for information about a protocol */
310 const char *name; /* long description */
311 const char *short_name; /* short description */
312 const char *filter_name; /* name of this protocol in filters */
313 GPtrArray *fields; /* fields for this protocol */
314 int proto_id; /* field ID for this protocol */
315 gboolean is_enabled; /* TRUE if protocol is enabled */
316 gboolean enabled_by_default; /* TRUE if protocol is enabled by default */
317 gboolean can_toggle; /* TRUE if is_enabled can be changed */
318 GList *heur_list; /* Heuristic dissectors associated with this protocol */
321 /* List of all protocols */
322 static GList *protocols = NULL;
324 /* Deregistered fields */
325 static GPtrArray *deregistered_fields = NULL;
326 static GPtrArray *deregistered_data = NULL;
328 /* Contains information about a field when a dissector calls
329 * proto_tree_add_item. */
330 #define FIELD_INFO_NEW(pool, fi) fi = wmem_new(pool, field_info)
331 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
333 /* Contains the space for proto_nodes. */
334 #define PROTO_NODE_INIT(node) \
335 node->first_child = NULL; \
336 node->last_child = NULL; \
339 #define PROTO_NODE_FREE(pool, node) \
340 wmem_free(pool, node)
342 /* String space for protocol and field items for the GUI */
343 #define ITEM_LABEL_NEW(pool, il) \
344 il = wmem_new(pool, item_label_t);
345 #define ITEM_LABEL_FREE(pool, il) \
348 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
349 if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
350 g_error("Unregistered hf! index=%d", hfindex); \
351 DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
352 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
353 hfinfo = gpa_hfinfo.hfi[hfindex];
355 /* List which stores protocols and fields that have been registered */
356 typedef struct _gpa_hfinfo_t {
358 guint32 allocated_len;
359 header_field_info **hfi;
362 static gpa_hfinfo_t gpa_hfinfo;
364 /* Hash table of abbreviations and IDs */
365 static GHashTable *gpa_name_map = NULL;
366 static header_field_info *same_name_hfinfo;
368 * We're called repeatedly with the same field name when sorting a column.
369 * Cache our last gpa_name_map hit for faster lookups.
371 static char *last_field_name = NULL;
372 static header_field_info *last_hfinfo;
374 static void save_same_name_hfinfo(gpointer data)
376 same_name_hfinfo = (header_field_info*)data;
379 /* Cached value for VINES address type (used for FT_VINES) */
380 static int vines_address_type = -1;
382 /* Points to the first element of an array of bits, indexed by
383 a subtree item type; that array element is TRUE if subtrees of
384 an item of that type are to be expanded. */
385 static guint32 *tree_is_expanded;
387 /* Number of elements in that array. */
390 /* Name hashtables for fast detection of duplicate names */
391 static GHashTable* proto_names = NULL;
392 static GHashTable* proto_short_names = NULL;
393 static GHashTable* proto_filter_names = NULL;
396 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
398 const protocol_t *p1 = (const protocol_t *)p1_arg;
399 const protocol_t *p2 = (const protocol_t *)p2_arg;
401 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
406 * List of dissector plugins.
409 void (*register_protoinfo)(void); /* routine to call to register protocol information */
410 void (*reg_handoff)(void); /* routine to call to register dissector handoff */
413 static GSList *dissector_plugins = NULL;
416 * Callback for each plugin found.
419 check_for_dissector_plugin(GModule *handle)
422 void (*register_protoinfo)(void);
423 void (*reg_handoff)(void);
424 dissector_plugin *plugin;
427 * Do we have a register routine?
429 if (g_module_symbol(handle, "plugin_register", &gp)) {
431 register_protoinfo = (void (*)(void))gp;
435 register_protoinfo = NULL;
439 * Do we have a reg_handoff routine?
441 if (g_module_symbol(handle, "plugin_reg_handoff", &gp)) {
443 reg_handoff = (void (*)(void))gp;
451 * If we have neither, we're not a dissector plugin.
453 if (register_protoinfo == NULL && reg_handoff == NULL)
457 * Add this one to the list of dissector plugins.
459 plugin = (dissector_plugin *)g_malloc(sizeof (dissector_plugin));
460 plugin->register_protoinfo = register_protoinfo;
461 plugin->reg_handoff = reg_handoff;
462 dissector_plugins = g_slist_append(dissector_plugins, plugin);
467 register_dissector_plugin(gpointer data, gpointer user_data _U_)
469 dissector_plugin *plugin = (dissector_plugin *)data;
471 if (plugin->register_protoinfo)
472 (plugin->register_protoinfo)();
476 reg_handoff_dissector_plugin(gpointer data, gpointer user_data _U_)
478 dissector_plugin *plugin = (dissector_plugin *)data;
480 if (plugin->reg_handoff)
481 (plugin->reg_handoff)();
485 * Register dissector plugin type.
488 register_dissector_plugin_type(void)
490 add_plugin_type("dissector", check_for_dissector_plugin);
492 #endif /* HAVE_PLUGINS */
494 /* initialize data structures and register protocols and fields */
496 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
497 void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
499 gpointer client_data)
503 proto_names = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
504 proto_short_names = g_hash_table_new(wrs_str_hash, g_str_equal);
505 proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
508 gpa_hfinfo.allocated_len = 0;
509 gpa_hfinfo.hfi = NULL;
510 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
511 deregistered_fields = g_ptr_array_new();
512 deregistered_data = g_ptr_array_new();
514 /* Initialize the ftype subsystem */
517 /* Initialize the addres type subsystem */
518 address_types_initialize();
520 /* Register one special-case FT_TEXT_ONLY field for use when
521 converting wireshark to new-style proto_tree. These fields
522 are merely strings on the GUI tree; they are not filterable */
523 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
525 /* Register the pseudo-protocols used for exceptions. */
526 register_show_exception();
527 register_type_length_mismatch();
528 register_number_string_decoding_error();
530 /* Have each built-in dissector register its protocols, fields,
531 dissector tables, and dissectors to be called through a
532 handle, and do whatever one-time initialization it needs to
534 register_all_protocols_func(cb, client_data);
536 /* Now that the VINES dissector has registered it's address
537 type, grab the value for the field type */
538 vines_address_type = address_type_get_by_name("AT_VINES");
540 /* Now call the registration routines for all disssector
543 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
544 g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL);
547 /* Now call the "handoff registration" routines of all built-in
548 dissectors; those routines register the dissector in other
549 dissectors' handoff tables, and fetch any dissector handles
551 register_all_handoffs_func(cb, client_data);
554 /* Now do the same with plugins. */
556 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
557 g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL);
560 /* sort the protocols by protocol name */
561 protocols = g_list_sort(protocols, proto_compare_name);
563 /* We've assigned all the subtree type values; allocate the array
564 for them, and zero it out. */
565 tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
571 /* Free the abbrev/ID hash table */
573 g_hash_table_destroy(gpa_name_map);
576 g_free(last_field_name);
577 last_field_name = NULL;
580 protocol_t *protocol = (protocol_t *)protocols->data;
581 header_field_info *hfinfo;
582 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
583 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
585 g_slice_free(header_field_info, hfinfo);
586 if (protocol->fields) {
587 g_ptr_array_free(protocol->fields, TRUE);
589 g_list_free(protocol->heur_list);
590 protocols = g_list_remove(protocols, protocol);
595 g_hash_table_destroy(proto_names);
599 if (proto_short_names) {
600 g_hash_table_destroy(proto_short_names);
601 proto_short_names = NULL;
604 if (proto_filter_names) {
605 g_hash_table_destroy(proto_filter_names);
606 proto_filter_names = NULL;
609 if (gpa_hfinfo.allocated_len) {
611 gpa_hfinfo.allocated_len = 0;
612 g_free(gpa_hfinfo.hfi);
613 gpa_hfinfo.hfi = NULL;
616 if (deregistered_fields) {
617 g_ptr_array_free(deregistered_fields, FALSE);
618 deregistered_fields = NULL;
621 if (deregistered_data) {
622 g_ptr_array_free(deregistered_data, FALSE);
623 deregistered_data = NULL;
626 g_free(tree_is_expanded);
627 tree_is_expanded = NULL;
631 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
634 proto_node *pnode = tree;
638 if (func(pnode, data))
641 child = pnode->first_child;
642 while (child != NULL) {
644 * The routine we call might modify the child, e.g. by
645 * freeing it, so we get the child's successor before
646 * calling that routine.
649 child = current->next;
650 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
658 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
661 proto_node *pnode = tree;
665 child = pnode->first_child;
666 while (child != NULL) {
668 * The routine we call might modify the child, e.g. by
669 * freeing it, so we get the child's successor before
670 * calling that routine.
673 child = current->next;
674 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
677 if (func(pnode, data))
684 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
687 proto_node *node = tree;
693 node = node->first_child;
694 while (node != NULL) {
696 node = current->next;
697 func((proto_tree *)current, data);
702 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
704 GPtrArray *ptrs = (GPtrArray *)value;
705 gint hfid = GPOINTER_TO_UINT(key);
706 header_field_info *hfinfo;
708 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
709 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
710 /* when a field is referenced by a filter this also
711 affects the refcount for the parent protocol so we need
712 to adjust the refcount for the parent as well
714 if (hfinfo->parent != -1) {
715 header_field_info *parent_hfinfo;
716 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
717 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
719 hfinfo->ref_type = HF_REF_TYPE_NONE;
722 g_ptr_array_free(ptrs, TRUE);
726 proto_tree_free_node(proto_node *node, gpointer data _U_)
728 field_info *finfo = PNODE_FINFO(node);
730 proto_tree_children_foreach(node, proto_tree_free_node, NULL);
732 FVALUE_CLEANUP(&finfo->value);
736 proto_tree_reset(proto_tree *tree)
738 tree_data_t *tree_data = PTREE_DATA(tree);
740 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
743 if (tree_data->interesting_hfids) {
744 /* Free all the GPtrArray's in the interesting_hfids hash. */
745 g_hash_table_foreach(tree_data->interesting_hfids,
746 free_GPtrArray_value, NULL);
748 /* And then remove all values. */
749 g_hash_table_remove_all(tree_data->interesting_hfids);
752 /* Reset track of the number of children */
753 tree_data->count = 0;
755 PROTO_NODE_INIT(tree);
758 /* frees the resources that the dissection a proto_tree uses */
760 proto_tree_free(proto_tree *tree)
762 tree_data_t *tree_data = PTREE_DATA(tree);
764 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
767 if (tree_data->interesting_hfids) {
768 /* Free all the GPtrArray's in the interesting_hfids hash. */
769 g_hash_table_foreach(tree_data->interesting_hfids,
770 free_GPtrArray_value, NULL);
772 /* And then destroy the hash. */
773 g_hash_table_destroy(tree_data->interesting_hfids);
776 g_slice_free(tree_data_t, tree_data);
778 g_slice_free(proto_tree, tree);
781 /* Is the parsing being done for a visible proto_tree or an invisible one?
782 * By setting this correctly, the proto_tree creation is sped up by not
783 * having to call g_vsnprintf and copy strings around.
786 proto_tree_set_visible(proto_tree *tree, gboolean visible)
788 gboolean old_visible = PTREE_DATA(tree)->visible;
790 PTREE_DATA(tree)->visible = visible;
796 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
798 PTREE_DATA(tree)->fake_protocols = fake_protocols;
801 /* Assume dissector set only its protocol fields.
802 This function is called by dissectors and allows the speeding up of filtering
803 in wireshark; if this function returns FALSE it is safe to reset tree to NULL
804 and thus skip calling most of the expensive proto_tree_add_...()
806 If the tree is visible we implicitly assume the field is referenced.
809 proto_field_is_referenced(proto_tree *tree, int proto_id)
811 register header_field_info *hfinfo;
817 if (PTREE_DATA(tree)->visible)
820 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
821 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
824 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
831 /* Finds a record in the hfinfo array by id. */
833 proto_registrar_get_nth(guint hfindex)
835 register header_field_info *hfinfo;
837 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
842 /* Prefix initialization
843 * this allows for a dissector to register a display filter name prefix
844 * so that it can delay the initialization of the hf array as long as
848 /* compute a hash for the part before the dot of a display filter */
850 prefix_hash (gconstpointer key) {
851 /* end the string at the dot and compute its hash */
852 gchar* copy = g_strdup((const gchar *)key);
863 tmp = g_str_hash(copy);
868 /* are both strings equal up to the end or the dot? */
870 prefix_equal (gconstpointer ap, gconstpointer bp) {
871 const gchar* a = (const gchar *)ap;
872 const gchar* b = (const gchar *)bp;
878 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
880 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
881 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
883 if (ac != bc) return FALSE;
890 /* indexed by prefix, contains initializers */
891 static GHashTable* prefixes = NULL;
894 /* Register a new prefix for "delayed" initialization of field arrays */
896 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
898 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
901 g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
904 /* helper to call all prefix initializers */
906 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
907 ((prefix_initializer_t)v)((const char *)k);
911 /** Initialize every remaining uninitialized prefix. */
913 proto_initialize_all_prefixes(void) {
914 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
917 /* Finds a record in the hfinfo array by name.
918 * If it fails to find it in the already registered fields,
919 * it tries to find and call an initializer in the prefixes
920 * table and if so it looks again.
924 proto_registrar_get_byname(const char *field_name)
926 header_field_info *hfinfo;
927 prefix_initializer_t pi;
932 if (g_strcmp0(field_name, last_field_name) == 0) {
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;
948 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
950 g_hash_table_remove(prefixes, field_name);
955 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
958 g_free(last_field_name);
959 last_field_name = g_strdup(field_name);
960 last_hfinfo = hfinfo;
966 proto_registrar_get_id_byname(const char *field_name)
968 header_field_info *hfinfo;
970 hfinfo = proto_registrar_get_byname(field_name);
980 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
982 subtree_lvl *pushed_tree;
984 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
985 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
987 pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
988 DISSECTOR_ASSERT(pushed_tree != NULL);
989 if (ptvc->pushed_tree)
990 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
991 ptvc->pushed_tree = pushed_tree;
995 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
997 ptvc->pushed_tree = NULL;
998 ptvc->pushed_tree_max = 0;
999 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1000 ptvc->pushed_tree_index = 0;
1003 /* Allocates an initializes a ptvcursor_t with 3 variables:
1004 * proto_tree, tvbuff, and offset. */
1006 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
1010 ptvc = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
1013 ptvc->offset = offset;
1014 ptvc->pushed_tree = NULL;
1015 ptvc->pushed_tree_max = 0;
1016 ptvc->pushed_tree_index = 0;
1021 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1023 ptvcursor_free(ptvcursor_t *ptvc)
1025 ptvcursor_free_subtree_levels(ptvc);
1029 /* Returns tvbuff. */
1031 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1036 /* Returns current offset. */
1038 ptvcursor_current_offset(ptvcursor_t *ptvc)
1040 return ptvc->offset;
1044 ptvcursor_tree(ptvcursor_t *ptvc)
1053 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1058 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1060 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1062 subtree_lvl *subtree;
1063 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1064 ptvcursor_new_subtree_levels(ptvc);
1066 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1067 subtree->tree = ptvc->tree;
1069 ptvc->pushed_tree_index++;
1070 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1073 /* pops a subtree */
1075 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1077 subtree_lvl *subtree;
1079 if (ptvc->pushed_tree_index <= 0)
1082 ptvc->pushed_tree_index--;
1083 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1084 if (subtree->it != NULL)
1085 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1087 ptvc->tree = subtree->tree;
1090 /* saves the current tvb offset and the item in the current subtree level */
1092 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1094 subtree_lvl *subtree;
1096 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1098 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1100 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1103 /* Creates a subtree and adds it to the cursor as the working tree but does not
1104 * save the old working tree */
1106 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1108 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1113 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1115 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1116 if (length == SUBTREE_UNDEFINED_LENGTH)
1117 ptvcursor_subtree_set_item(ptvc, it);
1118 return ptvcursor_tree(ptvc);
1121 /* Add an item to the tree and create a subtree
1122 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1123 * In this case, when the subtree will be closed, the parent item length will
1124 * be equal to the advancement of the cursor since the creation of the subtree.
1127 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1128 const guint encoding, gint ett_subtree)
1132 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1133 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1137 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1139 /* Add a text node to the tree and create a subtree
1140 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1141 * In this case, when the subtree will be closed, the item length will be equal
1142 * to the advancement of the cursor since the creation of the subtree.
1145 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1146 gint ett_subtree, const char *format, ...)
1150 header_field_info *hfinfo;
1153 tree = ptvcursor_tree(ptvc);
1155 CHECK_FOR_NULL_TREE(tree);
1157 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1159 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1160 ptvcursor_current_offset(ptvc), length);
1162 TRY_TO_FAKE_THIS_REPR(pi);
1164 va_start(ap, format);
1165 proto_tree_set_representation(pi, format, ap);
1168 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1171 /* Add a text-only node, leaving it to our caller to fill the text in */
1173 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1180 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1185 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1187 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1188 const char *format, ...)
1192 header_field_info *hfinfo;
1195 /* If we're fetching until the end of the TVB, only validate
1196 * that the offset is within range.
1200 tvb_ensure_bytes_exist(tvb, start, length);
1202 CHECK_FOR_NULL_TREE(tree);
1204 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1206 pi = proto_tree_add_text_node(tree, tvb, start, length);
1208 TRY_TO_FAKE_THIS_REPR(pi);
1210 va_start(ap, format);
1211 proto_tree_set_representation(pi, format, ap);
1217 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1219 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1220 gint length, const char *format, va_list ap)
1223 header_field_info *hfinfo;
1226 /* If we're fetching until the end of the TVB, only validate
1227 * that the offset is within range.
1231 tvb_ensure_bytes_exist(tvb, start, length);
1233 CHECK_FOR_NULL_TREE(tree);
1235 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1237 pi = proto_tree_add_text_node(tree, tvb, start, length);
1239 TRY_TO_FAKE_THIS_REPR(pi);
1241 proto_tree_set_representation(pi, format, ap);
1246 /* Add a text-only node that creates a subtree underneath.
1249 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1251 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1254 /* Add a text-only node that creates a subtree underneath.
1257 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1263 va_start(ap, format);
1264 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1267 if (tree_item != NULL)
1270 pt = proto_item_add_subtree(pi, idx);
1275 /* Add a text-only node for debugging purposes. The caller doesn't need
1276 * to worry about tvbuff, start, or length. Debug message gets sent to
1279 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1284 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1287 va_start(ap, format);
1288 proto_tree_set_representation(pi, format, ap);
1291 va_start(ap, format);
1292 vprintf(format, ap);
1294 ws_debug_printf("\n");
1300 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1303 header_field_info *hfinfo;
1305 CHECK_FOR_NULL_TREE(tree);
1307 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1309 pi = proto_tree_add_text_node(tree, tvb, start, length);
1311 TRY_TO_FAKE_THIS_REPR(pi);
1313 proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1319 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1322 header_field_info *hfinfo;
1324 CHECK_FOR_NULL_TREE(tree);
1326 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1328 pi = proto_tree_add_text_node(tree, tvb, start, length);
1330 TRY_TO_FAKE_THIS_REPR(pi);
1332 proto_item_set_text(pi, "%s", tvb_format_text_wsp(tvb, start, length));
1337 void proto_report_dissector_bug(const char *message)
1339 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1342 THROW_MESSAGE(DissectorError, message);
1345 /* We could probably get away with changing is_error to a minimum length value. */
1347 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1350 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1352 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1356 THROW(ReportedBoundsError);
1361 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1364 gboolean length_error;
1369 value = tvb_get_guint8(tvb, offset);
1373 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1374 : tvb_get_ntohs(tvb, offset);
1378 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1379 : tvb_get_ntoh24(tvb, offset);
1383 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1384 : tvb_get_ntohl(tvb, offset);
1389 length_error = TRUE;
1392 length_error = FALSE;
1393 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1394 : tvb_get_ntohl(tvb, offset);
1396 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1402 static inline guint64
1403 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1406 gboolean length_error;
1411 value = tvb_get_guint8(tvb, offset);
1415 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1416 : tvb_get_ntohs(tvb, offset);
1420 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1421 : tvb_get_ntoh24(tvb, offset);
1425 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1426 : tvb_get_ntohl(tvb, offset);
1430 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1431 : tvb_get_ntoh40(tvb, offset);
1435 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1436 : tvb_get_ntoh48(tvb, offset);
1440 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1441 : tvb_get_ntoh56(tvb, offset);
1445 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1446 : tvb_get_ntoh64(tvb, offset);
1451 length_error = TRUE;
1454 length_error = FALSE;
1455 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1456 : tvb_get_ntoh64(tvb, offset);
1458 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1465 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1468 gboolean length_error;
1473 value = (gint8)tvb_get_guint8(tvb, offset);
1477 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1478 : tvb_get_ntohs(tvb, offset));
1482 value = encoding ? tvb_get_letoh24(tvb, offset)
1483 : tvb_get_ntoh24(tvb, offset);
1484 if (value & 0x00800000) {
1485 /* Sign bit is set; sign-extend it. */
1486 value |= 0xFF000000;
1491 value = encoding ? tvb_get_letohl(tvb, offset)
1492 : tvb_get_ntohl(tvb, offset);
1497 length_error = TRUE;
1500 length_error = FALSE;
1501 value = encoding ? tvb_get_letohl(tvb, offset)
1502 : tvb_get_ntohl(tvb, offset);
1504 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1510 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1511 * be cast-able as a gint64. This is weird, but what the code has always done.
1513 static inline guint64
1514 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1516 guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1521 value = ws_sign_ext64(value, 56);
1524 value = ws_sign_ext64(value, 48);
1527 value = ws_sign_ext64(value, 40);
1530 value = ws_sign_ext64(value, 32);
1533 value = ws_sign_ext64(value, 24);
1536 value = ws_sign_ext64(value, 16);
1539 value = ws_sign_ext64(value, 8);
1547 static inline const guint8 *
1548 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1549 gint length, gint *ret_length, const guint encoding)
1552 length = tvb_ensure_captured_length_remaining(tvb, start);
1554 *ret_length = length;
1555 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1558 /* For FT_STRINGZ */
1559 static inline const guint8 *
1560 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1561 gint start, gint length, gint *ret_length, const guint encoding)
1563 const guint8 *value;
1566 report_type_length_mismatch(tree, "a string", length, TRUE);
1569 /* This can throw an exception */
1570 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1571 } else if (length == 0) {
1574 /* In this case, length signifies the length of the string.
1576 * This could either be a null-padded string, which doesn't
1577 * necessarily have a '\0' at the end, or a null-terminated
1578 * string, with a trailing '\0'. (Yes, there are cases
1579 * where you have a string that's both counted and null-
1582 * In the first case, we must allocate a buffer of length
1583 * "length+1", to make room for a trailing '\0'.
1585 * In the second case, we don't assume that there is a
1586 * trailing '\0' there, as the packet might be malformed.
1587 * (XXX - should we throw an exception if there's no
1588 * trailing '\0'?) Therefore, we allocate a buffer of
1589 * length "length+1", and put in a trailing '\0', just to
1592 * (XXX - this would change if we made string values counted
1593 * rather than null-terminated.)
1595 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1597 *ret_length = length;
1601 /* For FT_UINT_STRING */
1602 static inline const guint8 *
1603 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1604 tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1605 const guint encoding)
1608 const guint8 *value;
1610 /* I believe it's ok if this is called with a NULL tree */
1611 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1612 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1614 *ret_length = length;
1618 /* For FT_STRINGZPAD */
1619 static inline const guint8 *
1620 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1621 gint length, gint *ret_length, const guint encoding)
1624 * XXX - currently, string values are null-
1625 * terminated, so a "zero-padded" string
1626 * isn't special. If we represent string
1627 * values as something that includes a counted
1628 * array of bytes, we'll need to strip
1632 length = tvb_ensure_captured_length_remaining(tvb, start);
1634 *ret_length = length;
1635 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1638 /* this can be called when there is no tree, so don't add that as a param */
1640 get_time_value(tvbuff_t *tvb, const gint start, const gint length, const guint encoding,
1641 nstime_t *time_stamp, const gboolean is_relative)
1646 /* relative timestamps don't do TOD/NTP */
1648 (encoding != (ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN)) &&
1649 (encoding != (ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN)) )
1651 /* XXX: I think this should call REPORT_DISSECTOR_BUG(), but
1652 the existing code didn't do that, so I'm not either */
1658 case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1660 * 4-byte UNIX epoch, possibly followed by
1661 * 4-byte fractional time in nanoseconds,
1664 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1666 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1668 time_stamp->nsecs = 0;
1671 case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1673 * 4-byte UNIX epoch, possibly followed by
1674 * 4-byte fractional time in nanoseconds,
1675 * both little-endian.
1677 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1679 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1681 time_stamp->nsecs = 0;
1684 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1686 * TOD time stamp, big-endian.
1688 /* XXX - where should this go? */
1689 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800)
1691 todsecs = tvb_get_ntoh64(tvb, start) >> 12;
1692 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1693 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1696 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1698 * TOD time stamp, big-endian.
1700 todsecs = tvb_get_letoh64(tvb, start) >> 12 ;
1701 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1702 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1705 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1707 * NTP time stamp, big-endian.
1710 /* XXX - where should this go? */
1711 #define NTP_BASETIME G_GUINT64_CONSTANT(2208988800)
1713 /* We need a temporary variable here so the unsigned math
1714 * works correctly (for years > 2036 according to RFC 2030
1717 tmpsecs = tvb_get_ntohl(tvb, start);
1719 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1721 time_stamp->secs = tmpsecs; /* 0 */
1725 * We're using nanoseconds here (and we will
1726 * display nanoseconds), but NTP's timestamps
1727 * have a precision in microseconds or greater.
1728 * Round to 1 microsecond.
1730 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1731 time_stamp->nsecs *= 1000;
1733 time_stamp->nsecs = 0;
1737 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1739 * NTP time stamp, big-endian.
1741 tmpsecs = tvb_get_letohl(tvb, start);
1743 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1745 time_stamp->secs = tmpsecs; /* 0 */
1749 * We're using nanoseconds here (and we will
1750 * display nanoseconds), but NTP's timestamps
1751 * have a precision in microseconds or greater.
1752 * Round to 1 microsecond.
1754 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1755 time_stamp->nsecs *= 1000;
1757 time_stamp->nsecs = 0;
1760 case ENC_TIME_NTP_BASE_ZERO|ENC_BIG_ENDIAN:
1762 * DDS NTP time stamp, big-endian.
1765 #define NTP_BASETIME_ZERO G_GUINT64_CONSTANT(0)
1767 tmpsecs = tvb_get_ntohl(tvb, start);
1769 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1771 time_stamp->secs = tmpsecs; /* 0 */
1775 * We're using nanoseconds here (and we will
1776 * display nanoseconds), but NTP's timestamps
1777 * have a precision in microseconds or greater.
1778 * Round to 1 microsecond.
1780 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1781 time_stamp->nsecs *= 1000;
1783 time_stamp->nsecs = 0;
1787 case ENC_TIME_NTP_BASE_ZERO|ENC_LITTLE_ENDIAN:
1789 * NTP time stamp, big-endian.
1791 tmpsecs = tvb_get_letohl(tvb, start);
1793 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1795 time_stamp->secs = tmpsecs; /* 0 */
1796 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1799 * We're using nanoseconds here (and we will
1800 * display nanoseconds), but NTP's timestamps
1801 * have a precision in microseconds or greater.
1802 * Round to 1 microsecond.
1804 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1805 time_stamp->nsecs *= 1000;
1807 time_stamp->nsecs = 0;
1812 DISSECTOR_ASSERT_NOT_REACHED();
1818 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
1820 const header_field_info *hfinfo = fi->hfinfo;
1822 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
1823 GPtrArray *ptrs = NULL;
1825 if (tree_data->interesting_hfids == NULL) {
1826 /* Initialize the hash because we now know that it is needed */
1827 tree_data->interesting_hfids =
1828 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
1829 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
1830 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
1831 GINT_TO_POINTER(hfinfo->id));
1835 /* First element triggers the creation of pointer array */
1836 ptrs = g_ptr_array_new();
1837 g_hash_table_insert(tree_data->interesting_hfids,
1838 GINT_TO_POINTER(hfinfo->id), ptrs);
1841 g_ptr_array_add(ptrs, fi);
1845 /* Add an item to a proto_tree, using the text label registered to that item;
1846 the item is extracted from the tvbuff handed to it. */
1848 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
1849 tvbuff_t *tvb, gint start, gint length,
1856 const char *stringval;
1857 nstime_t time_stamp;
1858 gboolean length_error;
1860 switch (new_fi->hfinfo->type) {
1862 /* no value to set for FT_NONE */
1866 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
1870 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
1875 * Map all non-zero values to little-endian for
1876 * backwards compatibility.
1879 encoding = ENC_LITTLE_ENDIAN;
1880 n = get_uint_value(tree, tvb, start, length, encoding);
1881 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
1883 /* Instead of calling proto_item_set_len(), since we don't yet
1884 * have a proto_item, we set the field_info's length ourselves. */
1885 new_fi->length = n + length;
1890 * Map all non-zero values to little-endian for
1891 * backwards compatibility.
1894 encoding = ENC_LITTLE_ENDIAN;
1895 proto_tree_set_boolean(new_fi,
1896 get_uint64_value(tree, tvb, start, length, encoding));
1900 /* XXX - make these just FT_UINT? */
1906 * Map all non-zero values to little-endian for
1907 * backwards compatibility.
1910 encoding = ENC_LITTLE_ENDIAN;
1911 proto_tree_set_uint(new_fi,
1912 get_uint_value(tree, tvb, start, length, encoding));
1920 * Map all non-zero values to little-endian for
1921 * backwards compatibility.
1924 encoding = ENC_LITTLE_ENDIAN;
1925 proto_tree_set_uint64(new_fi,
1926 get_uint64_value(tree, tvb, start, length, encoding));
1929 /* XXX - make these just FT_INT? */
1935 * Map all non-zero values to little-endian for
1936 * backwards compatibility.
1939 encoding = ENC_LITTLE_ENDIAN;
1940 proto_tree_set_int(new_fi,
1941 get_int_value(tree, tvb, start, length, encoding));
1949 * Map all non-zero values to little-endian for
1950 * backwards compatibility.
1953 encoding = ENC_LITTLE_ENDIAN;
1954 proto_tree_set_int64(new_fi,
1955 get_int64_value(tree, tvb, start, length, encoding));
1960 * Map all non-zero values to little-endian for
1961 * backwards compatibility.
1964 encoding = ENC_LITTLE_ENDIAN;
1965 if (length != FT_IPv4_LEN) {
1966 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
1967 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
1969 value = tvb_get_ipv4(tvb, start);
1971 * NOTE: to support code written when
1972 * proto_tree_add_item() took a gboolean as its
1973 * last argument, with FALSE meaning "big-endian"
1974 * and TRUE meaning "little-endian", we treat any
1975 * non-zero value of "encoding" as meaning
1978 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
1982 if (length != FT_IPXNET_LEN) {
1983 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
1984 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
1986 proto_tree_set_ipxnet(new_fi,
1987 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
1991 if (length != FT_IPv6_LEN) {
1992 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
1993 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
1995 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
1999 if (length != FT_FCWWN_LEN) {
2000 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2001 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2003 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2008 length_error = length < 7 ? TRUE : FALSE;
2009 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2011 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2015 if (length != VINES_ADDR_LEN) {
2016 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2017 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2019 proto_tree_set_vines_tvb(new_fi, tvb, start);
2023 if (length != FT_ETHER_LEN) {
2024 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2025 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2027 proto_tree_set_ether_tvb(new_fi, tvb, start);
2032 * Map all non-zero values to little-endian for
2033 * backwards compatibility.
2036 encoding = ENC_LITTLE_ENDIAN;
2037 if (length != FT_EUI64_LEN) {
2038 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2039 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2041 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2045 * Map all non-zero values to little-endian for
2046 * backwards compatibility.
2049 encoding = ENC_LITTLE_ENDIAN;
2050 if (length != FT_GUID_LEN) {
2051 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2052 report_type_length_mismatch(tree, "a GUID", length, length_error);
2054 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2059 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2063 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2068 * NOTE: to support code written when
2069 * proto_tree_add_item() took a gboolean as its
2070 * last argument, with FALSE meaning "big-endian"
2071 * and TRUE meaning "little-endian", we treat any
2072 * non-zero value of "encoding" as meaning
2075 * At some point in the future, we might
2076 * support non-IEEE-binary floating-point
2077 * formats in the encoding as well
2078 * (IEEE decimal, System/3x0, VAX).
2081 encoding = ENC_LITTLE_ENDIAN;
2083 length_error = length < 4 ? TRUE : FALSE;
2084 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2087 floatval = tvb_get_letohieee_float(tvb, start);
2089 floatval = tvb_get_ntohieee_float(tvb, start);
2090 proto_tree_set_float(new_fi, floatval);
2095 * NOTE: to support code written when
2096 * proto_tree_add_item() took a gboolean as its
2097 * last argument, with FALSE meaning "big-endian"
2098 * and TRUE meaning "little-endian", we treat any
2099 * non-zero value of "encoding" as meaning
2102 * At some point in the future, we might
2103 * support non-IEEE-binary floating-point
2104 * formats in the encoding as well
2105 * (IEEE decimal, System/3x0, VAX).
2107 if (encoding == TRUE)
2108 encoding = ENC_LITTLE_ENDIAN;
2110 length_error = length < 8 ? TRUE : FALSE;
2111 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2114 doubleval = tvb_get_letohieee_double(tvb, start);
2116 doubleval = tvb_get_ntohieee_double(tvb, start);
2117 proto_tree_set_double(new_fi, doubleval);
2121 stringval = get_string_value(wmem_packet_scope(),
2122 tvb, start, length, &length, encoding);
2123 proto_tree_set_string(new_fi, stringval);
2125 /* Instead of calling proto_item_set_len(), since we
2126 * don't yet have a proto_item, we set the
2127 * field_info's length ourselves.
2129 * XXX - our caller can't use that length to
2130 * advance an offset unless they arrange that
2131 * there always be a protocol tree into which
2132 * we're putting this item.
2134 new_fi->length = length;
2138 stringval = get_stringz_value(wmem_packet_scope(),
2139 tree, tvb, start, length, &length, encoding);
2140 proto_tree_set_string(new_fi, stringval);
2142 /* Instead of calling proto_item_set_len(),
2143 * since we don't yet have a proto_item, we
2144 * set the field_info's length ourselves.
2146 * XXX - our caller can't use that length to
2147 * advance an offset unless they arrange that
2148 * there always be a protocol tree into which
2149 * we're putting this item.
2151 new_fi->length = length;
2154 case FT_UINT_STRING:
2156 * NOTE: to support code written when
2157 * proto_tree_add_item() took a gboolean as its
2158 * last argument, with FALSE meaning "big-endian"
2159 * and TRUE meaning "little-endian", if the
2160 * encoding value is TRUE, treat that as
2161 * ASCII with a little-endian length.
2163 * This won't work for code that passes
2164 * arbitrary non-zero values; that code
2165 * will need to be fixed.
2167 if (encoding == TRUE)
2168 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2169 stringval = get_uint_string_value(wmem_packet_scope(),
2170 tree, tvb, start, length, &length, encoding);
2171 proto_tree_set_string(new_fi, stringval);
2173 /* Instead of calling proto_item_set_len(), since we
2174 * don't yet have a proto_item, we set the
2175 * field_info's length ourselves.
2177 * XXX - our caller can't use that length to
2178 * advance an offset unless they arrange that
2179 * there always be a protocol tree into which
2180 * we're putting this item.
2182 new_fi->length = length;
2186 stringval = get_stringzpad_value(wmem_packet_scope(),
2187 tvb, start, length, &length, encoding);
2188 proto_tree_set_string(new_fi, stringval);
2190 /* Instead of calling proto_item_set_len(), since we
2191 * don't yet have a proto_item, we set the
2192 * field_info's length ourselves.
2194 * XXX - our caller can't use that length to
2195 * advance an offset unless they arrange that
2196 * there always be a protocol tree into which
2197 * we're putting this item.
2199 new_fi->length = length;
2202 case FT_ABSOLUTE_TIME:
2204 * Absolute times can be in any of a number of
2205 * formats, and they can be big-endian or
2208 * Historically FT_TIMEs were only timespecs;
2209 * the only question was whether they were stored
2210 * in big- or little-endian format.
2212 * For backwards compatibility, we interpret an
2213 * encoding of 1 as meaning "little-endian timespec",
2214 * so that passing TRUE is interpreted as that.
2216 if (encoding == TRUE)
2217 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2219 if (length != 8 && length != 4) {
2220 length_error = length < 4 ? TRUE : FALSE;
2221 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2224 get_time_value(tvb, start, length, encoding, &time_stamp, FALSE);
2226 proto_tree_set_time(new_fi, &time_stamp);
2229 case FT_RELATIVE_TIME:
2231 * Relative times can be in any of a number of
2232 * formats, and they can be big-endian or
2235 * Historically FT_TIMEs were only timespecs;
2236 * the only question was whether they were stored
2237 * in big- or little-endian format.
2239 * For backwards compatibility, we interpret an
2240 * encoding of 1 as meaning "little-endian timespec",
2241 * so that passing TRUE is interpreted as that.
2243 if (encoding == TRUE)
2244 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2246 if (length != 8 && length != 4) {
2247 length_error = length < 4 ? TRUE : FALSE;
2248 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2251 get_time_value(tvb, start, length, encoding, &time_stamp, TRUE);
2253 proto_tree_set_time(new_fi, &time_stamp);
2255 case FT_IEEE_11073_SFLOAT:
2257 encoding = ENC_LITTLE_ENDIAN;
2259 length_error = length < 2 ? TRUE : FALSE;
2260 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2263 fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2266 case FT_IEEE_11073_FLOAT:
2268 encoding = ENC_LITTLE_ENDIAN;
2270 length_error = length < 4 ? TRUE : FALSE;
2271 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2276 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2277 new_fi->hfinfo->type,
2278 ftype_name(new_fi->hfinfo->type));
2279 DISSECTOR_ASSERT_NOT_REACHED();
2282 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2284 /* Don't add new node to proto_tree until now so that any exceptions
2285 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2286 /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2287 * to know which item caused exception? */
2288 pi = proto_tree_add_node(tree, new_fi);
2294 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2295 const gint start, gint length,
2296 const guint encoding, gint32 *retval)
2298 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2302 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2304 switch (hfinfo->type){
2311 DISSECTOR_ASSERT_NOT_REACHED();
2314 /* length validation for native number encoding caught by get_uint_value() */
2315 /* length has to be -1 or > 0 regardless of encoding */
2316 if (length < -1 || length == 0)
2317 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2318 "Invalid length %d passed to proto_tree_add_item_ret_int",
2321 if (encoding & ENC_STRING) {
2322 REPORT_DISSECTOR_BUG("wrong encoding");
2324 /* I believe it's ok if this is called with a NULL tree */
2325 value = get_int_value(tree, tvb, start, length, encoding);
2330 CHECK_FOR_NULL_TREE(tree);
2332 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2334 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2336 proto_tree_set_int(new_fi, value);
2338 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2340 return proto_tree_add_node(tree, new_fi);
2344 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2345 const gint start, gint length,
2346 const guint encoding, guint32 *retval)
2348 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2352 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2354 switch (hfinfo->type){
2362 DISSECTOR_ASSERT_NOT_REACHED();
2365 /* length validation for native number encoding caught by get_uint_value() */
2366 /* length has to be -1 or > 0 regardless of encoding */
2367 if (length < -1 || length == 0)
2368 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2369 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2372 if (encoding & ENC_STRING) {
2373 REPORT_DISSECTOR_BUG("wrong encoding");
2375 /* I believe it's ok if this is called with a NULL tree */
2376 /* XXX - modify if we ever support EBCDIC FT_CHAR */
2377 value = get_uint_value(tree, tvb, start, length, encoding);
2382 CHECK_FOR_NULL_TREE(tree);
2384 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2386 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2388 proto_tree_set_uint(new_fi, value);
2390 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2392 return proto_tree_add_node(tree, new_fi);
2396 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
2398 const gint start, gint length,
2399 const guint encoding,
2400 wmem_allocator_t *scope,
2401 const guint8 **retval,
2404 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2406 const guint8 *value;
2408 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2410 switch (hfinfo->type){
2412 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
2415 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
2417 case FT_UINT_STRING:
2418 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
2421 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
2424 DISSECTOR_ASSERT_NOT_REACHED();
2430 CHECK_FOR_NULL_TREE(tree);
2432 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2434 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2436 proto_tree_set_string(new_fi, value);
2438 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2440 return proto_tree_add_node(tree, new_fi);
2444 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2445 const gint start, gint length,
2446 const guint encoding, wmem_allocator_t *scope,
2447 const guint8 **retval)
2449 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
2450 tvb, start, length, encoding, scope, retval, &length);
2454 * Validates that field length bytes are available starting from
2455 * start (pos/neg). Throws an exception if they aren't.
2458 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2459 gint start, gint length)
2466 if (hfinfo->type == FT_STRINGZ) {
2467 /* If we're fetching until the end of the TVB, only validate
2468 * that the offset is within range.
2474 tvb_ensure_bytes_exist(tvb, start, size);
2477 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2478 and returns proto_item* */
2480 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
2481 const guint encoding)
2484 header_field_info *hfinfo;
2488 offset = ptvc->offset;
2489 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2490 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
2491 test_length(hfinfo, ptvc->tvb, offset, item_length);
2493 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2494 item_length, encoding);
2496 CHECK_FOR_NULL_TREE(ptvc->tree);
2498 /* Coast clear. Try and fake it */
2499 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2501 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2503 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2504 offset, length, encoding);
2507 /* Add an item to a proto_tree, using the text label registered to that item;
2508 the item is extracted from the tvbuff handed to it. */
2510 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
2511 const gint start, gint length, const guint encoding)
2516 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2518 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2519 test_length(hfinfo, tvb, start, item_length);
2521 CHECK_FOR_NULL_TREE(tree);
2523 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2525 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2527 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2531 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2532 const gint start, gint length, const guint encoding)
2534 register header_field_info *hfinfo;
2536 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2537 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
2540 /* Add an item to a proto_tree, using the text label registered to that item;
2541 the item is extracted from the tvbuff handed to it.
2543 Return the length of the item through the pointer. */
2545 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
2546 tvbuff_t *tvb, const gint start,
2547 gint length, const guint encoding,
2554 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2556 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2557 test_length(hfinfo, tvb, start, item_length);
2561 * We need to get the correct item length here.
2562 * That's normally done by proto_tree_new_item(),
2563 * but we won't be calling it.
2565 *lenretval = get_full_length(hfinfo, tvb, start, length,
2566 item_length, encoding);
2570 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2572 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2574 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2575 *lenretval = new_fi->length;
2580 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2581 const gint start, gint length,
2582 const guint encoding, gint *lenretval)
2584 register header_field_info *hfinfo;
2586 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2587 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
2590 /* which FT_ types can use proto_tree_add_bytes_item() */
2591 static inline gboolean
2592 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
2594 return (type == FT_BYTES ||
2595 type == FT_UINT_BYTES ||
2597 type == FT_REL_OID ||
2598 type == FT_SYSTEM_ID );
2601 /* Note: this does no validation that the byte array of an FT_OID or
2602 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
2603 so I think it's ok to continue not validating it?
2606 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2607 const gint start, gint length, const guint encoding,
2608 GByteArray *retval, gint *endoff, gint *err)
2611 GByteArray *bytes = retval;
2612 GByteArray *created_bytes = NULL;
2615 header_field_info *hfinfo;
2616 gboolean generate = (bytes || tree) ? TRUE : FALSE;
2618 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2620 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2622 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
2623 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
2625 /* length has to be -1 or > 0 regardless of encoding */
2626 /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
2627 if (length < -1 || length == 0) {
2628 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2629 "Invalid length %d passed to proto_tree_add_bytes_item for %s",
2630 length, ftype_name(hfinfo->type)));
2633 if (encoding & ENC_STR_NUM) {
2634 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
2637 if (generate && (encoding & ENC_STR_HEX)) {
2638 if (hfinfo->type == FT_UINT_BYTES) {
2639 /* can't decode FT_UINT_BYTES from strings */
2640 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
2641 "FT_UINT_BYTES type, but as ENC_STR_HEX");
2645 /* caller doesn't care about return value, but we need it to
2646 call tvb_get_string_bytes() and set the tree later */
2647 bytes = created_bytes = g_byte_array_new();
2650 /* bytes might be NULL after this, but can't add expert error until later */
2651 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
2653 /* grab the errno now before it gets overwritten */
2656 else if (generate) {
2657 tvb_ensure_bytes_exist(tvb, start, length);
2660 /* caller doesn't care about return value, but we need it to
2661 call tvb_get_string_bytes() and set the tree later */
2662 bytes = created_bytes = g_byte_array_new();
2665 if (hfinfo->type == FT_UINT_BYTES) {
2666 n = length; /* n is now the "header" length */
2667 length = get_uint_value(tree, tvb, start, n, encoding);
2668 /* length is now the value's length; only store the value in the array */
2669 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
2671 else if (length > 0) {
2672 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
2676 *endoff = start + n + length;
2679 if (err) *err = saved_err;
2681 CHECK_FOR_NULL_TREE_AND_FREE(tree,
2684 g_byte_array_free(created_bytes, TRUE);
2685 created_bytes = NULL;
2689 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
2692 g_byte_array_free(created_bytes, TRUE);
2693 created_bytes = NULL;
2697 /* n will be zero except when it's a FT_UINT_BYTES */
2698 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
2700 if (encoding & ENC_STRING) {
2701 if (saved_err == ERANGE)
2702 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2703 else if (!bytes || saved_err != 0)
2704 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2707 proto_tree_set_bytes_gbytearray(new_fi, bytes);
2709 proto_tree_set_bytes(new_fi, NULL, 0);
2712 g_byte_array_free(created_bytes, TRUE);
2715 /* n will be zero except when it's a FT_UINT_BYTES */
2716 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
2719 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2722 return proto_tree_add_node(tree, new_fi);
2727 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2728 const gint start, gint length, const guint encoding,
2729 nstime_t *retval, gint *endoff, gint *err)
2732 nstime_t time_stamp;
2734 header_field_info *hfinfo;
2736 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2738 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2740 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
2742 /* length has to be -1 or > 0 regardless of encoding */
2743 if (length < -1 || length == 0) {
2744 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2745 "Invalid length %d passed to proto_tree_add_time_item", length));
2748 time_stamp.secs = 0;
2749 time_stamp.nsecs = 0;
2751 if (encoding & ENC_STR_TIME_MASK) {
2752 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
2753 /* grab the errno now before it gets overwritten */
2757 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
2759 if (length != 8 && length != 4) {
2760 const gboolean length_error = length < 4 ? TRUE : FALSE;
2762 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2764 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2767 tvb_ensure_bytes_exist(tvb, start, length);
2768 get_time_value(tvb, start, length, encoding, &time_stamp, is_relative);
2769 if (endoff) *endoff = length;
2772 if (err) *err = saved_err;
2775 retval->secs = time_stamp.secs;
2776 retval->nsecs = time_stamp.nsecs;
2779 CHECK_FOR_NULL_TREE(tree);
2781 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2783 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2785 proto_tree_set_time(new_fi, &time_stamp);
2787 if (encoding & ENC_STRING) {
2788 if (saved_err == ERANGE)
2789 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2790 else if (saved_err == EDOM)
2791 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2795 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2798 return proto_tree_add_node(tree, new_fi);
2801 /* Add a FT_NONE to a proto_tree */
2803 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
2804 const gint start, gint length, const char *format,
2809 header_field_info *hfinfo;
2811 CHECK_FOR_NULL_TREE(tree);
2813 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2815 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
2817 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2819 TRY_TO_FAKE_THIS_REPR(pi);
2821 va_start(ap, format);
2822 proto_tree_set_representation(pi, format, ap);
2825 /* no value to set for FT_NONE */
2829 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
2830 * offset, and returns proto_item* */
2832 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
2833 const guint encoding)
2837 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
2843 /* Advance the ptvcursor's offset within its tvbuff without
2844 * adding anything to the proto_tree. */
2846 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
2848 ptvc->offset += length;
2853 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
2855 fvalue_set_protocol(&fi->value, tvb, field_data);
2858 /* Add a FT_PROTOCOL to a proto_tree */
2860 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2861 gint start, gint length, const char *format, ...)
2865 header_field_info *hfinfo;
2866 gchar* protocol_rep;
2868 CHECK_FOR_NULL_TREE(tree);
2870 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2872 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
2874 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2876 va_start(ap, format);
2877 protocol_rep = g_strdup_vprintf(format, ap);
2878 proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length)), protocol_rep);
2879 g_free(protocol_rep);
2882 TRY_TO_FAKE_THIS_REPR(pi);
2884 va_start(ap, format);
2885 proto_tree_set_representation(pi, format, ap);
2891 /* Add a FT_BYTES to a proto_tree */
2893 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2894 gint length, const guint8 *start_ptr)
2897 header_field_info *hfinfo;
2900 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2901 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2902 test_length(hfinfo, tvb, start, item_length);
2904 CHECK_FOR_NULL_TREE(tree);
2906 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2908 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2910 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2911 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
2916 /* Add a FT_BYTES to a proto_tree */
2918 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2919 gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
2922 header_field_info *hfinfo;
2925 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2926 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length);
2927 test_length(hfinfo, tvb, start, item_length);
2929 CHECK_FOR_NULL_TREE(tree);
2931 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2933 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2935 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
2936 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
2942 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2943 gint start, gint length,
2944 const guint8 *start_ptr,
2945 const char *format, ...)
2949 header_field_info *hfinfo;
2952 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2953 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2954 test_length(hfinfo, tvb, start, item_length);
2956 CHECK_FOR_NULL_TREE(tree);
2958 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2961 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2964 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2965 tvb_get_ptr(tvb, start, length));
2967 va_start(ap, format);
2968 proto_tree_set_representation_value(pi, format, ap);
2975 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2976 gint start, gint length, const guint8 *start_ptr,
2977 const char *format, ...)
2981 header_field_info *hfinfo;
2984 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2985 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2986 test_length(hfinfo, tvb, start, item_length);
2988 CHECK_FOR_NULL_TREE(tree);
2990 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2993 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2996 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2997 tvb_get_ptr(tvb, start, length));
2999 TRY_TO_FAKE_THIS_REPR(pi);
3001 va_start(ap, format);
3002 proto_tree_set_representation(pi, format, ap);
3009 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
3013 DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
3015 bytes = g_byte_array_new();
3017 g_byte_array_append(bytes, start_ptr, length);
3019 fvalue_set_byte_array(&fi->value, bytes);
3024 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
3026 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
3030 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
3034 DISSECTOR_ASSERT(value != NULL);
3036 bytes = byte_array_dup(value);
3038 fvalue_set_byte_array(&fi->value, bytes);
3041 /* Add a FT_*TIME to a proto_tree */
3043 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3044 gint length, const nstime_t *value_ptr)
3047 header_field_info *hfinfo;
3049 CHECK_FOR_NULL_TREE(tree);
3051 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3053 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3055 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3056 proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
3062 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3063 gint start, gint length, nstime_t *value_ptr,
3064 const char *format, ...)
3069 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3071 va_start(ap, format);
3072 proto_tree_set_representation_value(pi, format, ap);
3080 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3081 gint start, gint length, nstime_t *value_ptr,
3082 const char *format, ...)
3087 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3089 TRY_TO_FAKE_THIS_REPR(pi);
3091 va_start(ap, format);
3092 proto_tree_set_representation(pi, format, ap);
3099 /* Set the FT_*TIME value */
3101 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
3103 DISSECTOR_ASSERT(value_ptr != NULL);
3105 fvalue_set_time(&fi->value, value_ptr);
3108 /* Add a FT_IPXNET to a proto_tree */
3110 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3111 gint length, guint32 value)
3114 header_field_info *hfinfo;
3116 CHECK_FOR_NULL_TREE(tree);
3118 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3120 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
3122 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3123 proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
3129 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3130 gint start, gint length, guint32 value,
3131 const char *format, ...)
3136 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3138 va_start(ap, format);
3139 proto_tree_set_representation_value(pi, format, ap);
3147 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3148 gint start, gint length, guint32 value,
3149 const char *format, ...)
3154 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3156 TRY_TO_FAKE_THIS_REPR(pi);
3158 va_start(ap, format);
3159 proto_tree_set_representation(pi, format, ap);
3166 /* Set the FT_IPXNET value */
3168 proto_tree_set_ipxnet(field_info *fi, guint32 value)
3170 fvalue_set_uinteger(&fi->value, value);
3173 /* Add a FT_IPv4 to a proto_tree */
3175 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3176 gint length, guint32 value)
3179 header_field_info *hfinfo;
3181 CHECK_FOR_NULL_TREE(tree);
3183 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3185 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
3187 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3188 proto_tree_set_ipv4(PNODE_FINFO(pi), value);
3194 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3195 gint start, gint length, guint32 value,
3196 const char *format, ...)
3201 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3203 va_start(ap, format);
3204 proto_tree_set_representation_value(pi, format, ap);
3212 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3213 gint start, gint length, guint32 value,
3214 const char *format, ...)
3219 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3221 TRY_TO_FAKE_THIS_REPR(pi);
3223 va_start(ap, format);
3224 proto_tree_set_representation(pi, format, ap);
3231 /* Set the FT_IPv4 value */
3233 proto_tree_set_ipv4(field_info *fi, guint32 value)
3235 fvalue_set_uinteger(&fi->value, value);
3238 /* Add a FT_IPv6 to a proto_tree */
3240 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3241 gint length, const struct e_in6_addr *value_ptr)
3244 header_field_info *hfinfo;
3246 CHECK_FOR_NULL_TREE(tree);
3248 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3250 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
3252 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3253 proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
3259 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3260 gint start, gint length,
3261 const struct e_in6_addr *value_ptr,
3262 const char *format, ...)
3267 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3269 va_start(ap, format);
3270 proto_tree_set_representation_value(pi, format, ap);
3278 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3279 gint start, gint length,
3280 const struct e_in6_addr *value_ptr,
3281 const char *format, ...)
3286 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3288 TRY_TO_FAKE_THIS_REPR(pi);
3290 va_start(ap, format);
3291 proto_tree_set_representation(pi, format, ap);
3298 /* Set the FT_IPv6 value */
3300 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
3302 DISSECTOR_ASSERT(value_ptr != NULL);
3303 fvalue_set_bytes(&fi->value, value_ptr);
3307 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3309 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
3312 /* Set the FT_FCWWN value */
3314 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
3316 DISSECTOR_ASSERT(value_ptr != NULL);
3317 fvalue_set_bytes(&fi->value, value_ptr);
3321 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3323 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
3326 /* Add a FT_GUID to a proto_tree */
3328 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3329 gint length, const e_guid_t *value_ptr)
3332 header_field_info *hfinfo;
3334 CHECK_FOR_NULL_TREE(tree);
3336 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3338 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
3340 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3341 proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
3347 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3348 gint start, gint length,
3349 const e_guid_t *value_ptr,
3350 const char *format, ...)
3355 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3357 va_start(ap, format);
3358 proto_tree_set_representation_value(pi, format, ap);
3366 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3367 gint start, gint length, const e_guid_t *value_ptr,
3368 const char *format, ...)
3373 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3375 TRY_TO_FAKE_THIS_REPR(pi);
3377 va_start(ap, format);
3378 proto_tree_set_representation(pi, format, ap);
3385 /* Set the FT_GUID value */
3387 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
3389 DISSECTOR_ASSERT(value_ptr != NULL);
3390 fvalue_set_guid(&fi->value, value_ptr);
3394 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
3395 const guint encoding)
3399 tvb_get_guid(tvb, start, &guid, encoding);
3400 proto_tree_set_guid(fi, &guid);
3403 /* Add a FT_OID to a proto_tree */
3405 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3406 gint length, const guint8* value_ptr)
3409 header_field_info *hfinfo;
3411 CHECK_FOR_NULL_TREE(tree);
3413 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3415 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
3417 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3418 proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
3424 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3425 gint start, gint length,
3426 const guint8* value_ptr,
3427 const char *format, ...)
3432 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3434 va_start(ap, format);
3435 proto_tree_set_representation_value(pi, format, ap);
3443 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3444 gint start, gint length, const guint8* value_ptr,
3445 const char *format, ...)
3450 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3452 TRY_TO_FAKE_THIS_REPR(pi);
3454 va_start(ap, format);
3455 proto_tree_set_representation(pi, format, ap);
3462 /* Set the FT_OID value */
3464 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
3468 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3470 bytes = g_byte_array_new();
3472 g_byte_array_append(bytes, value_ptr, length);
3474 fvalue_set_byte_array(&fi->value, bytes);
3478 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3480 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
3483 /* Set the FT_SYSTEM_ID value */
3485 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
3489 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3491 bytes = g_byte_array_new();
3493 g_byte_array_append(bytes, value_ptr, length);
3495 fvalue_set_byte_array(&fi->value, bytes);
3499 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3501 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
3504 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
3505 * own copy of string, and frees it when the proto_tree is destroyed. */
3507 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3508 gint length, const char* value)
3511 header_field_info *hfinfo;
3513 CHECK_FOR_NULL_TREE(tree);
3515 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3517 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
3519 if (hfinfo->display == STR_UNICODE) {
3520 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
3523 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3524 DISSECTOR_ASSERT(length >= 0);
3525 proto_tree_set_string(PNODE_FINFO(pi), value);
3531 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3532 gint start, gint length, const char* value,
3539 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3541 va_start(ap, format);
3542 proto_tree_set_representation_value(pi, format, ap);
3550 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3551 gint start, gint length, const char* value,
3552 const char *format, ...)
3557 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3559 TRY_TO_FAKE_THIS_REPR(pi);
3561 va_start(ap, format);
3562 proto_tree_set_representation(pi, format, ap);
3569 /* Set the FT_STRING value */
3571 proto_tree_set_string(field_info *fi, const char* value)
3574 fvalue_set_string(&fi->value, value);
3576 fvalue_set_string(&fi->value, "[ Null ]");
3580 /* Set the FT_AX25 value */
3582 proto_tree_set_ax25(field_info *fi, const guint8* value)
3584 fvalue_set_bytes(&fi->value, value);
3588 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3590 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
3593 /* Set the FT_VINES value */
3595 proto_tree_set_vines(field_info *fi, const guint8* value)
3597 fvalue_set_bytes(&fi->value, value);
3601 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3603 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
3606 /* Add a FT_ETHER to a proto_tree */
3608 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3609 gint length, const guint8* value)
3612 header_field_info *hfinfo;
3614 CHECK_FOR_NULL_TREE(tree);
3616 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3618 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
3620 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3621 proto_tree_set_ether(PNODE_FINFO(pi), value);
3627 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3628 gint start, gint length, const guint8* value,
3629 const char *format, ...)
3634 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3636 va_start(ap, format);
3637 proto_tree_set_representation_value(pi, format, ap);
3645 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3646 gint start, gint length, const guint8* value,
3647 const char *format, ...)
3652 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3654 TRY_TO_FAKE_THIS_REPR(pi);
3656 va_start(ap, format);
3657 proto_tree_set_representation(pi, format, ap);
3664 /* Set the FT_ETHER value */
3666 proto_tree_set_ether(field_info *fi, const guint8* value)
3668 fvalue_set_bytes(&fi->value, value);
3672 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3674 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
3677 /* Add a FT_BOOLEAN to a proto_tree */
3679 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3680 gint length, guint32 value)
3683 header_field_info *hfinfo;
3685 CHECK_FOR_NULL_TREE(tree);
3687 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3689 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3691 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3692 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3698 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
3699 tvbuff_t *tvb, gint start, gint length,
3700 guint32 value, const char *format, ...)
3705 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3707 va_start(ap, format);
3708 proto_tree_set_representation_value(pi, format, ap);
3716 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3717 gint start, gint length, guint32 value,
3718 const char *format, ...)
3723 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3725 TRY_TO_FAKE_THIS_REPR(pi);
3727 va_start(ap, format);
3728 proto_tree_set_representation(pi, format, ap);
3736 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3737 gint length, guint64 value)
3740 header_field_info *hfinfo;
3742 CHECK_FOR_NULL_TREE(tree);
3744 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3746 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3748 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3749 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3754 /* Set the FT_BOOLEAN value */
3756 proto_tree_set_boolean(field_info *fi, guint64 value)
3758 proto_tree_set_uint64(fi, value);
3761 /* Generate, into "buf", a string showing the bits of a bitfield.
3762 Return a pointer to the character after that string. */
3763 /*XXX this needs a buf_len check */
3765 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3773 bit = G_GUINT64_CONSTANT(1) << (width - 1);
3776 /* This bit is part of the field. Show its value. */
3782 /* This bit is not part of the field. */
3797 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3801 p = other_decode_bitfield_value(buf, val, mask, width);
3802 p = g_stpcpy(p, " = ");
3807 /* Add a FT_FLOAT to a proto_tree */
3809 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3810 gint length, float value)
3813 header_field_info *hfinfo;
3815 CHECK_FOR_NULL_TREE(tree);
3817 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3819 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
3821 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3822 proto_tree_set_float(PNODE_FINFO(pi), value);
3828 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3829 gint start, gint length, float value,
3830 const char *format, ...)
3835 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3837 va_start(ap, format);
3838 proto_tree_set_representation_value(pi, format, ap);
3846 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3847 gint start, gint length, float value,
3848 const char *format, ...)
3853 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3855 TRY_TO_FAKE_THIS_REPR(pi);
3857 va_start(ap, format);
3858 proto_tree_set_representation(pi, format, ap);
3865 /* Set the FT_FLOAT value */
3867 proto_tree_set_float(field_info *fi, float value)
3869 fvalue_set_floating(&fi->value, value);
3872 /* Add a FT_DOUBLE to a proto_tree */
3874 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3875 gint length, double value)
3878 header_field_info *hfinfo;
3880 CHECK_FOR_NULL_TREE(tree);
3882 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3884 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
3886 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3887 proto_tree_set_double(PNODE_FINFO(pi), value);
3893 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3894 gint start, gint length, double value,
3895 const char *format, ...)
3900 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3902 va_start(ap, format);
3903 proto_tree_set_representation_value(pi, format, ap);
3911 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3912 gint start, gint length, double value,
3913 const char *format, ...)
3918 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3920 TRY_TO_FAKE_THIS_REPR(pi);
3922 va_start(ap, format);
3923 proto_tree_set_representation(pi, format, ap);
3930 /* Set the FT_DOUBLE value */
3932 proto_tree_set_double(field_info *fi, double value)
3934 fvalue_set_floating(&fi->value, value);
3937 /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
3939 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3940 gint length, guint32 value)
3942 proto_item *pi = NULL;
3943 header_field_info *hfinfo;
3945 CHECK_FOR_NULL_TREE(tree);
3947 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3949 switch (hfinfo->type) {
3956 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3957 proto_tree_set_uint(PNODE_FINFO(pi), value);
3961 DISSECTOR_ASSERT_NOT_REACHED();
3968 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3969 gint start, gint length, guint32 value,
3970 const char *format, ...)
3975 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3977 va_start(ap, format);
3978 proto_tree_set_representation_value(pi, format, ap);
3986 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3987 gint start, gint length, guint32 value,
3988 const char *format, ...)
3993 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3995 TRY_TO_FAKE_THIS_REPR(pi);
3997 va_start(ap, format);
3998 proto_tree_set_representation(pi, format, ap);
4005 /* Set the FT_UINT{8,16,24,32} value */
4007 proto_tree_set_uint(field_info *fi, guint32 value)
4009 header_field_info *hfinfo;
4012 hfinfo = fi->hfinfo;
4015 if (hfinfo->bitmask) {
4016 /* Mask out irrelevant portions */
4017 integer &= (guint32)(hfinfo->bitmask);
4020 integer >>= hfinfo_bitshift(hfinfo);
4023 fvalue_set_uinteger(&fi->value, integer);
4026 /* Add FT_UINT{40,48,56,64} to a proto_tree */
4028 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4029 gint length, guint64 value)
4031 proto_item *pi = NULL;
4032 header_field_info *hfinfo;
4034 CHECK_FOR_NULL_TREE(tree);
4036 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4038 switch (hfinfo->type) {
4044 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4045 proto_tree_set_uint64(PNODE_FINFO(pi), value);
4049 DISSECTOR_ASSERT_NOT_REACHED();
4056 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4057 gint start, gint length, guint64 value,
4058 const char *format, ...)
4063 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4065 va_start(ap, format);
4066 proto_tree_set_representation_value(pi, format, ap);
4074 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4075 gint start, gint length, guint64 value,
4076 const char *format, ...)
4081 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4083 TRY_TO_FAKE_THIS_REPR(pi);
4085 va_start(ap, format);
4086 proto_tree_set_representation(pi, format, ap);
4093 /* Set the FT_UINT{40,48,56,64} value */
4095 proto_tree_set_uint64(field_info *fi, guint64 value)
4097 header_field_info *hfinfo;
4100 hfinfo = fi->hfinfo;
4103 if (hfinfo->bitmask) {
4104 /* Mask out irrelevant portions */
4105 integer &= hfinfo->bitmask;
4108 integer >>= hfinfo_bitshift(hfinfo);
4111 fvalue_set_uinteger64(&fi->value, integer);
4114 /* Add FT_INT{8,16,24,32} to a proto_tree */
4116 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4117 gint length, gint32 value)
4119 proto_item *pi = NULL;
4120 header_field_info *hfinfo;
4122 CHECK_FOR_NULL_TREE(tree);
4124 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4126 switch (hfinfo->type) {
4131 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4132 proto_tree_set_int(PNODE_FINFO(pi), value);
4136 DISSECTOR_ASSERT_NOT_REACHED();
4143 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4144 gint start, gint length, gint32 value,
4145 const char *format, ...)
4150 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4152 va_start(ap, format);
4153 proto_tree_set_representation_value(pi, format, ap);
4161 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4162 gint start, gint length, gint32 value,
4163 const char *format, ...)
4168 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4170 TRY_TO_FAKE_THIS_REPR(pi);
4172 va_start(ap, format);
4173 proto_tree_set_representation(pi, format, ap);
4180 /* Set the FT_INT{8,16,24,32} value */
4182 proto_tree_set_int(field_info *fi, gint32 value)
4184 header_field_info *hfinfo;
4188 hfinfo = fi->hfinfo;
4189 integer = (guint32) value;
4191 if (hfinfo->bitmask) {
4192 /* Mask out irrelevant portions */
4193 integer &= (guint32)(hfinfo->bitmask);
4196 integer >>= hfinfo_bitshift(hfinfo);
4198 no_of_bits = ws_count_ones(hfinfo->bitmask);
4199 integer = ws_sign_ext32(integer, no_of_bits);
4202 fvalue_set_sinteger(&fi->value, integer);
4205 /* Add FT_INT{40,48,56,64} to a proto_tree */
4207 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4208 gint length, gint64 value)
4210 proto_item *pi = NULL;
4211 header_field_info *hfinfo;
4213 CHECK_FOR_NULL_TREE(tree);
4215 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4217 switch (hfinfo->type) {
4222 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4223 proto_tree_set_int64(PNODE_FINFO(pi), value);
4227 DISSECTOR_ASSERT_NOT_REACHED();
4234 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4235 gint start, gint length, gint64 value,
4236 const char *format, ...)
4241 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4243 va_start(ap, format);
4244 proto_tree_set_representation_value(pi, format, ap);
4251 /* Set the FT_INT{40,48,56,64} value */
4253 proto_tree_set_int64(field_info *fi, gint64 value)
4255 header_field_info *hfinfo;
4259 hfinfo = fi->hfinfo;
4262 if (hfinfo->bitmask) {
4263 /* Mask out irrelevant portions */
4264 integer &= hfinfo->bitmask;
4267 integer >>= hfinfo_bitshift(hfinfo);
4269 no_of_bits = ws_count_ones(hfinfo->bitmask);
4270 integer = ws_sign_ext64(integer, no_of_bits);
4273 fvalue_set_sinteger64(&fi->value, integer);
4277 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4278 gint start, gint length, gint64 value,
4279 const char *format, ...)
4284 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4286 TRY_TO_FAKE_THIS_REPR(pi);
4288 va_start(ap, format);
4289 proto_tree_set_representation(pi, format, ap);
4296 /* Add a FT_EUI64 to a proto_tree */
4298 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4299 gint length, const guint64 value)
4302 header_field_info *hfinfo;
4304 CHECK_FOR_NULL_TREE(tree);
4306 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4308 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
4310 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4311 proto_tree_set_eui64(PNODE_FINFO(pi), value);
4317 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4318 gint start, gint length, const guint64 value,
4319 const char *format, ...)
4324 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4326 va_start(ap, format);
4327 proto_tree_set_representation_value(pi, format, ap);
4335 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4336 gint start, gint length, const guint64 value,
4337 const char *format, ...)
4342 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4344 TRY_TO_FAKE_THIS_REPR(pi);
4346 va_start(ap, format);
4347 proto_tree_set_representation(pi, format, ap);
4354 /* Set the FT_EUI64 value */
4356 proto_tree_set_eui64(field_info *fi, const guint64 value)
4358 fvalue_set_uinteger64(&fi->value, value);
4361 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
4365 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
4367 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
4371 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
4373 proto_tree_add_node(proto_tree *tree, field_info *fi)
4375 proto_node *pnode, *tnode, *sibling;
4380 * Restrict our depth. proto_tree_traverse_pre_order and
4381 * proto_tree_traverse_post_order (and possibly others) are recursive
4382 * so we need to be mindful of our stack size.
4384 if (tree->first_child == NULL) {
4385 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
4387 if (G_UNLIKELY(depth > MAX_TREE_LEVELS)) {
4388 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
4389 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u)",
4391 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
4397 * Make sure "tree" is ready to have subtrees under it, by
4398 * checking whether it's been given an ett_ value.
4400 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
4401 * node of the protocol tree. That node is not displayed,
4402 * so it doesn't need an ett_ value to remember whether it
4406 tfi = PNODE_FINFO(tnode);
4407 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
4408 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4409 "\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
4410 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
4411 /* XXX - is it safe to continue here? */
4414 pnode = wmem_new(PNODE_POOL(tree), proto_node);
4415 PROTO_NODE_INIT(pnode);
4416 pnode->parent = tnode;
4417 PNODE_FINFO(pnode) = fi;
4418 pnode->tree_data = PTREE_DATA(tree);
4420 if (tnode->last_child != NULL) {
4421 sibling = tnode->last_child;
4422 DISSECTOR_ASSERT(sibling->next == NULL);
4423 sibling->next = pnode;
4425 tnode->first_child = pnode;
4426 tnode->last_child = pnode;
4428 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
4430 return (proto_item *)pnode;
4434 /* Generic way to allocate field_info and add to proto_tree.
4435 * Sets *pfi to address of newly-allocated field_info struct */
4437 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
4444 get_hfi_length(hfinfo, tvb, start, length, &item_length);
4445 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4446 pi = proto_tree_add_node(tree, fi);
4453 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
4456 gint length_remaining;
4459 * We only allow a null tvbuff if the item has a zero length,
4460 * i.e. if there's no data backing it.
4462 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
4465 * XXX - in some protocols, there are 32-bit unsigned length
4466 * fields, so lengths in protocol tree and tvbuff routines
4467 * should really be unsigned. We should have, for those
4468 * field types for which "to the end of the tvbuff" makes sense,
4469 * additional routines that take no length argument and
4470 * add fields that run to the end of the tvbuff.
4472 if (*length == -1) {
4474 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
4475 * FT_STRINGZPAD fields, a length of -1 means "set the
4476 * length to what remains in the tvbuff".
4478 * The assumption is either that
4480 * 1) the length of the item can only be determined
4481 * by dissection (typically true of items with
4482 * subitems, which are probably FT_NONE or
4487 * 2) if the tvbuff is "short" (either due to a short
4488 * snapshot length or due to lack of reassembly of
4489 * fragments/segments/whatever), we want to display
4490 * what's available in the field (probably FT_BYTES
4491 * or FT_STRING) and then throw an exception later
4495 * 3) the field is defined to be "what's left in the
4498 * so we set the length to what remains in the tvbuff so
4499 * that, if we throw an exception while dissecting, it
4500 * has what is probably the right value.
4502 * For FT_STRINGZ, it means "the string is null-terminated,
4503 * not null-padded; set the length to the actual length
4504 * of the string", and if the tvbuff if short, we just
4505 * throw an exception.
4507 * It's not valid for any other type of field. For those
4508 * fields, we treat -1 the same way we treat other
4509 * negative values - we assume the length is a Really
4510 * Big Positive Number, and throw a ReportedBoundsError
4511 * exception, under the assumption that the Really Big
4512 * Length would run past the end of the packet.
4514 switch (hfinfo->type) {
4522 * We allow FT_PROTOCOLs to be zero-length -
4523 * for example, an ONC RPC NULL procedure has
4524 * neither arguments nor reply, so the
4525 * payload for that protocol is empty.
4527 * We also allow the others to be zero-length -
4528 * because that's the way the code has been for a
4531 * However, we want to ensure that the start
4532 * offset is not *past* the byte past the end
4533 * of the tvbuff: we throw an exception in that
4536 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
4537 DISSECTOR_ASSERT(*length >= 0);
4542 * Leave the length as -1, so our caller knows
4548 THROW(ReportedBoundsError);
4549 DISSECTOR_ASSERT_NOT_REACHED();
4551 *item_length = *length;
4553 *item_length = *length;
4554 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
4556 * These types are for interior nodes of the
4557 * tree, and don't have data associated with
4558 * them; if the length is negative (XXX - see
4559 * above) or goes past the end of the tvbuff,
4560 * cut it short at the end of the tvbuff.
4561 * That way, if this field is selected in
4562 * Wireshark, we don't highlight stuff past
4563 * the end of the data.
4565 /* XXX - what to do, if we don't have a tvb? */
4567 length_remaining = tvb_captured_length_remaining(tvb, start);
4568 if (*item_length < 0 ||
4569 (*item_length > 0 &&
4570 (length_remaining < *item_length)))
4571 *item_length = length_remaining;
4574 if (*item_length < 0) {
4575 THROW(ReportedBoundsError);
4581 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
4582 gint length, guint item_length, const gint encoding)
4587 * We need to get the correct item length here.
4588 * That's normally done by proto_tree_new_item(),
4589 * but we won't be calling it.
4591 switch (hfinfo->type) {
4597 * The length is the specified length.
4603 * Map all non-zero values to little-endian for
4604 * backwards compatibility.
4606 n = get_uint_value(NULL, tvb, start, length,
4607 encoding ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
4613 /* XXX - make these just FT_UINT? */
4622 /* XXX - make these just FT_INT? */
4647 * The length is the specified length.
4653 report_type_length_mismatch(NULL, "a string", length, TRUE);
4656 /* This can throw an exception */
4657 /* XXX - do this without fetching the string? */
4658 tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
4660 item_length = length;
4663 case FT_UINT_STRING:
4664 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
4669 case FT_ABSOLUTE_TIME:
4670 case FT_RELATIVE_TIME:
4671 case FT_IEEE_11073_SFLOAT:
4672 case FT_IEEE_11073_FLOAT:
4674 * The length is the specified length.
4679 g_error("hfinfo->type %d (%s) not handled\n",
4681 ftype_name(hfinfo->type));
4682 DISSECTOR_ASSERT_NOT_REACHED();
4689 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4690 const gint start, const gint item_length)
4694 FIELD_INFO_NEW(PNODE_POOL(tree), fi);
4696 fi->hfinfo = hfinfo;
4698 fi->start += (tvb)?tvb_raw_offset(tvb):0;
4699 fi->length = item_length;
4702 if (!PTREE_DATA(tree)->visible)
4703 FI_SET_FLAG(fi, FI_HIDDEN);
4704 fvalue_init(&fi->value, fi->hfinfo->type);
4707 /* add the data source tvbuff */
4708 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
4710 fi->appendix_start = 0;
4711 fi->appendix_length = 0;
4716 /* If the protocol tree is to be visible, set the representation of a
4717 proto_tree entry with the name of the field for the item and with
4718 the value formatted with the supplied printf-style format and
4721 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
4725 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
4726 * items string representation */
4727 if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
4729 field_info *fi = PITEM_FINFO(pi);
4730 header_field_info *hf;
4732 DISSECTOR_ASSERT(fi);
4736 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4737 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
4741 if (IS_FT_UINT(hf->type))
4742 val = fvalue_get_uinteger(&fi->value);
4744 val = fvalue_get_uinteger64(&fi->value);
4746 val <<= hfinfo_bitshift(hf);
4748 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
4749 ret = (int) (p - fi->rep->representation);
4752 /* put in the hf name */
4753 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
4755 /* If possible, Put in the value of the string */
4756 if (ret < ITEM_LABEL_LENGTH) {
4757 ret += g_vsnprintf(fi->rep->representation + ret,
4758 ITEM_LABEL_LENGTH - ret, format, ap);
4760 if (ret >= ITEM_LABEL_LENGTH) {
4761 /* Uh oh, we don't have enough room. Tell the user
4762 * that the field is truncated.
4764 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4769 /* If the protocol tree is to be visible, set the representation of a
4770 proto_tree entry with the representation formatted with the supplied
4771 printf-style format and argument list. */
4773 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
4775 int ret; /*tmp return value */
4776 field_info *fi = PITEM_FINFO(pi);
4778 DISSECTOR_ASSERT(fi);
4780 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4781 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4782 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
4784 if (ret >= ITEM_LABEL_LENGTH) {
4785 /* Uh oh, we don't have enough room. Tell the user
4786 * that the field is truncated.
4788 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4794 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
4796 switch (hfinfo->display) {
4798 return format_text(string, strlen(string));
4801 return format_text_wsp(string, strlen(string));
4804 /* XXX, format_unicode_text() */
4808 return format_text(string, strlen(string));
4812 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
4814 gsize res = g_strlcpy(dest, src, dest_size);
4816 if (res > dest_size)
4821 static header_field_info *
4822 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
4824 header_field_info *dup_hfinfo;
4826 if (hfinfo->same_name_prev_id == -1)
4828 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
4833 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
4835 g_free(last_field_name);
4836 last_field_name = NULL;
4838 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
4839 /* No hfinfo with the same name */
4840 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
4844 if (hfinfo->same_name_next) {
4845 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
4848 if (hfinfo->same_name_prev_id != -1) {
4849 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
4850 same_name_prev->same_name_next = hfinfo->same_name_next;
4851 if (!hfinfo->same_name_next) {
4852 /* It's always the latest added hfinfo which is stored in gpa_name_map */
4853 g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
4858 /* -------------------------- */
4860 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
4861 gchar *result, gchar *expr, const int size)
4866 ipv4_addr_and_mask *ipv4;
4867 struct e_in6_addr *ipv6;
4869 guint32 n_addr; /* network-order IPv4 address */
4871 const true_false_string *tfstring;
4873 int len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
4875 field_info *finfo = NULL;
4876 header_field_info* hfinfo;
4877 const gchar *abbrev = NULL;
4879 const char *hf_str_val;
4880 char number_buf[48];
4881 const char *number_out;
4887 g_assert(field_ids != NULL);
4888 while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
4889 field_id = *field_idx;
4890 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
4892 /* do we need to rewind ? */
4896 if (occurrence < 0) {
4897 /* Search other direction */
4898 while (hfinfo->same_name_prev_id != -1) {
4899 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
4904 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
4906 if (!finfos || !(len = g_ptr_array_len(finfos))) {
4907 if (occurrence < 0) {
4908 hfinfo = hfinfo->same_name_next;
4910 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4915 /* Are there enough occurrences of the field? */
4916 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
4917 if (occurrence < 0) {
4918 hfinfo = hfinfo->same_name_next;
4920 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4926 /* Calculate single index or set outer bounderies */
4927 if (occurrence < 0) {
4928 i = occurrence + len + prev_len;
4930 } else if (occurrence > 0) {
4931 i = occurrence - 1 - prev_len;
4938 prev_len += len; /* Count handled occurrences */
4941 finfo = (field_info *)g_ptr_array_index(finfos, i);
4943 if (offset_r && (offset_r < (size - 2)))
4944 result[offset_r++] = ',';
4946 if (offset_e && (offset_e < (size - 2)))
4947 expr[offset_e++] = ',';
4949 switch (hfinfo->type) {
4951 case FT_NONE: /* Nothing to add */
4952 if (offset_r == 0) {
4954 } else if (result[offset_r-1] == ',') {
4955 result[offset_r-1] = '\0';
4960 /* prevent multiple "yes" entries by setting result directly */
4961 g_strlcpy(result, "Yes", size);
4966 bytes = (guint8 *)fvalue_get(&finfo->value);
4968 switch(hfinfo->display)
4971 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
4974 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
4977 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
4980 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
4984 if (prefs.display_byte_fields_with_spaces)
4986 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
4990 str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
4994 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
4995 wmem_free(NULL, str);
4998 if (hfinfo->display & BASE_ALLOW_ZERO) {
4999 offset_r += protoo_strlcpy(result+offset_r, "<none>", size-offset_r);
5001 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
5006 case FT_ABSOLUTE_TIME:
5007 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
5008 offset_r += protoo_strlcpy(result+offset_r,
5011 wmem_free(NULL, tmpbuf);
5014 case FT_RELATIVE_TIME:
5015 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
5016 offset_r += protoo_strlcpy(result+offset_r,
5019 wmem_free(NULL, tmpbuf);
5023 number64 = fvalue_get_uinteger64(&finfo->value);
5024 tfstring = (const true_false_string *)&tfs_true_false;
5025 if (hfinfo->strings) {
5026 tfstring = (const struct true_false_string*) hfinfo->strings;
5028 offset_r += protoo_strlcpy(result+offset_r,
5030 tfstring->true_string :
5031 tfstring->false_string, size-offset_r);
5033 offset_e += protoo_strlcpy(expr+offset_e,
5034 number64 ? "1" : "0", size-offset_e);
5039 number = fvalue_get_uinteger(&finfo->value);
5041 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5042 gchar tmp[ITEM_LABEL_LENGTH];
5043 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5045 DISSECTOR_ASSERT(fmtfunc);
5046 fmtfunc(tmp, number);
5048 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5050 } else if (hfinfo->strings) {
5051 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5054 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
5056 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5059 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5061 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5064 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5065 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5067 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5069 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5072 offset_e = (int)strlen(expr);
5075 /* XXX - make these just FT_NUMBER? */
5086 number = IS_FT_INT(hfinfo->type) ?
5087 (guint32) fvalue_get_sinteger(&finfo->value) :
5088 fvalue_get_uinteger(&finfo->value);
5090 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5091 gchar tmp[ITEM_LABEL_LENGTH];
5092 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5094 DISSECTOR_ASSERT(fmtfunc);
5095 fmtfunc(tmp, number);
5097 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5099 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
5100 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5103 number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
5105 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5108 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
5110 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5113 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5114 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5116 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5118 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5121 offset_e = (int)strlen(expr);
5133 number64 = IS_FT_INT(hfinfo->type) ?
5134 (guint64) fvalue_get_sinteger64(&finfo->value) :
5135 fvalue_get_uinteger64(&finfo->value);
5137 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5138 gchar tmp[ITEM_LABEL_LENGTH];
5139 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
5141 DISSECTOR_ASSERT(fmtfunc64);
5142 fmtfunc64(tmp, number64);
5143 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5144 } else if (hfinfo->strings) {
5145 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
5148 number_out = hfinfo_number_value_format_display64(hfinfo, BASE_DEC, number_buf, number64);
5150 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5153 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
5155 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5158 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5159 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5161 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
5163 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5166 offset_e = (int)strlen(expr);
5170 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
5171 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5172 wmem_free(NULL, str);
5176 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&finfo->value);
5177 n_addr = ipv4_get_net_order_addr(ipv4);
5178 set_address (&addr, AT_IPv4, 4, &n_addr);
5179 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5180 offset_r = (int)strlen(result);
5184 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
5185 set_address (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
5186 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5187 offset_r = (int)strlen(result);
5191 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
5192 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5193 offset_r = (int)strlen(result);
5197 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
5198 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5199 offset_r = (int)strlen(result);
5203 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
5204 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5205 wmem_free(NULL, str);
5209 bytes = (guint8 *)fvalue_get(&finfo->value);
5210 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5211 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5212 wmem_free(NULL, str);
5214 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5215 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5216 wmem_free(NULL, str);
5220 bytes = (guint8 *)fvalue_get(&finfo->value);
5221 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5222 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5223 wmem_free(NULL, str);
5225 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5226 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5227 wmem_free(NULL, str);
5231 bytes = (guint8 *)fvalue_get(&finfo->value);
5232 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
5233 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5234 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5235 wmem_free(NULL, str);
5239 g_snprintf(result+offset_r, size-offset_r,
5240 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
5241 offset_r = (int)strlen(result);
5245 g_snprintf(result+offset_r, size-offset_r,
5246 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
5247 offset_r = (int)strlen(result);
5252 case FT_UINT_STRING:
5254 bytes = (guint8 *)fvalue_get(&finfo->value);
5255 offset_r += protoo_strlcpy(result+offset_r,
5256 hfinfo_format_text(hfinfo, bytes),
5260 case FT_IEEE_11073_SFLOAT:
5261 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5262 g_snprintf(result+offset_r, size-offset_r,
5265 wmem_free(NULL, str);
5266 offset_r = (int)strlen(result);
5269 case FT_IEEE_11073_FLOAT:
5270 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5271 g_snprintf(result+offset_r, size-offset_r,
5274 offset_r = (int)strlen(result);
5275 wmem_free(NULL, str);
5278 case FT_IPXNET: /*XXX really No column custom ?*/
5281 g_error("hfinfo->type %d (%s) not handled\n",
5283 ftype_name(hfinfo->type));
5284 DISSECTOR_ASSERT_NOT_REACHED();
5290 switch (hfinfo->type) {
5314 /* for these types, "expr" is filled in the loop above */
5318 /* for all others, just copy "result" to "expr" */
5319 g_strlcpy(expr, result, size);
5324 /* Store abbrev for return value */
5325 abbrev = hfinfo->abbrev;
5328 if (occurrence == 0) {
5329 /* Fetch next hfinfo with same name (abbrev) */
5330 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5337 return abbrev ? abbrev : "";
5341 /* Set text of proto_item after having already been created. */
5343 proto_item_set_text(proto_item *pi, const char *format, ...)
5345 field_info *fi = NULL;
5348 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5350 fi = PITEM_FINFO(pi);
5355 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
5359 va_start(ap, format);
5360 proto_tree_set_representation(pi, format, ap);
5364 /* Append to text of proto_item after having already been created. */
5366 proto_item_append_text(proto_item *pi, const char *format, ...)
5368 field_info *fi = NULL;
5372 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5374 fi = PITEM_FINFO(pi);
5379 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5381 * If we don't already have a representation,
5382 * generate the default representation.
5384 if (fi->rep == NULL) {
5385 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5386 proto_item_fill_label(fi, fi->rep->representation);
5389 curlen = strlen(fi->rep->representation);
5390 if (ITEM_LABEL_LENGTH > curlen) {
5391 va_start(ap, format);
5392 g_vsnprintf(fi->rep->representation + curlen,
5393 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
5399 /* Prepend to text of proto_item after having already been created. */
5401 proto_item_prepend_text(proto_item *pi, const char *format, ...)
5403 field_info *fi = NULL;
5404 char representation[ITEM_LABEL_LENGTH];
5407 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5409 fi = PITEM_FINFO(pi);
5414 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5416 * If we don't already have a representation,
5417 * generate the default representation.
5419 if (fi->rep == NULL) {
5420 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5421 proto_item_fill_label(fi, representation);
5423 g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
5425 va_start(ap, format);
5426 g_vsnprintf(fi->rep->representation,
5427 ITEM_LABEL_LENGTH, format, ap);
5429 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
5434 proto_item_set_len(proto_item *pi, const gint length)
5438 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5440 fi = PITEM_FINFO(pi);
5444 DISSECTOR_ASSERT(length >= 0);
5445 fi->length = length;
5448 * You cannot just make the "len" field of a GByteArray
5449 * larger, if there's no data to back that length;
5450 * you can only make it smaller.
5452 if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
5453 fi->value.value.bytes->len = length;
5457 * Sets the length of the item based on its start and on the specified
5458 * offset, which is the offset past the end of the item; as the start
5459 * in the item is relative to the beginning of the data source tvbuff,
5460 * we need to pass in a tvbuff - the end offset is relative to the beginning
5464 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
5468 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5470 fi = PITEM_FINFO(pi);
5474 end += tvb_raw_offset(tvb);
5475 DISSECTOR_ASSERT(end >= fi->start);
5476 fi->length = end - fi->start;
5480 proto_item_get_len(const proto_item *pi)
5482 field_info *fi = PITEM_FINFO(pi);
5483 return fi ? fi->length : -1;
5487 proto_tree_create_root(packet_info *pinfo)
5491 /* Initialize the proto_node */
5492 pnode = g_slice_new(proto_tree);
5493 PROTO_NODE_INIT(pnode);
5494 pnode->parent = NULL;
5495 PNODE_FINFO(pnode) = NULL;
5496 pnode->tree_data = g_slice_new(tree_data_t);
5498 /* Make sure we can access pinfo everywhere */
5499 pnode->tree_data->pinfo = pinfo;
5501 /* Don't initialize the tree_data_t. Wait until we know we need it */
5502 pnode->tree_data->interesting_hfids = NULL;
5504 /* Set the default to FALSE so it's easier to
5505 * find errors; if we expect to see the protocol tree
5506 * but for some reason the default 'visible' is not
5507 * changed, then we'll find out very quickly. */
5508 pnode->tree_data->visible = FALSE;
5510 /* Make sure that we fake protocols (if possible) */
5511 pnode->tree_data->fake_protocols = TRUE;
5513 /* Keep track of the number of children */
5514 pnode->tree_data->count = 0;
5516 return (proto_tree *)pnode;
5520 /* "prime" a proto_tree with a single hfid that a dfilter
5521 * is interested in. */
5523 proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
5525 header_field_info *hfinfo;
5527 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
5528 /* this field is referenced by a filter so increase the refcount.
5529 also increase the refcount for the parent, i.e the protocol.
5531 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
5532 /* only increase the refcount if there is a parent.
5533 if this is a protocol and not a field then parent will be -1
5534 and there is no parent to add any refcounting for.
5536 if (hfinfo->parent != -1) {
5537 header_field_info *parent_hfinfo;
5538 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
5540 /* Mark parent as indirectly referenced unless it is already directly
5541 * referenced, i.e. the user has specified the parent in a filter.
5543 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
5544 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
5549 proto_item_add_subtree(proto_item *pi, const gint idx) {
5555 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
5557 fi = PITEM_FINFO(pi);
5559 return (proto_tree *)pi;
5561 fi->tree_type = idx;
5563 return (proto_tree *)pi;
5567 proto_item_get_subtree(proto_item *pi) {
5572 fi = PITEM_FINFO(pi);
5573 if ( (!fi) || (fi->tree_type == -1) )
5575 return (proto_tree *)pi;
5579 proto_item_get_parent(const proto_item *ti) {
5586 proto_item_get_parent_nth(proto_item *ti, int gen) {
5599 proto_tree_get_parent(proto_tree *tree) {
5602 return (proto_item *)tree;
5606 proto_tree_get_parent_tree(proto_tree *tree) {
5610 /* we're the root tree, there's no parent
5611 return ourselves so the caller has at least a tree to attach to */
5615 return (proto_tree *)tree->parent;
5619 proto_tree_get_root(proto_tree *tree) {
5622 while (tree->parent) {
5623 tree = tree->parent;
5629 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
5630 proto_item *item_to_move)
5633 /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
5634 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
5636 /* This function doesn't generate any values. It only reorganizes the prococol tree
5637 * so we can bail out immediately if it isn't visible. */
5638 if (!tree || !PTREE_DATA(tree)->visible)
5641 DISSECTOR_ASSERT(item_to_move->parent == tree);
5642 DISSECTOR_ASSERT(fixed_item->parent == tree);
5644 /*** cut item_to_move out ***/
5646 /* is item_to_move the first? */
5647 if (tree->first_child == item_to_move) {
5648 /* simply change first child to next */
5649 tree->first_child = item_to_move->next;
5651 DISSECTOR_ASSERT(tree->last_child != item_to_move);
5653 proto_item *curr_item;
5654 /* find previous and change it's next */
5655 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
5656 if (curr_item->next == item_to_move) {
5661 DISSECTOR_ASSERT(curr_item);
5663 curr_item->next = item_to_move->next;
5665 /* fix last_child if required */
5666 if (tree->last_child == item_to_move) {
5667 tree->last_child = curr_item;
5671 /*** insert to_move after fixed ***/
5672 item_to_move->next = fixed_item->next;
5673 fixed_item->next = item_to_move;
5674 if (tree->last_child == fixed_item) {
5675 tree->last_child = item_to_move;
5680 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
5688 fi = PTREE_FINFO(tree);
5692 start += tvb_raw_offset(tvb);
5693 DISSECTOR_ASSERT(start >= 0);
5694 DISSECTOR_ASSERT(length >= 0);
5696 fi->appendix_start = start;
5697 fi->appendix_length = length;
5701 proto_register_protocol(const char *name, const char *short_name,
5702 const char *filter_name)
5704 protocol_t *protocol;
5705 const protocol_t *existing_protocol = NULL;
5706 header_field_info *hfinfo;
5708 const char *existing_name;
5712 gboolean found_invalid;
5715 * Make sure there's not already a protocol with any of those
5716 * names. Crash if there is, as that's an error in the code
5717 * or an inappropriate plugin.
5718 * This situation has to be fixed to not register more than one
5719 * protocol with the same name.
5721 * This is done by reducing the number of strcmp (and alike) calls
5722 * as much as possible, as this significally slows down startup time.
5724 * Drawback: As a hash value is used to reduce insert time,
5725 * this might lead to a hash collision.
5726 * However, although we have somewhat over 1000 protocols, we're using
5727 * a 32 bit int so this is very, very unlikely.
5730 key = (gint *)g_malloc (sizeof(gint));
5731 *key = wrs_str_hash(name);
5733 existing_name = (const char *)g_hash_table_lookup(proto_names, key);
5734 if (existing_name != NULL) {
5735 /* g_error will terminate the program */
5736 g_error("Duplicate protocol name \"%s\"!"
5737 " This might be caused by an inappropriate plugin or a development error.", name);
5739 g_hash_table_insert(proto_names, key, (gpointer)name);
5741 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5742 if (existing_protocol != NULL) {
5743 g_error("Duplicate protocol short_name \"%s\"!"
5744 " This might be caused by an inappropriate plugin or a development error.", short_name);
5747 found_invalid = FALSE;
5748 for (i = 0; filter_name[i]; i++) {
5750 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
5751 found_invalid = TRUE;
5754 if (found_invalid) {
5755 g_error("Protocol filter name \"%s\" has one or more invalid characters."
5756 " Allowed are lower characters, digits, '-', '_' and '.'."
5757 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5759 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5760 if (existing_protocol != NULL) {
5761 g_error("Duplicate protocol filter_name \"%s\"!"
5762 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5765 /* Add this protocol to the list of known protocols; the list
5766 is sorted by protocol short name. */
5767 protocol = g_new(protocol_t, 1);
5768 protocol->name = name;
5769 protocol->short_name = short_name;
5770 protocol->filter_name = filter_name;
5771 /*protocol->fields = g_ptr_array_new();*/
5772 /* Delegate until actually needed and use g_ptr_array_sized_new*/
5773 protocol->fields = NULL;
5774 protocol->is_enabled = TRUE; /* protocol is enabled by default */
5775 protocol->enabled_by_default = TRUE; /* see previous comment */
5776 protocol->can_toggle = TRUE;
5777 protocol->heur_list = NULL;
5778 /* list will be sorted later by name, when all protocols completed registering */
5779 protocols = g_list_prepend(protocols, protocol);
5780 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
5781 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
5783 /* Here we allocate a new header_field_info struct */
5784 hfinfo = g_slice_new(header_field_info);
5785 hfinfo->name = name;
5786 hfinfo->abbrev = filter_name;
5787 hfinfo->type = FT_PROTOCOL;
5788 hfinfo->display = BASE_NONE;
5789 hfinfo->strings = protocol;
5790 hfinfo->bitmask = 0;
5791 hfinfo->ref_type = HF_REF_TYPE_NONE;
5792 hfinfo->blurb = NULL;
5793 hfinfo->parent = -1; /* this field differentiates protos and fields */
5795 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
5796 protocol->proto_id = proto_id;
5801 proto_deregister_protocol(const char *short_name)
5803 protocol_t *protocol;
5804 header_field_info *hfinfo;
5809 proto_id = proto_get_id_by_short_name(short_name);
5810 protocol = find_protocol_by_id(proto_id);
5811 if (protocol == NULL)
5814 key = wrs_str_hash(protocol->name);
5815 g_hash_table_remove(proto_names, &key);
5817 g_hash_table_remove(proto_short_names, (gpointer)short_name);
5818 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
5820 if (protocol->fields) {
5821 for (i = 0; i < protocol->fields->len; i++) {
5822 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
5823 hfinfo_remove_from_gpa_name_map(hfinfo);
5824 expert_deregister_expertinfo(hfinfo->abbrev);
5825 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
5827 g_ptr_array_free(protocol->fields, TRUE);
5828 protocol->fields = NULL;
5831 /* Remove this protocol from the list of known protocols */
5832 protocols = g_list_remove(protocols, protocol);
5834 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
5835 g_hash_table_steal(gpa_name_map, protocol->filter_name);
5837 g_free(last_field_name);
5838 last_field_name = NULL;
5844 * Routines to use to iterate over the protocols.
5845 * The argument passed to the iterator routines is an opaque cookie to
5846 * their callers; it's the GList pointer for the current element in
5848 * The ID of the protocol is returned, or -1 if there is no protocol.
5851 proto_get_first_protocol(void **cookie)
5853 protocol_t *protocol;
5855 if (protocols == NULL)
5857 *cookie = protocols;
5858 protocol = (protocol_t *)protocols->data;
5859 return protocol->proto_id;
5863 proto_get_data_protocol(void *cookie)
5865 GList *list_item = (GList *)cookie;
5867 protocol_t *protocol = (protocol_t *)list_item->data;
5868 return protocol->proto_id;
5872 proto_get_next_protocol(void **cookie)
5874 GList *list_item = (GList *)*cookie;
5875 protocol_t *protocol;
5877 list_item = g_list_next(list_item);
5878 if (list_item == NULL)
5880 *cookie = list_item;
5881 protocol = (protocol_t *)list_item->data;
5882 return protocol->proto_id;
5885 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
5886 assume that the cookie stored by
5887 proto_get_(first|next)_protocol_field() will never have a
5888 value of NULL. So, to preserve this semantic, the cookie value
5889 below is adjusted so that the cookie value stored is 1 + the
5890 current (zero-based) array index.
5893 proto_get_first_protocol_field(const int proto_id, void **cookie)
5895 protocol_t *protocol = find_protocol_by_id(proto_id);
5897 if ((protocol == NULL) || (protocol->fields == NULL))
5900 *cookie = GUINT_TO_POINTER(0 + 1);
5901 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
5905 proto_get_next_protocol_field(const int proto_id, void **cookie)
5907 protocol_t *protocol = find_protocol_by_id(proto_id);
5908 guint i = GPOINTER_TO_UINT(*cookie) - 1;
5912 if ((protocol->fields == NULL) || (i >= protocol->fields->len))
5915 *cookie = GUINT_TO_POINTER(i + 1);
5916 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
5920 find_protocol_by_id(const int proto_id)
5922 header_field_info *hfinfo;
5927 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
5928 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
5929 return (protocol_t *)hfinfo->strings;
5933 proto_get_id(const protocol_t *protocol)
5935 return protocol->proto_id;
5939 proto_name_already_registered(const gchar *name)
5943 DISSECTOR_ASSERT_HINT(name, "No name present");
5945 key = wrs_str_hash(name);
5946 if (g_hash_table_lookup(proto_names, &key) != NULL)
5952 proto_get_id_by_filter_name(const gchar *filter_name)
5954 const protocol_t *protocol = NULL;
5956 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
5958 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5960 if (protocol == NULL)
5962 return protocol->proto_id;
5966 proto_get_id_by_short_name(const gchar *short_name)
5968 const protocol_t *protocol = NULL;
5970 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
5972 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5974 if (protocol == NULL)
5976 return protocol->proto_id;
5980 proto_get_protocol_name(const int proto_id)
5982 protocol_t *protocol;
5984 protocol = find_protocol_by_id(proto_id);
5986 if (protocol == NULL)
5988 return protocol->name;
5992 proto_get_protocol_short_name(const protocol_t *protocol)
5994 if (protocol == NULL)
5996 return protocol->short_name;
6000 proto_get_protocol_long_name(const protocol_t *protocol)
6002 if (protocol == NULL)
6004 return protocol->name;
6008 proto_get_protocol_filter_name(const int proto_id)
6010 protocol_t *protocol;
6012 protocol = find_protocol_by_id(proto_id);
6013 if (protocol == NULL)
6015 return protocol->filter_name;
6018 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
6020 heur_dtbl_entry_t* heuristic_dissector;
6022 if (protocol == NULL)
6025 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
6026 if (heuristic_dissector != NULL)
6028 protocol->heur_list = g_list_append (protocol->heur_list, heuristic_dissector);
6032 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
6034 if (protocol == NULL)
6037 g_list_foreach(protocol->heur_list, func, user_data);
6041 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
6042 gboolean *is_tcp, gboolean *is_udp,
6043 gboolean *is_sctp, gboolean *is_ssl,
6045 gboolean *is_lte_rlc)
6047 wmem_list_frame_t *protos = wmem_list_head(layers);
6049 const char *proto_name;
6051 /* Walk the list of a available protocols in the packet and
6052 find "major" ones. */
6053 /* It might make more sense to assemble and return a bitfield. */
6054 while (protos != NULL)
6056 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6057 proto_name = proto_get_protocol_filter_name(proto_id);
6059 if (is_ip && ((!strcmp(proto_name, "ip")) ||
6060 (!strcmp(proto_name, "ipv6")))) {
6062 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
6064 } else if (is_udp && !strcmp(proto_name, "udp")) {
6066 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
6068 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
6070 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
6072 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
6076 protos = wmem_list_frame_next(protos);
6081 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
6083 wmem_list_frame_t *protos = wmem_list_head(layers);
6087 /* Walk the list of a available protocols in the packet and
6088 find "major" ones. */
6089 /* It might make more sense to assemble and return a bitfield. */
6090 while (protos != NULL)
6092 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6093 name = proto_get_protocol_filter_name(proto_id);
6095 if (!strcmp(name, proto_name))
6100 protos = wmem_list_frame_next(protos);
6108 proto_is_protocol_enabled(const protocol_t *protocol)
6110 return protocol->is_enabled;
6114 proto_can_toggle_protocol(const int proto_id)
6116 protocol_t *protocol;
6118 protocol = find_protocol_by_id(proto_id);
6119 return protocol->can_toggle;
6123 proto_disable_by_default(const int proto_id)
6125 protocol_t *protocol;
6127 protocol = find_protocol_by_id(proto_id);
6128 DISSECTOR_ASSERT(protocol->can_toggle);
6129 protocol->is_enabled = FALSE;
6130 protocol->enabled_by_default = FALSE;
6134 proto_set_decoding(const int proto_id, const gboolean enabled)
6136 protocol_t *protocol;
6138 protocol = find_protocol_by_id(proto_id);
6139 DISSECTOR_ASSERT(protocol->can_toggle);
6140 protocol->is_enabled = enabled;
6144 proto_enable_all(void)
6146 protocol_t *protocol;
6147 GList *list_item = protocols;
6149 if (protocols == NULL)
6153 protocol = (protocol_t *)list_item->data;
6154 if (protocol->can_toggle && protocol->enabled_by_default)
6155 protocol->is_enabled = TRUE;
6156 list_item = g_list_next(list_item);
6161 proto_set_cant_toggle(const int proto_id)
6163 protocol_t *protocol;
6165 protocol = find_protocol_by_id(proto_id);
6166 protocol->can_toggle = FALSE;
6170 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
6172 if (proto != NULL) {
6173 g_ptr_array_add(proto->fields, hfi);
6176 return proto_register_field_init(hfi, parent);
6179 /* for use with static arrays only, since we don't allocate our own copies
6180 of the header_field_info struct contained within the hf_register_info struct */
6182 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
6184 hf_register_info *ptr = hf;
6188 proto = find_protocol_by_id(parent);
6190 if (proto->fields == NULL) {
6191 proto->fields = g_ptr_array_sized_new(num_records);
6194 for (i = 0; i < num_records; i++, ptr++) {
6196 * Make sure we haven't registered this yet.
6197 * Most fields have variables associated with them
6198 * that are initialized to -1; some have array elements,
6199 * or possibly uninitialized variables, so we also allow
6200 * 0 (which is unlikely to be the field ID we get back
6201 * from "proto_register_field_init()").
6203 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
6205 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
6206 ptr->hfinfo.abbrev);
6210 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
6215 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
6220 proto = find_protocol_by_id(parent);
6222 if (proto->fields == NULL) {
6223 proto->fields = g_ptr_array_sized_new(num_records);
6226 for (i = 0; i < num_records; i++) {
6228 * Make sure we haven't registered this yet.
6230 if (hfi[i].id != -1) {
6232 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6237 proto_register_field_common(proto, &hfi[i], parent);
6242 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
6247 proto = find_protocol_by_id(parent);
6249 if (proto->fields == NULL) {
6250 proto->fields = g_ptr_array_sized_new(num_records);
6254 for (i = 0; i < num_records; i++) {
6256 * Make sure we haven't registered this yet.
6258 if (hfi[i]->id != -1) {
6260 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6265 proto_register_field_common(proto, hfi[i], parent);
6269 /* deregister already registered fields */
6271 proto_deregister_field (const int parent, gint hf_id)
6273 header_field_info *hfi;
6277 g_free(last_field_name);
6278 last_field_name = NULL;
6280 if (hf_id == -1 || hf_id == 0)
6283 proto = find_protocol_by_id (parent);
6284 if (!proto || proto->fields == NULL) {
6288 for (i = 0; i < proto->fields->len; i++) {
6289 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
6290 if (hfi->id == hf_id) {
6291 /* Found the hf_id in this protocol */
6292 g_hash_table_steal(gpa_name_map, hfi->abbrev);
6293 g_ptr_array_remove_index_fast(proto->fields, i);
6294 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
6301 proto_add_deregistered_data (void *data)
6303 g_ptr_array_add(deregistered_data, data);
6307 free_deregistered_field (gpointer data, gpointer user_data _U_)
6309 header_field_info *hfi = (header_field_info *) data;
6310 gint hf_id = hfi->id;
6312 g_free((char *)hfi->name);
6313 g_free((char *)hfi->abbrev);
6314 g_free((char *)hfi->blurb);
6317 switch (hfi->type) {
6319 /* This is just an integer represented as a pointer */
6322 protocol_t *protocol = (protocol_t *)hfi->strings;
6323 g_free((gchar *)protocol->short_name);
6327 true_false_string *tf = (true_false_string *)hfi->strings;
6328 g_free ((gchar *)tf->true_string);
6329 g_free ((gchar *)tf->false_string);
6334 val64_string *vs64 = (val64_string *)hfi->strings;
6335 while (vs64->strptr) {
6336 g_free((gchar *)vs64->strptr);
6342 /* Other Integer types */
6343 value_string *vs = (value_string *)hfi->strings;
6344 while (vs->strptr) {
6345 g_free((gchar *)vs->strptr);
6351 if (hfi->type != FT_FRAMENUM) {
6352 g_free((void *)hfi->strings);
6356 if (hfi->parent == -1)
6357 g_slice_free(header_field_info, hfi);
6359 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
6363 free_deregistered_data (gpointer data, gpointer user_data _U_)
6368 /* free deregistered fields and data */
6370 proto_free_deregistered_fields (void)
6372 expert_free_deregistered_expertinfos();
6374 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
6375 g_ptr_array_free(deregistered_fields, TRUE);
6376 deregistered_fields = g_ptr_array_new();
6378 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
6379 g_ptr_array_free(deregistered_data, TRUE);
6380 deregistered_data = g_ptr_array_new();
6383 /* chars allowed in field abbrev */
6385 const guint8 fld_abbrev_chars[256] = {
6386 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
6387 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
6388 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
6389 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
6390 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
6391 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
6392 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
6393 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
6394 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
6395 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
6396 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
6397 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
6398 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
6399 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
6400 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
6401 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
6404 static const value_string hf_display[] = {
6405 { BASE_NONE, "BASE_NONE" },
6406 { BASE_DEC, "BASE_DEC" },
6407 { BASE_HEX, "BASE_HEX" },
6408 { BASE_OCT, "BASE_OCT" },
6409 { BASE_DEC_HEX, "BASE_DEC_HEX" },
6410 { BASE_HEX_DEC, "BASE_HEX_DEC" },
6411 { BASE_CUSTOM, "BASE_CUSTOM" },
6412 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
6413 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
6414 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
6415 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
6416 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
6417 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
6418 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
6419 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
6420 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
6421 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
6422 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
6423 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
6424 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
6425 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
6426 /* Alias: BASE_NONE { BASE_FLOAT, "BASE_FLOAT" }, */
6427 /* Alias: BASE_NONE { STR_ASCII, "STR_ASCII" }, */
6428 { STR_UNICODE, "STR_UNICODE" },
6429 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
6430 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
6431 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
6432 { BASE_PT_UDP, "BASE_PT_UDP" },
6433 { BASE_PT_TCP, "BASE_PT_TCP" },
6434 { BASE_PT_DCCP, "BASE_PT_DCCP" },
6435 { BASE_PT_SCTP, "BASE_PT_SCTP" },
6438 const char* proto_field_display_to_string(int field_display)
6440 return val_to_str_const(field_display, hf_display, "Unknown");
6443 static inline port_type
6444 display_to_port_type(field_display_e e)
6461 /* temporary function containing assert part for easier profiling */
6463 tmp_fld_check_assert(header_field_info *hfinfo)
6467 /* The field must have a name (with length > 0) */
6468 if (!hfinfo->name || !hfinfo->name[0]) {
6470 /* Try to identify the field */
6471 g_error("Field (abbrev='%s') does not have a name\n",
6475 g_error("Field does not have a name (nor an abbreviation)\n");
6478 /* fields with an empty string for an abbreviation aren't filterable */
6479 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
6480 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
6482 /* These types of fields are allowed to have value_strings,
6483 * true_false_strings or a protocol_t struct
6485 if (hfinfo->strings != NULL && !(
6486 (hfinfo->type == FT_CHAR) ||
6487 (hfinfo->type == FT_UINT8) ||
6488 (hfinfo->type == FT_UINT16) ||
6489 (hfinfo->type == FT_UINT24) ||
6490 (hfinfo->type == FT_UINT32) ||
6491 (hfinfo->type == FT_UINT40) ||
6492 (hfinfo->type == FT_UINT48) ||
6493 (hfinfo->type == FT_UINT56) ||
6494 (hfinfo->type == FT_UINT64) ||
6495 (hfinfo->type == FT_INT8) ||
6496 (hfinfo->type == FT_INT16) ||
6497 (hfinfo->type == FT_INT24) ||
6498 (hfinfo->type == FT_INT32) ||
6499 (hfinfo->type == FT_INT40) ||
6500 (hfinfo->type == FT_INT48) ||
6501 (hfinfo->type == FT_INT56) ||
6502 (hfinfo->type == FT_INT64) ||
6503 (hfinfo->type == FT_BOOLEAN) ||
6504 (hfinfo->type == FT_PROTOCOL) ||
6505 (hfinfo->type == FT_FRAMENUM) ))
6506 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
6507 " (which is not allowed to have strings)\n",
6508 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
6510 /* TODO: This check may slow down startup, and output quite a few warnings.
6511 It would be good to be able to enable this (and possibly other checks?)
6512 in non-release builds. */
6514 /* Check for duplicate value_string values.
6515 There are lots that have the same value *and* string, so for now only
6516 report those that have same value but different string. */
6517 if ((hfinfo->strings != NULL) &&
6518 !(hfinfo->display & BASE_RANGE_STRING) &&
6519 !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
6521 (hfinfo->type == FT_CHAR) ||
6522 (hfinfo->type == FT_UINT8) ||
6523 (hfinfo->type == FT_UINT16) ||
6524 (hfinfo->type == FT_UINT24) ||
6525 (hfinfo->type == FT_UINT32) ||
6526 (hfinfo->type == FT_INT8) ||
6527 (hfinfo->type == FT_INT16) ||
6528 (hfinfo->type == FT_INT24) ||
6529 (hfinfo->type == FT_INT32) ||
6530 (hfinfo->type == FT_FRAMENUM) )) {
6533 const value_string *start_values;
6534 const value_string *current;
6536 if (hfinfo->display & BASE_EXT_STRING)
6537 start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
6539 start_values = (const value_string*)hfinfo->strings;
6540 current = start_values;
6542 for (n=0; current; n++, current++) {
6543 /* Drop out if we reached the end. */
6544 if ((current->value == 0) && (current->strptr == NULL)) {
6548 /* Check value against all previous */
6549 for (m=0; m < n; m++) {
6550 /* There are lots of duplicates with the same string,
6551 so only report if different... */
6552 if ((start_values[m].value == current->value) &&
6553 (strcmp(start_values[m].strptr, current->strptr) != 0)) {
6554 ws_g_warning("Field '%s' (%s) has a conflicting entry in its"
6555 " value_string: %u is at indices %u (%s) and %u (%s))\n",
6556 hfinfo->name, hfinfo->abbrev,
6557 current->value, m, start_values[m].strptr, n, current->strptr);
6565 switch (hfinfo->type) {
6568 /* Require the char type to have BASE_HEX, BASE_OCT,
6569 * BASE_CUSTOM, or BASE_NONE as its base.
6571 * If the display value is BASE_NONE and there is a
6572 * strings conversion then the dissector writer is
6573 * telling us that the field's numerical value is
6574 * meaningless; we'll avoid showing the value to the
6577 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6580 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6583 if (hfinfo->strings == NULL)
6584 g_error("Field '%s' (%s) is an integral value (%s)"
6585 " but is being displayed as BASE_NONE but"
6586 " without a strings conversion",
6587 hfinfo->name, hfinfo->abbrev,
6588 ftype_name(hfinfo->type));
6591 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6592 g_error("Field '%s' (%s) is a character value (%s)"
6593 " but is being displayed as %s\n",
6594 hfinfo->name, hfinfo->abbrev,
6595 ftype_name(hfinfo->type), tmp_str);
6596 wmem_free(NULL, tmp_str);
6607 /* Hexadecimal and octal are, in printf() and everywhere
6608 * else, unsigned so don't allow dissectors to register a
6609 * signed field to be displayed unsigned. (Else how would
6610 * we display negative values?)
6612 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6617 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6618 g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
6619 hfinfo->name, hfinfo->abbrev,
6620 ftype_name(hfinfo->type), tmp_str);
6621 wmem_free(NULL, tmp_str);
6632 if (IS_BASE_PORT(hfinfo->display)) {
6633 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6634 if (hfinfo->type != FT_UINT16) {
6635 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
6636 hfinfo->name, hfinfo->abbrev,
6637 tmp_str, ftype_name(hfinfo->type));
6639 if (hfinfo->strings != NULL) {
6640 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
6641 hfinfo->name, hfinfo->abbrev,
6642 ftype_name(hfinfo->type), tmp_str);
6644 if (hfinfo->bitmask != 0) {
6645 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
6646 hfinfo->name, hfinfo->abbrev,
6647 ftype_name(hfinfo->type), tmp_str);
6649 wmem_free(NULL, tmp_str);
6653 /* Require integral types (other than frame number,
6654 * which is always displayed in decimal) to have a
6657 * If the display value is BASE_NONE and there is a
6658 * strings conversion then the dissector writer is
6659 * telling us that the field's numerical value is
6660 * meaningless; we'll avoid showing the value to the
6663 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6669 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6672 if (hfinfo->strings == NULL)
6673 g_error("Field '%s' (%s) is an integral value (%s)"
6674 " but is being displayed as BASE_NONE but"
6675 " without a strings conversion",
6676 hfinfo->name, hfinfo->abbrev,
6677 ftype_name(hfinfo->type));
6680 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6681 g_error("Field '%s' (%s) is an integral value (%s)"
6682 " but is being displayed as %s\n",
6683 hfinfo->name, hfinfo->abbrev,
6684 ftype_name(hfinfo->type), tmp_str);
6685 wmem_free(NULL, tmp_str);
6689 /* Require bytes to have a "display type" that could
6690 * add a character between displayed bytes.
6692 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6700 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6701 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",
6702 hfinfo->name, hfinfo->abbrev, tmp_str);
6703 wmem_free(NULL, tmp_str);
6705 if (hfinfo->bitmask != 0)
6706 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6707 hfinfo->name, hfinfo->abbrev,
6708 ftype_name(hfinfo->type));
6709 if (hfinfo->strings != NULL)
6710 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6711 hfinfo->name, hfinfo->abbrev,
6712 ftype_name(hfinfo->type));
6717 if (hfinfo->display != BASE_NONE) {
6718 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6719 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6720 hfinfo->name, hfinfo->abbrev,
6721 ftype_name(hfinfo->type), tmp_str);
6722 wmem_free(NULL, tmp_str);
6724 if (hfinfo->bitmask != 0)
6725 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6726 hfinfo->name, hfinfo->abbrev,
6727 ftype_name(hfinfo->type));
6733 case FT_ABSOLUTE_TIME:
6734 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
6735 hfinfo->display == ABSOLUTE_TIME_UTC ||
6736 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
6737 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6738 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
6739 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
6740 wmem_free(NULL, tmp_str);
6742 if (hfinfo->bitmask != 0)
6743 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6744 hfinfo->name, hfinfo->abbrev,
6745 ftype_name(hfinfo->type));
6750 case FT_UINT_STRING:
6752 switch (hfinfo->display) {
6758 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6759 g_error("Field '%s' (%s) is an string value (%s)"
6760 " but is being displayed as %s\n",
6761 hfinfo->name, hfinfo->abbrev,
6762 ftype_name(hfinfo->type), tmp_str);
6763 wmem_free(NULL, tmp_str);
6766 if (hfinfo->bitmask != 0)
6767 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6768 hfinfo->name, hfinfo->abbrev,
6769 ftype_name(hfinfo->type));
6770 if (hfinfo->strings != NULL)
6771 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6772 hfinfo->name, hfinfo->abbrev,
6773 ftype_name(hfinfo->type));
6777 switch (hfinfo->display) {
6783 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6784 g_error("Field '%s' (%s) is an IPv4 value (%s)"
6785 " but is being displayed as %s\n",
6786 hfinfo->name, hfinfo->abbrev,
6787 ftype_name(hfinfo->type), tmp_str);
6788 wmem_free(NULL, tmp_str);
6793 if (hfinfo->display != BASE_NONE) {
6794 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6795 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6796 hfinfo->name, hfinfo->abbrev,
6797 ftype_name(hfinfo->type),
6799 wmem_free(NULL, tmp_str);
6801 if (hfinfo->bitmask != 0)
6802 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6803 hfinfo->name, hfinfo->abbrev,
6804 ftype_name(hfinfo->type));
6805 if (hfinfo->strings != NULL)
6806 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6807 hfinfo->name, hfinfo->abbrev,
6808 ftype_name(hfinfo->type));
6813 #ifdef ENABLE_CHECK_FILTER
6815 _ftype_common(enum ftenum type)
6839 case FT_UINT_STRING:
6852 case FT_ABSOLUTE_TIME:
6853 case FT_RELATIVE_TIME:
6854 return FT_ABSOLUTE_TIME;
6863 register_type_length_mismatch(void)
6865 static ei_register_info ei[] = {
6866 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
6867 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
6870 expert_module_t* expert_type_length_mismatch;
6872 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
6874 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
6875 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
6877 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
6878 disabling them makes no sense. */
6879 proto_set_cant_toggle(proto_type_length_mismatch);
6883 register_number_string_decoding_error(void)
6885 static ei_register_info ei[] = {
6886 { &ei_number_string_decoding_failed_error,
6887 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
6888 "Failed to decode number from string", EXPFILL
6891 { &ei_number_string_decoding_erange_error,
6892 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
6893 "Decoded number from string is out of valid range", EXPFILL
6898 expert_module_t* expert_number_string_decoding_error;
6900 proto_number_string_decoding_error =
6901 proto_register_protocol("Number-String Decoding Error",
6902 "Number-string decoding error",
6903 "_ws.number_string.decoding_error");
6905 expert_number_string_decoding_error =
6906 expert_register_protocol(proto_number_string_decoding_error);
6907 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
6909 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
6910 disabling them makes no sense. */
6911 proto_set_cant_toggle(proto_number_string_decoding_error);
6914 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (183000+PRE_ALLOC_EXPERT_FIELDS_MEM)
6916 proto_register_field_init(header_field_info *hfinfo, const int parent)
6919 tmp_fld_check_assert(hfinfo);
6921 hfinfo->parent = parent;
6922 hfinfo->same_name_next = NULL;
6923 hfinfo->same_name_prev_id = -1;
6925 /* if we always add and never delete, then id == len - 1 is correct */
6926 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
6927 if (!gpa_hfinfo.hfi) {
6928 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
6929 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
6931 gpa_hfinfo.allocated_len += 1000;
6932 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
6933 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
6934 /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
6937 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
6939 hfinfo->id = gpa_hfinfo.len - 1;
6941 /* if we have real names, enter this field in the name tree */
6942 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
6944 header_field_info *same_name_next_hfinfo;
6947 /* Check that the filter name (abbreviation) is legal;
6948 * it must contain only alphanumerics, '-', "_", and ".". */
6949 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
6951 if (g_ascii_isprint(c))
6952 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
6954 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
6955 DISSECTOR_ASSERT_NOT_REACHED();
6958 /* We allow multiple hfinfo's to be registered under the same
6959 * abbreviation. This was done for X.25, as, depending
6960 * on whether it's modulo-8 or modulo-128 operation,
6961 * some bitfield fields may be in different bits of
6962 * a byte, and we want to be able to refer to that field
6963 * with one name regardless of whether the packets
6964 * are modulo-8 or modulo-128 packets. */
6966 same_name_hfinfo = NULL;
6968 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
6969 /* GLIB 2.x - if it is already present
6970 * the previous hfinfo with the same name is saved
6971 * to same_name_hfinfo by value destroy callback */
6972 if (same_name_hfinfo) {
6973 /* There's already a field with this name.
6974 * Put the current field *before* that field
6975 * in the list of fields with this name, Thus,
6976 * we end up with an effectively
6977 * doubly-linked-list of same-named hfinfo's,
6978 * with the head of the list (stored in the
6979 * hash) being the last seen hfinfo.
6981 same_name_next_hfinfo =
6982 same_name_hfinfo->same_name_next;
6984 hfinfo->same_name_next = same_name_next_hfinfo;
6985 if (same_name_next_hfinfo)
6986 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
6988 same_name_hfinfo->same_name_next = hfinfo;
6989 hfinfo->same_name_prev_id = same_name_hfinfo->id;
6990 #ifdef ENABLE_CHECK_FILTER
6991 while (same_name_hfinfo) {
6992 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
6993 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));
6994 same_name_hfinfo = same_name_hfinfo->same_name_next;
7004 proto_register_subtree_array(gint *const *indices, const int num_indices)
7007 gint *const *ptr = indices;
7010 * If we've already allocated the array of tree types, expand
7011 * it; this lets plugins such as mate add tree types after
7012 * the initial startup. (If we haven't already allocated it,
7013 * we don't allocate it; on the first pass, we just assign
7014 * ett values and keep track of how many we've assigned, and
7015 * when we're finished registering all dissectors we allocate
7016 * the array, so that we do only one allocation rather than
7017 * wasting CPU time and memory by growing the array for each
7018 * dissector that registers ett values.)
7020 if (tree_is_expanded != NULL) {
7021 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
7023 /* set new items to 0 */
7024 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
7025 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
7026 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
7030 * Assign "num_indices" subtree numbers starting at "num_tree_types",
7031 * returning the indices through the pointers in the array whose
7032 * first element is pointed to by "indices", and update
7033 * "num_tree_types" appropriately.
7035 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
7037 /* g_error will terminate the program */
7038 g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
7039 " This is a development error:"
7040 " Either the subtree item type has already been assigned or"
7041 " was not initialized to -1.");
7043 **ptr = num_tree_types;
7048 label_concat(char *label_str, gsize pos, const char *str)
7050 if (pos < ITEM_LABEL_LENGTH)
7051 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
7057 label_mark_truncated(char *label_str, gsize name_pos)
7059 static const char trunc_str[] = " [truncated]";
7060 const size_t trunc_len = sizeof(trunc_str)-1;
7063 /* ..... field_name: dataaaaaaaaaaaaa
7067 * ..... field_name [truncated]: dataaaaaaaaaaaaa
7069 * name_pos==0 means that we have only data or only a field_name
7072 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
7073 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
7074 memcpy(label_str + name_pos, trunc_str, trunc_len);
7076 /* in general, label_str is UTF-8
7077 we can truncate it only at the beginning of a new character
7078 we go backwards from the byte right after our buffer and
7079 find the next starting byte of a UTF-8 character, this is
7081 there's no need to use g_utf8_find_prev_char(), the search
7082 will always succeed since we copied trunc_str into the
7084 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH]);
7087 } else if (name_pos < ITEM_LABEL_LENGTH)
7088 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
7092 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
7096 /* "%s: %s", hfinfo->name, text */
7097 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
7098 pos = label_concat(label_str, pos, ": ");
7099 pos = label_concat(label_str, pos, text ? text : "(null)");
7101 if (pos >= ITEM_LABEL_LENGTH) {
7102 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7103 label_mark_truncated(label_str, name_pos);
7110 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
7114 /* "%s: %s (%s)", hfinfo->name, text, descr */
7115 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
7116 pos = label_concat(label_str, pos, ": ");
7117 pos = label_concat(label_str, pos, text ? text : "(null)");
7118 pos = label_concat(label_str, pos, " (");
7119 pos = label_concat(label_str, pos, descr ? descr : "(null)");
7120 pos = label_concat(label_str, pos, ")");
7122 if (pos >= ITEM_LABEL_LENGTH) {
7123 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7124 label_mark_truncated(label_str, name_pos);
7131 proto_item_fill_label(field_info *fi, gchar *label_str)
7133 header_field_info *hfinfo;
7137 ipv4_addr_and_mask *ipv4;
7139 guint32 n_addr; /* network-order IPv4 address */
7148 /* XXX: Check validity of hfinfo->type */
7152 hfinfo = fi->hfinfo;
7154 switch (hfinfo->type) {
7157 g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
7161 fill_label_boolean(fi, label_str);
7166 bytes = (guint8 *)fvalue_get(&fi->value);
7169 switch(hfinfo->display)
7172 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
7175 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
7178 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
7181 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7185 if (prefs.display_byte_fields_with_spaces)
7187 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7191 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
7195 label_fill(label_str, 0, hfinfo, str);
7196 wmem_free(NULL, str);
7198 if (hfinfo->display & BASE_ALLOW_ZERO) {
7199 label_fill(label_str, 0, hfinfo, "<none>");
7201 label_fill(label_str, 0, hfinfo, "<MISSING>");
7207 if (hfinfo->bitmask) {
7208 fill_label_bitfield_char(fi, label_str);
7210 fill_label_char(fi, label_str);
7214 /* Four types of integers to take care of:
7215 * Bitfield, with val_string
7216 * Bitfield, w/o val_string
7217 * Non-bitfield, with val_string
7218 * Non-bitfield, w/o val_string
7224 if (hfinfo->bitmask) {
7225 fill_label_bitfield(fi, label_str, FALSE);
7227 fill_label_number(fi, label_str, FALSE);
7232 fill_label_number(fi, label_str, FALSE);
7239 if (hfinfo->bitmask) {
7240 fill_label_bitfield64(fi, label_str, FALSE);
7242 fill_label_number64(fi, label_str, FALSE);
7250 if (hfinfo->bitmask) {
7251 fill_label_bitfield(fi, label_str, TRUE);
7253 fill_label_number(fi, label_str, TRUE);
7261 if (hfinfo->bitmask) {
7262 fill_label_bitfield64(fi, label_str, TRUE);
7264 fill_label_number64(fi, label_str, TRUE);
7269 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7270 "%s: %." G_STRINGIFY(FLT_DIG) "g",
7271 hfinfo->name, fvalue_get_floating(&fi->value));
7275 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7276 "%s: %." G_STRINGIFY(DBL_DIG) "g",
7277 hfinfo->name, fvalue_get_floating(&fi->value));
7280 case FT_ABSOLUTE_TIME:
7281 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
7282 label_fill(label_str, 0, hfinfo, tmp);
7283 wmem_free(NULL, tmp);
7286 case FT_RELATIVE_TIME:
7287 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
7288 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7289 "%s: %s seconds", hfinfo->name, tmp);
7290 wmem_free(NULL, tmp);
7294 integer = fvalue_get_uinteger(&fi->value);
7295 tmp = get_ipxnet_name(NULL, integer);
7296 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7297 "%s: %s (0x%08X)", hfinfo->name,
7299 wmem_free(NULL, tmp);
7303 addr.type = AT_AX25;
7304 addr.len = AX25_ADDR_LEN;
7305 addr.data = (guint8 *)fvalue_get(&fi->value);
7307 addr_str = (char*)address_to_str(NULL, &addr);
7308 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7309 "%s: %s", hfinfo->name, addr_str);
7310 wmem_free(NULL, addr_str);
7314 addr.type = vines_address_type;
7315 addr.len = VINES_ADDR_LEN;
7316 addr.data = (guint8 *)fvalue_get(&fi->value);
7318 addr_str = (char*)address_to_str(NULL, &addr);
7319 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7320 "%s: %s", hfinfo->name, addr_str);
7321 wmem_free(NULL, addr_str);
7325 bytes = (guint8 *)fvalue_get(&fi->value);
7327 addr.type = AT_ETHER;
7331 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7332 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7333 "%s: %s", hfinfo->name, addr_str);
7334 wmem_free(NULL, addr_str);
7338 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&fi->value);
7339 n_addr = ipv4_get_net_order_addr(ipv4);
7341 addr.type = AT_IPv4;
7343 addr.data = &n_addr;
7345 if (hfinfo->display == BASE_NETMASK)
7347 addr_str = (char*)address_to_str(NULL, &addr);
7351 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7353 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7354 "%s: %s", hfinfo->name, addr_str);
7355 wmem_free(NULL, addr_str);
7359 bytes = (guint8 *)fvalue_get(&fi->value);
7361 addr.type = AT_IPv6;
7365 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7366 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7367 "%s: %s", hfinfo->name, addr_str);
7368 wmem_free(NULL, addr_str);
7372 addr.type = AT_FCWWN;
7373 addr.len = FCWWN_ADDR_LEN;
7374 addr.data = (guint8 *)fvalue_get(&fi->value);
7376 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7377 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7378 "%s: %s", hfinfo->name, addr_str);
7379 wmem_free(NULL, addr_str);
7383 guid = (e_guid_t *)fvalue_get(&fi->value);
7384 tmp = guid_to_str(NULL, guid);
7385 label_fill(label_str, 0, hfinfo, tmp);
7386 wmem_free(NULL, tmp);
7390 bytes = (guint8 *)fvalue_get(&fi->value);
7391 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7392 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7394 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7395 wmem_free(NULL, name);
7397 label_fill(label_str, 0, hfinfo, tmp);
7399 wmem_free(NULL, tmp);
7403 bytes = (guint8 *)fvalue_get(&fi->value);
7404 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7405 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7407 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7408 wmem_free(NULL, name);
7410 label_fill(label_str, 0, hfinfo, tmp);
7412 wmem_free(NULL, tmp);
7416 bytes = (guint8 *)fvalue_get(&fi->value);
7417 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
7418 label_fill(label_str, 0, hfinfo, tmp);
7419 wmem_free(NULL, tmp);
7423 integer64 = fvalue_get_uinteger64(&fi->value);
7424 addr_str = eui64_to_str(NULL, integer64);
7425 tmp = (char*)eui64_to_display(NULL, integer64);
7426 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
7427 wmem_free(NULL, tmp);
7428 wmem_free(NULL, addr_str);
7432 case FT_UINT_STRING:
7434 bytes = (guint8 *)fvalue_get(&fi->value);
7435 label_fill(label_str, 0, hfinfo, hfinfo_format_text(hfinfo, bytes));
7438 case FT_IEEE_11073_SFLOAT:
7439 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7440 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7443 wmem_free(NULL, tmp);
7445 case FT_IEEE_11073_FLOAT:
7446 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7447 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7450 wmem_free(NULL, tmp);
7454 g_error("hfinfo->type %d (%s) not handled\n",
7455 hfinfo->type, ftype_name(hfinfo->type));
7456 DISSECTOR_ASSERT_NOT_REACHED();
7462 fill_label_boolean(field_info *fi, gchar *label_str)
7464 char *p = label_str;
7465 int bitfield_byte_length = 0, bitwidth;
7466 guint64 unshifted_value;
7469 header_field_info *hfinfo = fi->hfinfo;
7470 const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
7472 if (hfinfo->strings) {
7473 tfstring = (const struct true_false_string*) hfinfo->strings;
7476 value = fvalue_get_uinteger64(&fi->value);
7477 if (hfinfo->bitmask) {
7478 /* Figure out the bit width */
7479 bitwidth = hfinfo_container_bitwidth(hfinfo);
7482 unshifted_value = value;
7483 unshifted_value <<= hfinfo_bitshift(hfinfo);
7485 /* Create the bitfield first */
7486 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7487 bitfield_byte_length = (int) (p - label_str);
7490 /* Fill in the textual info */
7491 label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
7495 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
7497 if (hfinfo->display & BASE_RANGE_STRING)
7498 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
7500 if (hfinfo->display & BASE_EXT_STRING)
7501 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
7503 if (hfinfo->display & BASE_VAL64_STRING)
7504 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7506 return try_val_to_str(value, (const value_string *) hfinfo->strings);
7510 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
7512 if (hfinfo->display & BASE_VAL64_STRING)
7513 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7515 if (hfinfo->display & BASE_RANGE_STRING)
7516 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
7518 /* If this is reached somebody registered a 64-bit field with a 32-bit
7519 * value-string, which isn't right. */
7520 DISSECTOR_ASSERT_NOT_REACHED();
7522 /* This is necessary to squelch MSVC errors; is there
7523 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
7529 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
7531 const char *str = hf_try_val_to_str(value, hfinfo);
7533 return (str) ? str : unknown_str;
7537 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
7539 const char *str = hf_try_val64_to_str(value, hfinfo);
7541 return (str) ? str : unknown_str;
7544 /* Fills data for bitfield chars with val_strings */
7546 fill_label_bitfield_char(field_info *fi, gchar *label_str)
7549 int bitfield_byte_length, bitwidth;
7550 guint32 unshifted_value;
7556 header_field_info *hfinfo = fi->hfinfo;
7558 /* Figure out the bit width */
7559 bitwidth = hfinfo_container_bitwidth(hfinfo);
7562 value = fvalue_get_uinteger(&fi->value);
7564 unshifted_value = value;
7565 if (hfinfo->bitmask) {
7566 unshifted_value <<= hfinfo_bitshift(hfinfo);
7569 /* Create the bitfield first */
7570 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7571 bitfield_byte_length = (int) (p - label_str);
7573 /* Fill in the textual info using stored (shifted) value */
7574 if (hfinfo->display == BASE_CUSTOM) {
7575 gchar tmp[ITEM_LABEL_LENGTH];
7576 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7578 DISSECTOR_ASSERT(fmtfunc);
7579 fmtfunc(tmp, value);
7580 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7582 else if (hfinfo->strings) {
7583 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7585 out = hfinfo_char_vals_format(hfinfo, buf, value);
7586 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7587 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7589 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7592 out = hfinfo_char_value_format(hfinfo, buf, value);
7594 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7598 /* Fills data for bitfield ints with val_strings */
7600 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
7603 int bitfield_byte_length, bitwidth;
7604 guint32 unshifted_value;
7610 header_field_info *hfinfo = fi->hfinfo;
7612 /* Figure out the bit width */
7613 bitwidth = hfinfo_container_bitwidth(hfinfo);
7617 value = fvalue_get_sinteger(&fi->value);
7619 value = fvalue_get_uinteger(&fi->value);
7621 unshifted_value = value;
7622 if (hfinfo->bitmask) {
7623 unshifted_value <<= hfinfo_bitshift(hfinfo);
7626 /* Create the bitfield first */
7627 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7628 bitfield_byte_length = (int) (p - label_str);
7630 /* Fill in the textual info using stored (shifted) value */
7631 if (hfinfo->display == BASE_CUSTOM) {
7632 gchar tmp[ITEM_LABEL_LENGTH];
7633 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7635 DISSECTOR_ASSERT(fmtfunc);
7636 fmtfunc(tmp, value);
7637 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7639 else if (hfinfo->strings) {
7640 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7642 out = hfinfo_number_vals_format(hfinfo, buf, value);
7643 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7644 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7646 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7649 out = hfinfo_number_value_format(hfinfo, buf, value);
7651 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7656 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
7659 int bitfield_byte_length, bitwidth;
7660 guint64 unshifted_value;
7666 header_field_info *hfinfo = fi->hfinfo;
7668 /* Figure out the bit width */
7669 bitwidth = hfinfo_container_bitwidth(hfinfo);
7673 value = fvalue_get_sinteger64(&fi->value);
7675 value = fvalue_get_uinteger64(&fi->value);
7677 unshifted_value = value;
7678 if (hfinfo->bitmask) {
7679 unshifted_value <<= hfinfo_bitshift(hfinfo);
7682 /* Create the bitfield first */
7683 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7684 bitfield_byte_length = (int) (p - label_str);
7686 /* Fill in the textual info using stored (shifted) value */
7687 if (hfinfo->display == BASE_CUSTOM) {
7688 gchar tmp[ITEM_LABEL_LENGTH];
7689 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7691 DISSECTOR_ASSERT(fmtfunc64);
7692 fmtfunc64(tmp, value);
7693 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7695 else if (hfinfo->strings) {
7696 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7698 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7699 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7700 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7702 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7705 out = hfinfo_number_value_format64(hfinfo, buf, value);
7707 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7712 fill_label_char(field_info *fi, gchar *label_str)
7714 header_field_info *hfinfo = fi->hfinfo;
7720 value = fvalue_get_uinteger(&fi->value);
7722 /* Fill in the textual info */
7723 if (hfinfo->display == BASE_CUSTOM) {
7724 gchar tmp[ITEM_LABEL_LENGTH];
7725 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7727 DISSECTOR_ASSERT(fmtfunc);
7728 fmtfunc(tmp, value);
7729 label_fill(label_str, 0, hfinfo, tmp);
7731 else if (hfinfo->strings) {
7732 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7734 out = hfinfo_char_vals_format(hfinfo, buf, value);
7735 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7738 out = hfinfo_char_value_format(hfinfo, buf, value);
7740 label_fill(label_str, 0, hfinfo, out);
7745 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
7747 header_field_info *hfinfo = fi->hfinfo;
7754 value = fvalue_get_sinteger(&fi->value);
7756 value = fvalue_get_uinteger(&fi->value);
7758 /* Fill in the textual info */
7759 if (hfinfo->display == BASE_CUSTOM) {
7760 gchar tmp[ITEM_LABEL_LENGTH];
7761 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7763 DISSECTOR_ASSERT(fmtfunc);
7764 fmtfunc(tmp, value);
7765 label_fill(label_str, 0, hfinfo, tmp);
7767 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7769 * It makes no sense to have a value-string table for a
7770 * frame-number field - they're just integers giving
7771 * the ordinal frame number.
7773 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7775 out = hfinfo_number_vals_format(hfinfo, buf, value);
7776 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7777 label_fill(label_str, 0, hfinfo, val_str);
7779 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7781 else if (IS_BASE_PORT(hfinfo->display)) {
7782 gchar tmp[ITEM_LABEL_LENGTH];
7784 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
7785 display_to_port_type((field_display_e)hfinfo->display), value);
7786 label_fill(label_str, 0, hfinfo, tmp);
7789 out = hfinfo_number_value_format(hfinfo, buf, value);
7791 label_fill(label_str, 0, hfinfo, out);
7796 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
7798 header_field_info *hfinfo = fi->hfinfo;
7805 value = fvalue_get_sinteger64(&fi->value);
7807 value = fvalue_get_uinteger64(&fi->value);
7809 /* Fill in the textual info */
7810 if (hfinfo->display == BASE_CUSTOM) {
7811 gchar tmp[ITEM_LABEL_LENGTH];
7812 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7814 DISSECTOR_ASSERT(fmtfunc64);
7815 fmtfunc64(tmp, value);
7816 label_fill(label_str, 0, hfinfo, tmp);
7818 else if (hfinfo->strings) {
7819 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7821 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7822 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7823 label_fill(label_str, 0, hfinfo, val_str);
7825 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7828 out = hfinfo_number_value_format64(hfinfo, buf, value);
7830 label_fill(label_str, 0, hfinfo, out);
7835 hfinfo_bitshift(const header_field_info *hfinfo)
7837 return ws_ctz(hfinfo->bitmask);
7841 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
7843 if (!hfinfo->bitmask) {
7847 /* ilog2 = first set bit, ctz = last set bit */
7848 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
7852 hfinfo_type_bitwidth(enum ftenum type)
7891 DISSECTOR_ASSERT_NOT_REACHED();
7899 hfinfo_container_bitwidth(const header_field_info *hfinfo)
7901 if (!hfinfo->bitmask) {
7905 if (hfinfo->type == FT_BOOLEAN) {
7906 return hfinfo->display; /* hacky? :) */
7909 return hfinfo_type_bitwidth(hfinfo->type);
7913 hfinfo_hex_digits(const header_field_info *hfinfo)
7917 /* If we have a bitmask, hfinfo->type is the width of the container, so not
7918 * appropriate to determine the number of hex digits for the field.
7919 * So instead, we compute it from the bitmask.
7921 if (hfinfo->bitmask != 0) {
7922 bitwidth = hfinfo_mask_bitwidth(hfinfo);
7924 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
7927 /* Divide by 4, rounding up, to get number of hex digits. */
7928 return (bitwidth + 3) / 4;
7932 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
7934 char *ptr = &buf[6];
7935 static const gchar hex_digits[16] =
7936 { '0', '1', '2', '3', '4', '5', '6', '7',
7937 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
7941 /* Properly format value */
7942 if (g_ascii_isprint(value)) {
7944 * Printable, so just show the character, and, if it needs
7945 * to be escaped, escape it.
7948 if (value == '\\' || value == '\'')
7952 * Non-printable; show it as an escape sequence.
7958 * Show a NUL with only one digit.
7992 switch (display & FIELD_DISPLAY_E_MASK) {
7995 *(--ptr) = (value & 0x7) + '0';
7997 *(--ptr) = (value & 0x7) + '0';
7999 *(--ptr) = (value & 0x7) + '0';
8003 *(--ptr) = hex_digits[value & 0x0F];
8005 *(--ptr) = hex_digits[value & 0x0F];
8010 g_assert_not_reached();
8020 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
8022 char *ptr = &buf[31];
8023 gboolean isint = IS_FT_INT(hfinfo->type);
8026 /* Properly format value */
8027 switch (display & FIELD_DISPLAY_E_MASK) {
8029 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8033 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8036 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8040 return oct_to_str_back(ptr, value);
8043 return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8047 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8050 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8057 port_with_resolution_to_str_buf(buf, 32,
8058 display_to_port_type((field_display_e)display), value);
8062 g_assert_not_reached();
8068 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
8070 char *ptr = &buf[47];
8071 gboolean isint = IS_FT_INT(hfinfo->type);
8074 /* Properly format value */
8077 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8081 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8084 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8088 return oct64_to_str_back(ptr, value);
8091 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8095 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8098 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8102 g_assert_not_reached();
8108 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8110 int display = hfinfo->display;
8112 if (hfinfo->type == FT_FRAMENUM) {
8114 * Frame numbers are always displayed in decimal.
8119 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8123 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8125 int display = hfinfo->display;
8127 if (hfinfo->type == FT_FRAMENUM) {
8129 * Frame numbers are always displayed in decimal.
8134 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8138 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8140 /* Get the underlying BASE_ value */
8141 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8143 return hfinfo_char_value_format_display(display, buf, value);
8147 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8149 /* Get the underlying BASE_ value */
8150 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8152 if (hfinfo->type == FT_FRAMENUM) {
8154 * Frame numbers are always displayed in decimal.
8159 if (IS_BASE_PORT(display)) {
8165 /* case BASE_DEC: */
8167 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
8172 /* case BASE_HEX: */
8178 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8182 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8184 /* Get the underlying BASE_ value */
8185 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8187 if (hfinfo->type == FT_FRAMENUM) {
8189 * Frame numbers are always displayed in decimal.
8196 /* case BASE_DEC: */
8198 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
8203 /* case BASE_HEX: */
8209 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8213 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8215 /* Get the underlying BASE_ value */
8216 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8218 return hfinfo_char_value_format_display(display, buf, value);
8222 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8224 /* Get the underlying BASE_ value */
8225 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8227 if (display == BASE_NONE)
8230 if (display == BASE_DEC_HEX)
8232 if (display == BASE_HEX_DEC)
8235 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8239 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8241 /* Get the underlying BASE_ value */
8242 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8244 if (display == BASE_NONE)
8247 if (display == BASE_DEC_HEX)
8249 if (display == BASE_HEX_DEC)
8252 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8256 proto_registrar_get_name(const int n)
8258 header_field_info *hfinfo;
8260 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8261 return hfinfo->name;
8265 proto_registrar_get_abbrev(const int n)
8267 header_field_info *hfinfo;
8269 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8270 return hfinfo->abbrev;
8274 proto_registrar_get_ftype(const int n)
8276 header_field_info *hfinfo;
8278 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8279 return hfinfo->type;
8283 proto_registrar_get_parent(const int n)
8285 header_field_info *hfinfo;
8287 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8288 return hfinfo->parent;
8292 proto_registrar_is_protocol(const int n)
8294 header_field_info *hfinfo;
8296 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8297 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
8300 /* Returns length of field in packet (not necessarily the length
8301 * in our internal representation, as in the case of IPv4).
8302 * 0 means undeterminable at time of registration
8303 * -1 means the field is not registered. */
8305 proto_registrar_get_length(const int n)
8307 header_field_info *hfinfo;
8309 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8310 return ftype_length(hfinfo->type);
8313 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
8314 * it exists anywhere, or FALSE if it exists nowhere. */
8316 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
8318 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
8320 if (g_ptr_array_len(ptrs) > 0) {
8328 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
8329 * This only works if the hfindex was "primed" before the dissection
8330 * took place, as we just pass back the already-created GPtrArray*.
8331 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
8334 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
8339 if (PTREE_DATA(tree)->interesting_hfids != NULL)
8340 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
8341 GINT_TO_POINTER(id));
8347 proto_tracking_interesting_fields(const proto_tree *tree)
8349 GHashTable *interesting_hfids;
8354 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
8356 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
8359 /* Helper struct for proto_find_info() and proto_all_finfos() */
8365 /* Helper function for proto_find_info() */
8367 find_finfo(proto_node *node, gpointer data)
8369 field_info *fi = PNODE_FINFO(node);
8370 if (fi && fi->hfinfo) {
8371 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8372 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8376 /* Don't stop traversing. */
8380 /* Helper function for proto_find_first_info() */
8382 find_first_finfo(proto_node *node, gpointer data)
8384 field_info *fi = PNODE_FINFO(node);
8385 if (fi && fi->hfinfo) {
8386 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8387 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8391 /* Stop traversing. */
8395 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
8396 * This works on any proto_tree, primed or unprimed, but actually searches
8397 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8398 * The caller does need to free the returned GPtrArray with
8399 * g_ptr_array_free(<array>, TRUE).
8402 proto_find_finfo(proto_tree *tree, const int id)
8406 ffdata.array = g_ptr_array_new();
8409 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
8411 return ffdata.array;
8414 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
8415 * This works on any proto_tree, primed or unprimed, but actually searches
8416 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8417 * The caller does need to free the returned GPtrArray with
8418 * g_ptr_array_free(<array>, TRUE).
8421 proto_find_first_finfo(proto_tree *tree, const int id)
8425 ffdata.array = g_ptr_array_new();
8428 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
8430 return ffdata.array;
8433 /* Helper function for proto_all_finfos() */
8435 every_finfo(proto_node *node, gpointer data)
8437 field_info *fi = PNODE_FINFO(node);
8438 if (fi && fi->hfinfo) {
8439 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8442 /* Don't stop traversing. */
8446 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
8448 proto_all_finfos(proto_tree *tree)
8452 /* Pre allocate enough space to hold all fields in most cases */
8453 ffdata.array = g_ptr_array_sized_new(512);
8456 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
8458 return ffdata.array;
8469 check_for_offset(proto_node *node, gpointer data)
8471 field_info *fi = PNODE_FINFO(node);
8472 offset_search_t *offsearch = (offset_search_t *)data;
8474 /* !fi == the top most container node which holds nothing */
8475 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
8476 if (offsearch->offset >= (guint) fi->start &&
8477 offsearch->offset < (guint) (fi->start + fi->length)) {
8479 offsearch->finfo = fi;
8480 return FALSE; /* keep traversing */
8483 return FALSE; /* keep traversing */
8486 /* Search a proto_tree backwards (from leaves to root) looking for the field
8487 * whose start/length occupies 'offset' */
8488 /* XXX - I couldn't find an easy way to search backwards, so I search
8489 * forwards, w/o stopping. Therefore, the last finfo I find will the be
8490 * the one I want to return to the user. This algorithm is inefficient
8491 * and could be re-done, but I'd have to handle all the children and
8492 * siblings of each node myself. When I have more time I'll do that.
8495 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
8497 offset_search_t offsearch;
8499 offsearch.offset = offset;
8500 offsearch.finfo = NULL;
8501 offsearch.tvb = tvb;
8503 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
8505 return offsearch.finfo;
8510 check_for_undecoded(proto_node *node, gpointer data)
8512 field_info *fi = PNODE_FINFO(node);
8513 gchar* decoded = (gchar*)data;
8518 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
8519 for (i = fi->start; i < fi->start + fi->length; i++) {
8522 decoded[byte] |= (1 << bit);
8530 proto_find_undecoded_data(proto_tree *tree, guint length)
8532 gchar* decoded = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
8534 proto_tree_traverse_pre_order(tree, check_for_undecoded, decoded);
8538 /* Dumps the protocols in the registration database to stdout. An independent
8539 * program can take this output and format it into nice tables or HTML or
8542 * There is one record per line. The fields are tab-delimited.
8544 * Field 1 = protocol name
8545 * Field 2 = protocol short name
8546 * Field 3 = protocol filter name
8549 proto_registrar_dump_protocols(void)
8551 protocol_t *protocol;
8553 void *cookie = NULL;
8556 i = proto_get_first_protocol(&cookie);
8558 protocol = find_protocol_by_id(i);
8559 ws_debug_printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
8560 protocol->filter_name);
8561 i = proto_get_next_protocol(&cookie);
8565 /* Dumps the value_strings, extended value string headers, range_strings
8566 * or true/false strings for fields that have them.
8567 * There is one record per line. Fields are tab-delimited.
8568 * There are four types of records: Value String, Extended Value String Header,
8569 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
8570 * the type of record.
8572 * Note that a record will be generated only if the value_string,... is referenced
8573 * in a registered hfinfo entry.
8579 * Field 2 = Field abbreviation to which this value string corresponds
8580 * Field 3 = Integer value
8583 * Extended Value String Headers
8584 * -----------------------------
8586 * Field 2 = Field abbreviation to which this extended value string header corresponds
8587 * Field 3 = Extended Value String "Name"
8588 * Field 4 = Number of entries in the associated value_string array
8589 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
8594 * Field 2 = Field abbreviation to which this range string corresponds
8595 * Field 3 = Integer value: lower bound
8596 * Field 4 = Integer value: upper bound
8599 * True/False Strings
8600 * ------------------
8602 * Field 2 = Field abbreviation to which this true/false string corresponds
8603 * Field 3 = True String
8604 * Field 4 = False String
8607 proto_registrar_dump_values(void)
8609 header_field_info *hfinfo;
8611 const value_string *vals;
8612 const val64_string *vals64;
8613 const range_string *range;
8614 const true_false_string *tfs;
8616 len = gpa_hfinfo.len;
8617 for (i = 0; i < len ; i++) {
8618 if (gpa_hfinfo.hfi[i] == NULL)
8619 continue; /* This is a deregistered protocol or field */
8621 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8623 if (hfinfo->id == hf_text_only) {
8627 /* ignore protocols */
8628 if (proto_registrar_is_protocol(i)) {
8631 /* process header fields */
8632 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
8634 * If this field isn't at the head of the list of
8635 * fields with this name, skip this field - all
8636 * fields with the same name are really just versions
8637 * of the same field stored in different bits, and
8638 * should have the same type/radix/value list, and
8639 * just differ in their bit masks. (If a field isn't
8640 * a bitfield, but can be, say, 1 or 2 bytes long,
8641 * it can just be made FT_UINT16, meaning the
8642 * *maximum* length is 2 bytes, and be used
8645 if (hfinfo->same_name_prev_id != -1)
8653 if (hfinfo->strings != NULL) {
8654 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) != BASE_CUSTOM &&
8655 (hfinfo->type == FT_CHAR ||
8656 hfinfo->type == FT_UINT8 ||
8657 hfinfo->type == FT_UINT16 ||
8658 hfinfo->type == FT_UINT24 ||
8659 hfinfo->type == FT_UINT32 ||
8660 hfinfo->type == FT_UINT40 ||
8661 hfinfo->type == FT_UINT48 ||
8662 hfinfo->type == FT_UINT56 ||
8663 hfinfo->type == FT_UINT64 ||
8664 hfinfo->type == FT_INT8 ||
8665 hfinfo->type == FT_INT16 ||
8666 hfinfo->type == FT_INT24 ||
8667 hfinfo->type == FT_INT32 ||
8668 hfinfo->type == FT_INT40 ||
8669 hfinfo->type == FT_INT48 ||
8670 hfinfo->type == FT_INT56 ||
8671 hfinfo->type == FT_INT64)) {
8673 if (hfinfo->display & BASE_RANGE_STRING) {
8674 range = (const range_string *)hfinfo->strings;
8675 } else if (hfinfo->display & BASE_EXT_STRING) {
8676 vals = VALUE_STRING_EXT_VS_P((value_string_ext *)hfinfo->strings);
8677 } else if (hfinfo->display & BASE_VAL64_STRING) {
8678 vals64 = (const val64_string *)hfinfo->strings;
8680 vals = (const value_string *)hfinfo->strings;
8683 else if (hfinfo->type == FT_BOOLEAN) {
8684 tfs = (const struct true_false_string *)hfinfo->strings;
8688 /* Print value strings? */
8690 if (hfinfo->display & BASE_EXT_STRING) {
8691 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
8692 if (!value_string_ext_validate(vse_p)) {
8693 ws_g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
8696 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
8697 ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
8699 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
8700 VALUE_STRING_EXT_VS_NAME(vse_p),
8701 value_string_ext_match_type_str(vse_p));
8704 while (vals[vi].strptr) {
8705 /* Print in the proper base */
8706 if (hfinfo->type == FT_CHAR) {
8707 if (g_ascii_isprint(vals[vi].value)) {
8708 ws_debug_printf("V\t%s\t'%c'\t%s\n",
8713 if (hfinfo->display == BASE_HEX) {
8714 ws_debug_printf("V\t%s\t'\\x%02x'\t%s\n",
8720 ws_debug_printf("V\t%s\t'\\%03o'\t%s\n",
8727 if (hfinfo->display == BASE_HEX) {
8728 ws_debug_printf("V\t%s\t0x%x\t%s\n",
8734 ws_debug_printf("V\t%s\t%u\t%s\n",
8745 while (vals64[vi].strptr) {
8746 ws_debug_printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
8754 /* print range strings? */
8757 while (range[vi].strptr) {
8758 /* Print in the proper base */
8759 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_HEX) {
8760 ws_debug_printf("R\t%s\t0x%x\t0x%x\t%s\n",
8762 range[vi].value_min,
8763 range[vi].value_max,
8767 ws_debug_printf("R\t%s\t%u\t%u\t%s\n",
8769 range[vi].value_min,
8770 range[vi].value_max,
8777 /* Print true/false strings? */
8779 ws_debug_printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
8780 tfs->true_string, tfs->false_string);
8785 /* Prints the number of registered fields.
8786 * Useful for determining an appropriate value for
8787 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
8789 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
8790 * the number of fields, TRUE otherwise.
8793 proto_registrar_dump_fieldcount(void)
8796 header_field_info *hfinfo;
8797 guint32 deregistered_count = 0;
8798 guint32 same_name_count = 0;
8799 guint32 protocol_count = 0;
8801 for (i = 0; i < gpa_hfinfo.len; i++) {
8802 if (gpa_hfinfo.hfi[i] == NULL) {
8803 deregistered_count++;
8804 continue; /* This is a deregistered protocol or header field */
8807 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8809 if (proto_registrar_is_protocol(i))
8812 if (hfinfo->same_name_prev_id != -1)
8816 ws_debug_printf("There are %u header fields registered, of which:\n"
8817 "\t%u are deregistered\n"
8818 "\t%u are protocols\n"
8819 "\t%u have the same name as another field\n\n",
8820 gpa_hfinfo.len, deregistered_count, protocol_count,
8823 ws_debug_printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
8824 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
8825 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
8828 ws_debug_printf("The header field table consumes %u KiB of memory.\n",
8829 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
8830 ws_debug_printf("The fields themselves consume %u KiB of memory.\n",
8831 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
8833 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8837 /* Dumps the contents of the registration database to stdout. An independent
8838 * program can take this output and format it into nice tables or HTML or
8841 * There is one record per line. Each record is either a protocol or a header
8842 * field, differentiated by the first field. The fields are tab-delimited.
8847 * Field 2 = descriptive protocol name
8848 * Field 3 = protocol abbreviation
8853 * Field 2 = descriptive field name
8854 * Field 3 = field abbreviation
8855 * Field 4 = type ( textual representation of the the ftenum type )
8856 * Field 5 = parent protocol abbreviation
8857 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
8858 * Field 7 = bitmask: format: hex: 0x....
8859 * Field 8 = blurb describing field
8862 proto_registrar_dump_fields(void)
8864 header_field_info *hfinfo, *parent_hfinfo;
8866 const char *enum_name;
8867 const char *base_name;
8871 len = gpa_hfinfo.len;
8872 for (i = 0; i < len ; i++) {
8873 if (gpa_hfinfo.hfi[i] == NULL)
8874 continue; /* This is a deregistered protocol or header field */
8876 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8879 * Skip the pseudo-field for "proto_tree_add_text()" since
8880 * we don't want it in the list of filterable fields.
8882 if (hfinfo->id == hf_text_only)
8885 /* format for protocols */
8886 if (proto_registrar_is_protocol(i)) {
8887 ws_debug_printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
8889 /* format for header fields */
8892 * If this field isn't at the head of the list of
8893 * fields with this name, skip this field - all
8894 * fields with the same name are really just versions
8895 * of the same field stored in different bits, and
8896 * should have the same type/radix/value list, and
8897 * just differ in their bit masks. (If a field isn't
8898 * a bitfield, but can be, say, 1 or 2 bytes long,
8899 * it can just be made FT_UINT16, meaning the
8900 * *maximum* length is 2 bytes, and be used
8903 if (hfinfo->same_name_prev_id != -1)
8906 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
8908 enum_name = ftype_name(hfinfo->type);
8911 if (hfinfo->type == FT_CHAR ||
8912 hfinfo->type == FT_UINT8 ||
8913 hfinfo->type == FT_UINT16 ||
8914 hfinfo->type == FT_UINT24 ||
8915 hfinfo->type == FT_UINT32 ||
8916 hfinfo->type == FT_UINT40 ||
8917 hfinfo->type == FT_UINT48 ||
8918 hfinfo->type == FT_UINT56 ||
8919 hfinfo->type == FT_UINT64 ||
8920 hfinfo->type == FT_INT8 ||
8921 hfinfo->type == FT_INT16 ||
8922 hfinfo->type == FT_INT24 ||
8923 hfinfo->type == FT_INT32 ||
8924 hfinfo->type == FT_INT40 ||
8925 hfinfo->type == FT_INT48 ||
8926 hfinfo->type == FT_INT56 ||
8927 hfinfo->type == FT_INT64) {
8929 switch (FIELD_DISPLAY(hfinfo->display)) {
8941 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
8947 } else if (hfinfo->type == FT_BOOLEAN) {
8948 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
8949 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
8953 blurb = hfinfo->blurb;
8956 else if (strlen(blurb) == 0)
8959 ws_debug_printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
8960 hfinfo->name, hfinfo->abbrev, enum_name,
8961 parent_hfinfo->abbrev, base_name,
8962 hfinfo->bitmask, blurb);
8967 /* Dumps field types and descriptive names to stdout. An independent
8968 * program can take this output and format it into nice tables or HTML or
8971 * There is one record per line. The fields are tab-delimited.
8973 * Field 1 = field type name, e.g. FT_UINT8
8974 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
8977 proto_registrar_dump_ftypes(void)
8981 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
8982 ws_debug_printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
8986 /* This function indicates whether it's possible to construct a
8987 * "match selected" display filter string for the specified field,
8988 * returns an indication of whether it's possible, and, if it's
8989 * possible and "filter" is non-null, constructs the filter and
8990 * sets "*filter" to point to it.
8991 * You do not need to [g_]free() this string since it will be automatically
8992 * freed once the next packet is dissected.
8995 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
8998 header_field_info *hfinfo;
9003 gint start, length, length_remaining;
9005 gchar is_signed_num = FALSE;
9010 hfinfo = finfo->hfinfo;
9011 DISSECTOR_ASSERT(hfinfo);
9012 abbrev_len = (int) strlen(hfinfo->abbrev);
9014 if (hfinfo->strings && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
9015 const gchar *str = NULL;
9017 switch (hfinfo->type) {
9023 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
9031 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
9038 if (str != NULL && filter != NULL) {
9039 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
9045 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
9046 * functions for FT_UINT and FT_INT types, as we choose the base in
9047 * the string expression based on the display base of the field.
9049 * Note that the base does matter, as this is also used for
9050 * the protocolinfo tap.
9052 * It might be nice to use them in "proto_item_fill_label()"
9053 * as well, although, there, you'd have to deal with the base
9054 * *and* with resolved values for addresses.
9056 * Perhaps we need two different val_to_string routines, one
9057 * to generate items for display filters and one to generate
9058 * strings for display, and pass to both of them the
9059 * "display" and "strings" values in the header_field_info
9060 * structure for the field, so they can get the base and,
9061 * if the field is Boolean or an enumerated integer type,
9062 * the tables used to generate human-readable values.
9064 switch (hfinfo->type) {
9067 if (filter != NULL) {
9073 number = fvalue_get_uinteger(&finfo->value);
9075 out = hfinfo_char_value_format(hfinfo, buf, number);
9077 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9085 is_signed_num = TRUE;
9092 if (filter != NULL) {
9099 number = fvalue_get_sinteger(&finfo->value);
9101 number = fvalue_get_uinteger(&finfo->value);
9103 out = hfinfo_numeric_value_format(hfinfo, buf, number);
9105 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9113 is_signed_num = TRUE;
9119 if (filter != NULL) {
9126 number = fvalue_get_sinteger64(&finfo->value);
9128 number = fvalue_get_uinteger64(&finfo->value);
9130 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
9132 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9138 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
9143 * If the length is 0, just match the name of the
9146 * (Also check for negative values, just in case,
9147 * as we'll cast it to an unsigned value later.)
9149 length = finfo->length;
9152 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
9159 * This doesn't have a value, so we'd match
9160 * on the raw bytes at this address.
9162 * Should we be allowed to access to the raw bytes?
9163 * If "edt" is NULL, the answer is "no".
9169 * Is this field part of the raw frame tvbuff?
9170 * If not, we can't use "frame[N:M]" to match
9173 * XXX - should this be frame-relative, or
9174 * protocol-relative?
9176 * XXX - does this fallback for non-registered
9177 * fields even make sense?
9179 if (finfo->ds_tvb != edt->tvb)
9180 return FALSE; /* you lose */
9183 * Don't go past the end of that tvbuff.
9185 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
9186 if (length > length_remaining)
9187 length = length_remaining;
9191 if (filter != NULL) {
9192 start = finfo->start;
9193 buf_len = 32 + length * 3;
9194 *filter = (char *)wmem_alloc0(NULL, buf_len);
9197 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
9198 "frame[%d:%d] == ", finfo->start, length);
9199 for (i=0; i<length; i++) {
9200 c = tvb_get_guint8(finfo->ds_tvb, start);
9203 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
9206 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
9213 /* FT_PCRE never appears as a type for a registered field. It is
9214 * only used internally. */
9215 DISSECTOR_ASSERT_NOT_REACHED();
9218 /* By default, use the fvalue's "to_string_repr" method. */
9220 /* Figure out the string length needed.
9221 * The ft_repr length.
9222 * 4 bytes for " == ".
9223 * 1 byte for trailing NUL.
9225 if (filter != NULL) {
9227 dfilter_len = fvalue_string_repr_len(&finfo->value,
9228 FTREPR_DFILTER, finfo->hfinfo->display);
9229 dfilter_len += abbrev_len + 4 + 1;
9230 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
9232 /* Create the string */
9233 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
9234 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
9235 wmem_free(NULL, str);
9244 * Returns TRUE if we can do a "match selected" on the field, FALSE
9248 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
9250 return construct_match_selected_string(finfo, edt, NULL);
9253 /* This function attempts to construct a "match selected" display filter
9254 * string for the specified field; if it can do so, it returns a pointer
9255 * to the string, otherwise it returns NULL.
9257 * The string is allocated with packet lifetime scope.
9258 * You do not need to [g_]free() this string since it will be automatically
9259 * freed once the next packet is dissected.
9262 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
9264 char *filter = NULL;
9266 if (!construct_match_selected_string(finfo, edt, &filter))
9268 wmem_free(NULL, filter);
9274 /* This function is common code for all proto_tree_add_bitmask... functions.
9278 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
9279 const int len, const gint ett, const int **fields,
9280 const int flags, gboolean first,
9281 gboolean use_parent_tree,
9282 proto_tree* tree, guint64 value)
9285 guint64 available_bits = 0;
9287 header_field_info *hf;
9289 if (len < 0 || len > 8)
9290 g_assert_not_reached();
9291 bitshift = (8 - (guint)len)*8;
9292 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
9294 if (use_parent_tree == FALSE)
9295 tree = proto_item_add_subtree(item, ett);
9298 guint64 present_bits;
9299 PROTO_REGISTRAR_GET_NTH(**fields,hf);
9300 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
9302 /* Skip fields that aren't fully present */
9303 present_bits = available_bits & hf->bitmask;
9304 if (present_bits != hf->bitmask) {
9319 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
9330 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
9334 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
9338 DISSECTOR_ASSERT_NOT_REACHED();
9341 if (flags & BMT_NO_APPEND) {
9345 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
9349 if (hf->display == BASE_CUSTOM) {
9350 gchar lbl[ITEM_LABEL_LENGTH];
9351 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9353 DISSECTOR_ASSERT(fmtfunc);
9354 fmtfunc(lbl, (guint32) tmpval);
9355 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9359 else if (hf->strings) {
9360 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9361 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
9364 else if (!(flags & BMT_NO_INT)) {
9369 proto_item_append_text(item, ", ");
9372 out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
9373 proto_item_append_text(item, "%s: %s", hf->name, out);
9395 if (hf->display == BASE_CUSTOM) {
9396 gchar lbl[ITEM_LABEL_LENGTH];
9397 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9399 DISSECTOR_ASSERT(fmtfunc);
9400 fmtfunc(lbl, (guint32) tmpval);
9401 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9405 else if (hf->strings) {
9406 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9407 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
9410 else if (!(flags & BMT_NO_INT)) {
9415 proto_item_append_text(item, ", ");
9418 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
9419 proto_item_append_text(item, "%s: %s", hf->name, out);
9425 if (hf->strings && !(flags & BMT_NO_TFS)) {
9426 /* If we have true/false strings, emit full - otherwise messages
9428 const struct true_false_string *tfs =
9429 (const struct true_false_string *)hf->strings;
9432 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9433 hf->name, tfs->true_string);
9435 } else if (!(flags & BMT_NO_FALSE)) {
9436 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9437 hf->name, tfs->false_string);
9440 } else if (hf->bitmask & value) {
9441 /* If the flag is set, show the name */
9442 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
9447 DISSECTOR_ASSERT_NOT_REACHED();
9457 /* This function will dissect a sequence of bytes that describe a
9458 * bitmask and supply the value of that sequence through a pointer.
9459 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9461 * This field will form an expansion under which the individual fields of the
9462 * bitmask is dissected and displayed.
9463 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9465 * fields is an array of pointers to int that lists all the fields of the
9466 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9467 * or another integer of the same type/size as hf_hdr with a mask specified.
9468 * This array is terminated by a NULL entry.
9470 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9471 * FT_integer fields that have a value_string attached will have the
9472 * matched string displayed on the expansion line.
9475 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
9476 const guint offset, const int hf_hdr,
9477 const gint ett, const int **fields,
9478 const guint encoding, guint64 *retval)
9480 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);
9483 /* This function will dissect a sequence of bytes that describe a
9485 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9487 * This field will form an expansion under which the individual fields of the
9488 * bitmask is dissected and displayed.
9489 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9491 * fields is an array of pointers to int that lists all the fields of the
9492 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9493 * or another integer of the same type/size as hf_hdr with a mask specified.
9494 * This array is terminated by a NULL entry.
9496 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9497 * FT_integer fields that have a value_string attached will have the
9498 * matched string displayed on the expansion line.
9501 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
9502 const guint offset, const int hf_hdr,
9503 const gint ett, const int **fields,
9504 const guint encoding)
9506 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
9509 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9510 * what data is appended to the header.
9513 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9514 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
9517 proto_item *item = NULL;
9518 header_field_info *hf;
9522 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9523 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9524 len = ftype_length(hf->type);
9525 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9528 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9529 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9530 flags, FALSE, FALSE, NULL, value);
9537 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9538 * what data is appended to the header.
9541 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9542 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
9544 proto_item *item = NULL;
9545 header_field_info *hf;
9549 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9550 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9553 len = ftype_length(hf->type);
9554 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9555 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9556 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9557 flags, FALSE, FALSE, NULL, value);
9563 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
9564 can't be retrieved directly from tvb) */
9566 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9567 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
9569 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
9570 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
9573 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
9574 WS_DLL_PUBLIC proto_item *
9575 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9576 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
9578 proto_item *item = NULL;
9579 header_field_info *hf;
9582 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9583 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9584 len = ftype_length(hf->type);
9588 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
9590 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
9592 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9593 flags, FALSE, FALSE, NULL, value);
9599 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
9601 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9602 const int len, const int **fields, const guint encoding)
9607 value = get_uint64_value(tree, tvb, offset, len, encoding);
9608 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9609 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9614 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9615 const int len, const int **fields, const guint64 value)
9618 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9619 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9624 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
9625 * This is intended to support bitmask fields whose lengths can vary, perhaps
9626 * as the underlying standard evolves over time.
9627 * With this API there is the possibility of being called to display more or
9628 * less data than the dissector was coded to support.
9629 * In such cases, it is assumed that bitmasks are extended on the MSb end.
9630 * Thus when presented with "too much" or "too little" data, MSbits will be
9631 * ignored or MSfields sacrificed.
9633 * Only fields for which all defined bits are available are displayed.
9636 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
9637 const guint offset, const guint len, const int hf_hdr,
9638 const gint ett, const int **fields, struct expert_field* exp,
9639 const guint encoding)
9641 proto_item *item = NULL;
9642 header_field_info *hf;
9643 guint decodable_len;
9644 guint decodable_offset;
9645 guint32 decodable_value;
9648 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
9649 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9651 decodable_offset = offset;
9652 decodable_len = MIN(len, (guint) ftype_length(hf->type));
9654 /* If we are ftype_length-limited,
9655 * make sure we decode as many LSBs as possible.
9657 if (encoding == ENC_BIG_ENDIAN) {
9658 decodable_offset += (len - decodable_len);
9662 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
9663 decodable_len, encoding);
9665 /* The root item covers all the bytes even if we can't decode them all */
9666 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
9670 if (decodable_len < len) {
9671 /* Dissector likely requires updating for new protocol revision */
9672 expert_add_info_format(NULL, item, exp,
9673 "Only least-significant %d of %d bytes decoded",
9674 decodable_len, len);
9678 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
9679 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
9680 ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
9686 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
9688 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
9689 const guint offset, const guint len,
9690 const char *name, const char *fallback,
9691 const gint ett, const int **fields,
9692 const guint encoding, const int flags)
9694 proto_item *item = NULL;
9698 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
9699 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9700 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9701 flags, TRUE, FALSE, NULL, value) && fallback) {
9702 /* Still at first item - append 'fallback' text if any */
9703 proto_item_append_text(item, "%s", fallback);
9711 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9712 const guint bit_offset, const gint no_of_bits,
9713 const guint encoding)
9715 header_field_info *hfinfo;
9719 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9721 octet_length = (no_of_bits + 7) >> 3;
9722 octet_offset = bit_offset >> 3;
9723 test_length(hfinfo, tvb, octet_offset, octet_length);
9725 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
9726 * but only after doing a bunch more work (which we can, in the common
9727 * case, shortcut here).
9729 CHECK_FOR_NULL_TREE(tree);
9730 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9732 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
9736 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
9737 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
9738 * Offset should be given in bits from the start of the tvb.
9742 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9743 const guint bit_offset, const gint no_of_bits,
9744 guint64 *return_value, const guint encoding)
9750 char lbl_str[ITEM_LABEL_LENGTH];
9754 header_field_info *hf_field;
9756 const true_false_string *tfstring;
9758 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
9759 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
9761 if (hf_field->bitmask != 0) {
9762 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9763 "Incompatible use of proto_tree_add_bits_ret_val"
9764 " with field '%s' (%s) with bitmask != 0",
9765 hf_field->abbrev, hf_field->name));
9768 DISSECTOR_ASSERT(no_of_bits > 0);
9770 /* Byte align offset */
9771 offset = bit_offset>>3;
9774 * Calculate the number of octets used to hold the bits
9776 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
9777 length = (tot_no_bits + 7) >> 3;
9779 if (no_of_bits < 65) {
9780 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
9782 DISSECTOR_ASSERT_NOT_REACHED();
9786 /* Sign extend for signed types */
9787 switch (hf_field->type) {
9796 value = ws_sign_ext64(value, no_of_bits);
9804 *return_value = value;
9807 /* Coast clear. Try and fake it */
9808 CHECK_FOR_NULL_TREE(tree);
9809 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9811 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
9813 switch (hf_field->type) {
9816 tfstring = (const true_false_string *) &tfs_true_false;
9817 if (hf_field->strings)
9818 tfstring = (const true_false_string *)hf_field->strings;
9819 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
9821 bf_str, hf_field->name,
9822 (guint64)value ? tfstring->true_string : tfstring->false_string);
9826 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
9827 fill_label_char(PITEM_FINFO(pi), lbl_str);
9834 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
9835 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
9842 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
9843 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
9850 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
9851 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
9858 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
9859 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
9863 DISSECTOR_ASSERT_NOT_REACHED();
9868 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
9873 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9874 const guint bit_offset, const crumb_spec_t *crumb_spec,
9875 guint64 *return_value)
9880 guint mask_initial_bit_offset;
9881 guint mask_greatest_bit_offset;
9885 char lbl_str[ITEM_LABEL_LENGTH];
9887 guint64 composite_bitmask;
9888 guint64 composite_bitmap;
9890 header_field_info *hf_field;
9891 const true_false_string *tfstring;
9893 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
9894 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
9896 if (hf_field->bitmask != 0) {
9897 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9898 "Incompatible use of proto_tree_add_split_bits_item_ret_val"
9899 " with field '%s' (%s) with bitmask != 0",
9900 hf_field->abbrev, hf_field->name));
9903 mask_initial_bit_offset = bit_offset % 8;
9908 mask_greatest_bit_offset = 0;
9909 composite_bitmask = 0;
9910 composite_bitmap = 0;
9912 while (crumb_spec[i].crumb_bit_length != 0) {
9913 guint64 crumb_mask, crumb_value;
9914 guint8 crumb_end_bit_offset;
9916 DISSECTOR_ASSERT(i < 64);
9917 crumb_value = tvb_get_bits64(tvb,
9918 bit_offset + crumb_spec[i].crumb_bit_offset,
9919 crumb_spec[i].crumb_bit_length,
9921 value += crumb_value;
9922 no_of_bits += crumb_spec[i].crumb_bit_length;
9924 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
9925 octet containing the initial offset.
9926 If the mask is beyond 32 bits, then give up on bit map display.
9927 This could be improved in future, probably showing a table
9928 of 32 or 64 bits per row */
9929 if (mask_greatest_bit_offset < 32) {
9930 crumb_end_bit_offset = mask_initial_bit_offset
9931 + crumb_spec[i].crumb_bit_offset
9932 + crumb_spec[i].crumb_bit_length;
9933 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
9935 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
9936 mask_greatest_bit_offset = crumb_end_bit_offset;
9938 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
9939 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
9941 /* Shift left for the next segment */
9942 value <<= crumb_spec[++i].crumb_bit_length;
9945 /* Sign extend for signed types */
9946 switch (hf_field->type) {
9955 value = ws_sign_ext64(value, no_of_bits);
9962 *return_value = value;
9965 /* Coast clear. Try and fake it */
9966 CHECK_FOR_NULL_TREE(tree);
9967 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9969 /* initialise the format string */
9972 octet_offset = bit_offset >> 3;
9974 /* Round up mask length to nearest octet */
9975 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
9976 mask_greatest_bit_offset = octet_length << 3;
9978 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
9979 It would be a useful enhancement to eliminate this restriction. */
9980 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
9981 other_decode_bitfield_value(bf_str,
9982 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
9983 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
9984 mask_greatest_bit_offset);
9987 switch (hf_field->type) {
9988 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
9990 tfstring = (const true_false_string *) &tfs_true_false;
9991 if (hf_field->strings)
9992 tfstring = (const true_false_string *) hf_field->strings;
9993 return proto_tree_add_boolean_format(tree, hfindex,
9994 tvb, octet_offset, octet_length, (guint32)value,
9996 bf_str, hf_field->name,
9997 (guint64)value ? tfstring->true_string : tfstring->false_string);
10001 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
10002 fill_label_char(PITEM_FINFO(pi), lbl_str);
10009 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
10010 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
10017 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
10018 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
10025 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
10026 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
10033 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
10034 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
10038 DISSECTOR_ASSERT_NOT_REACHED();
10042 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
10047 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
10048 const crumb_spec_t *crumb_spec, guint16 crumb_index)
10050 header_field_info *hfinfo;
10052 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
10053 proto_tree_add_text_internal(tree, tvb,
10055 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
10056 "%s crumb %d of %s (decoded above)",
10057 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
10060 crumb_spec[crumb_index].crumb_bit_length,
10067 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10068 const guint bit_offset, const gint no_of_bits,
10069 guint64 *return_value, const guint encoding)
10073 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
10074 bit_offset, no_of_bits,
10075 return_value, encoding))) {
10076 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
10077 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
10082 static proto_item *
10083 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
10084 tvbuff_t *tvb, const guint bit_offset,
10085 const gint no_of_bits, void *value_ptr,
10090 guint8 tot_no_bits;
10093 header_field_info *hf_field;
10095 /* We do not have to return a value, try to fake it as soon as possible */
10096 CHECK_FOR_NULL_TREE(tree);
10097 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10099 if (hf_field->bitmask != 0) {
10100 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10101 "Incompatible use of proto_tree_add_bits_format_value"
10102 " with field '%s' (%s) with bitmask != 0",
10103 hf_field->abbrev, hf_field->name));
10106 DISSECTOR_ASSERT(no_of_bits > 0);
10108 /* Byte align offset */
10109 offset = bit_offset>>3;
10112 * Calculate the number of octets used to hold the bits
10114 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
10115 length = tot_no_bits>>3;
10116 /* If we are using part of the next octet, increase length by 1 */
10117 if (tot_no_bits & 0x07)
10120 if (no_of_bits < 65) {
10121 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
10123 DISSECTOR_ASSERT_NOT_REACHED();
10127 str = decode_bits_in_field(bit_offset, no_of_bits, value);
10129 g_strlcat(str, " = ", 256+64);
10130 g_strlcat(str, hf_field->name, 256+64);
10133 * This function does not receive an actual value but a dimensionless pointer to that value.
10134 * For this reason, the type of the header field is examined in order to determine
10135 * what kind of value we should read from this address.
10136 * The caller of this function must make sure that for the specific header field type the address of
10137 * a compatible value is provided.
10139 switch (hf_field->type) {
10141 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
10142 "%s: %s", str, value_str);
10150 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
10151 "%s: %s", str, value_str);
10158 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
10159 "%s: %s", str, value_str);
10166 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
10167 "%s: %s", str, value_str);
10174 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
10175 "%s: %s", str, value_str);
10179 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
10180 "%s: %s", str, value_str);
10184 DISSECTOR_ASSERT_NOT_REACHED();
10190 static proto_item *
10191 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
10192 tvbuff_t *tvb, const guint bit_offset,
10193 const gint no_of_bits, void *value_ptr,
10198 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
10199 tvb, bit_offset, no_of_bits,
10200 value_ptr, value_str))) {
10201 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
10202 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
10207 #define CREATE_VALUE_STRING(dst,format,ap) \
10208 va_start(ap, format); \
10209 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
10213 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
10214 tvbuff_t *tvb, const guint bit_offset,
10215 const gint no_of_bits, guint32 value,
10216 const char *format, ...)
10220 header_field_info *hf_field;
10222 CHECK_FOR_NULL_TREE(tree);
10224 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10226 switch (hf_field->type) {
10234 DISSECTOR_ASSERT_NOT_REACHED();
10239 CREATE_VALUE_STRING(dst, format, ap);
10241 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10245 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
10246 tvbuff_t *tvb, const guint bit_offset,
10247 const gint no_of_bits, guint64 value,
10248 const char *format, ...)
10252 header_field_info *hf_field;
10254 CHECK_FOR_NULL_TREE(tree);
10256 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10258 switch (hf_field->type) {
10266 DISSECTOR_ASSERT_NOT_REACHED();
10271 CREATE_VALUE_STRING(dst, format, ap);
10273 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10277 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
10278 tvbuff_t *tvb, const guint bit_offset,
10279 const gint no_of_bits, float value,
10280 const char *format, ...)
10284 header_field_info *hf_field;
10286 CHECK_FOR_NULL_TREE(tree);
10288 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10290 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
10292 CREATE_VALUE_STRING(dst, format, ap);
10294 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10298 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
10299 tvbuff_t *tvb, const guint bit_offset,
10300 const gint no_of_bits, gint32 value,
10301 const char *format, ...)
10305 header_field_info *hf_field;
10307 CHECK_FOR_NULL_TREE(tree);
10309 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10311 switch (hf_field->type) {
10319 DISSECTOR_ASSERT_NOT_REACHED();
10324 CREATE_VALUE_STRING(dst, format, ap);
10326 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10330 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
10331 tvbuff_t *tvb, const guint bit_offset,
10332 const gint no_of_bits, gint64 value,
10333 const char *format, ...)
10337 header_field_info *hf_field;
10339 CHECK_FOR_NULL_TREE(tree);
10341 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10343 switch (hf_field->type) {
10351 DISSECTOR_ASSERT_NOT_REACHED();
10356 CREATE_VALUE_STRING(dst, format, ap);
10358 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10362 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
10363 tvbuff_t *tvb, const guint bit_offset,
10364 const gint no_of_bits, guint32 value,
10365 const char *format, ...)
10369 header_field_info *hf_field;
10371 CHECK_FOR_NULL_TREE(tree);
10373 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10375 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
10377 CREATE_VALUE_STRING(dst, format, ap);
10379 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10383 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
10384 tvbuff_t *tvb, const guint bit_offset,
10385 const gint no_of_bits, guint64 value,
10386 const char *format, ...)
10390 header_field_info *hf_field;
10392 CHECK_FOR_NULL_TREE(tree);
10394 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10396 DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
10398 CREATE_VALUE_STRING(dst, format, ap);
10400 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10404 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10405 const guint bit_offset, const gint no_of_chars)
10408 header_field_info *hfinfo;
10413 CHECK_FOR_NULL_TREE(tree);
10415 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10417 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
10419 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
10420 byte_offset = bit_offset >> 3;
10422 string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
10424 if (hfinfo->display == STR_UNICODE) {
10425 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
10428 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
10429 DISSECTOR_ASSERT(byte_length >= 0);
10430 proto_tree_set_string(PNODE_FINFO(pi), string);
10436 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10437 const guint bit_offset, const gint no_of_chars)
10440 header_field_info *hfinfo;
10445 CHECK_FOR_NULL_TREE(tree);
10447 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10449 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
10451 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
10452 byte_offset = bit_offset >> 3;
10454 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
10456 if (hfinfo->display == STR_UNICODE) {
10457 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
10460 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
10461 DISSECTOR_ASSERT(byte_length >= 0);
10462 proto_tree_set_string(PNODE_FINFO(pi), string);
10467 const value_string proto_checksum_vals[] = {
10468 { PROTO_CHECKSUM_E_BAD, "Bad" },
10469 { PROTO_CHECKSUM_E_GOOD, "Good" },
10470 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
10471 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
10477 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
10478 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
10479 packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
10481 header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
10484 proto_item* ti = NULL;
10486 gboolean incorrect_checksum = TRUE;
10488 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
10490 if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
10491 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, 0, 0, "[missing]");
10492 PROTO_ITEM_SET_GENERATED(ti);
10493 if (hf_checksum_status != -1) {
10494 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_NOT_PRESENT);
10495 PROTO_ITEM_SET_GENERATED(ti2);
10500 switch (hfinfo->type){
10514 DISSECTOR_ASSERT_NOT_REACHED();
10517 if (flags & PROTO_CHECKSUM_GENERATED) {
10518 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, 0, computed_checksum);
10519 PROTO_ITEM_SET_GENERATED(ti);
10521 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
10522 if (flags & PROTO_CHECKSUM_VERIFY) {
10523 if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
10524 if (computed_checksum == 0) {
10525 proto_item_append_text(ti, " [correct]");
10526 if (hf_checksum_status != -1) {
10527 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
10528 PROTO_ITEM_SET_GENERATED(ti2);
10530 incorrect_checksum = FALSE;
10531 } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
10532 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
10535 if (checksum == computed_checksum) {
10536 proto_item_append_text(ti, " [correct]");
10537 if (hf_checksum_status != -1) {
10538 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
10539 PROTO_ITEM_SET_GENERATED(ti2);
10541 incorrect_checksum = FALSE;
10545 if (incorrect_checksum) {
10546 if (hf_checksum_status != -1) {
10547 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
10548 PROTO_ITEM_SET_GENERATED(ti2);
10550 if (flags & PROTO_CHECKSUM_ZERO) {
10551 proto_item_append_text(ti, " [incorrect]");
10552 if (bad_checksum_expert != NULL)
10553 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum");
10555 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
10556 if (bad_checksum_expert != NULL)
10557 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum [should be 0x%0*x]", len*2, computed_checksum);
10561 if (hf_checksum_status != -1) {
10562 proto_item_append_text(ti, " [unverified]");
10563 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
10564 PROTO_ITEM_SET_GENERATED(ti2);
10573 proto_check_field_name(const gchar *field_name)
10575 return wrs_check_charset(fld_abbrev_chars, field_name);
10579 tree_expanded(int tree_type)
10581 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10582 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
10586 tree_expanded_set(int tree_type, gboolean value)
10588 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10591 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
10593 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
10597 * Editor modelines - http://www.wireshark.org/tools/modelines.html
10600 * c-basic-offset: 8
10602 * indent-tabs-mode: t
10605 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
10606 * :indentSize=8:tabSize=8:noTabs=false: