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_prepend(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 if (hfinfo->bitmask) {
2331 /* Mask out irrelevant portions */
2332 *retval &= (guint32)(hfinfo->bitmask);
2334 *retval >>= hfinfo_bitshift(hfinfo);
2336 no_of_bits = ws_count_ones(hfinfo->bitmask);
2337 *retval = ws_sign_ext32(*retval, no_of_bits);
2340 CHECK_FOR_NULL_TREE(tree);
2342 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2344 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2346 proto_tree_set_int(new_fi, value);
2348 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2350 return proto_tree_add_node(tree, new_fi);
2354 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2355 const gint start, gint length,
2356 const guint encoding, guint32 *retval)
2358 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2362 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2364 switch (hfinfo->type){
2372 DISSECTOR_ASSERT_NOT_REACHED();
2375 /* length validation for native number encoding caught by get_uint_value() */
2376 /* length has to be -1 or > 0 regardless of encoding */
2377 if (length < -1 || length == 0)
2378 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2379 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2382 if (encoding & ENC_STRING) {
2383 REPORT_DISSECTOR_BUG("wrong encoding");
2385 /* I believe it's ok if this is called with a NULL tree */
2386 /* XXX - modify if we ever support EBCDIC FT_CHAR */
2387 value = get_uint_value(tree, tvb, start, length, encoding);
2391 if (hfinfo->bitmask) {
2392 /* Mask out irrelevant portions */
2393 *retval &= (guint32)(hfinfo->bitmask);
2395 *retval >>= hfinfo_bitshift(hfinfo);
2399 CHECK_FOR_NULL_TREE(tree);
2401 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2403 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2405 proto_tree_set_uint(new_fi, value);
2407 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2409 return proto_tree_add_node(tree, new_fi);
2413 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
2415 const gint start, gint length,
2416 const guint encoding,
2417 wmem_allocator_t *scope,
2418 const guint8 **retval,
2421 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2423 const guint8 *value;
2425 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2427 switch (hfinfo->type){
2429 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
2432 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
2434 case FT_UINT_STRING:
2435 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
2438 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
2441 DISSECTOR_ASSERT_NOT_REACHED();
2447 CHECK_FOR_NULL_TREE(tree);
2449 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2451 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
2453 proto_tree_set_string(new_fi, value);
2455 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2457 return proto_tree_add_node(tree, new_fi);
2461 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2462 const gint start, gint length,
2463 const guint encoding, wmem_allocator_t *scope,
2464 const guint8 **retval)
2466 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
2467 tvb, start, length, encoding, scope, retval, &length);
2471 * Validates that field length bytes are available starting from
2472 * start (pos/neg). Throws an exception if they aren't.
2475 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2476 gint start, gint length)
2483 if (hfinfo->type == FT_STRINGZ) {
2484 /* If we're fetching until the end of the TVB, only validate
2485 * that the offset is within range.
2491 tvb_ensure_bytes_exist(tvb, start, size);
2494 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2495 and returns proto_item* */
2497 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
2498 const guint encoding)
2501 header_field_info *hfinfo;
2505 offset = ptvc->offset;
2506 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2507 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
2508 test_length(hfinfo, ptvc->tvb, offset, item_length);
2510 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2511 item_length, encoding);
2513 CHECK_FOR_NULL_TREE(ptvc->tree);
2515 /* Coast clear. Try and fake it */
2516 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2518 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2520 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2521 offset, length, encoding);
2524 /* Add an item to a proto_tree, using the text label registered to that item;
2525 the item is extracted from the tvbuff handed to it. */
2527 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
2528 const gint start, gint length, const guint encoding)
2533 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2535 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2536 test_length(hfinfo, tvb, start, item_length);
2538 CHECK_FOR_NULL_TREE(tree);
2540 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2542 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2544 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2548 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2549 const gint start, gint length, const guint encoding)
2551 register header_field_info *hfinfo;
2553 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2554 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
2557 /* Add an item to a proto_tree, using the text label registered to that item;
2558 the item is extracted from the tvbuff handed to it.
2560 Return the length of the item through the pointer. */
2562 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
2563 tvbuff_t *tvb, const gint start,
2564 gint length, const guint encoding,
2571 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2573 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2574 test_length(hfinfo, tvb, start, item_length);
2578 * We need to get the correct item length here.
2579 * That's normally done by proto_tree_new_item(),
2580 * but we won't be calling it.
2582 *lenretval = get_full_length(hfinfo, tvb, start, length,
2583 item_length, encoding);
2587 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2589 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2591 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2592 *lenretval = new_fi->length;
2597 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2598 const gint start, gint length,
2599 const guint encoding, gint *lenretval)
2601 register header_field_info *hfinfo;
2603 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2604 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
2607 /* which FT_ types can use proto_tree_add_bytes_item() */
2608 static inline gboolean
2609 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
2611 return (type == FT_BYTES ||
2612 type == FT_UINT_BYTES ||
2614 type == FT_REL_OID ||
2615 type == FT_SYSTEM_ID );
2618 /* Note: this does no validation that the byte array of an FT_OID or
2619 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
2620 so I think it's ok to continue not validating it?
2623 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2624 const gint start, gint length, const guint encoding,
2625 GByteArray *retval, gint *endoff, gint *err)
2628 GByteArray *bytes = retval;
2629 GByteArray *created_bytes = NULL;
2632 header_field_info *hfinfo;
2633 gboolean generate = (bytes || tree) ? TRUE : FALSE;
2635 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2637 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2639 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
2640 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
2642 /* length has to be -1 or > 0 regardless of encoding */
2643 /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
2644 if (length < -1 || length == 0) {
2645 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2646 "Invalid length %d passed to proto_tree_add_bytes_item for %s",
2647 length, ftype_name(hfinfo->type)));
2650 if (encoding & ENC_STR_NUM) {
2651 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
2654 if (generate && (encoding & ENC_STR_HEX)) {
2655 if (hfinfo->type == FT_UINT_BYTES) {
2656 /* can't decode FT_UINT_BYTES from strings */
2657 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
2658 "FT_UINT_BYTES type, but as ENC_STR_HEX");
2662 /* caller doesn't care about return value, but we need it to
2663 call tvb_get_string_bytes() and set the tree later */
2664 bytes = created_bytes = g_byte_array_new();
2667 /* bytes might be NULL after this, but can't add expert error until later */
2668 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
2670 /* grab the errno now before it gets overwritten */
2673 else if (generate) {
2674 tvb_ensure_bytes_exist(tvb, start, length);
2677 /* caller doesn't care about return value, but we need it to
2678 call tvb_get_string_bytes() and set the tree later */
2679 bytes = created_bytes = g_byte_array_new();
2682 if (hfinfo->type == FT_UINT_BYTES) {
2683 n = length; /* n is now the "header" length */
2684 length = get_uint_value(tree, tvb, start, n, encoding);
2685 /* length is now the value's length; only store the value in the array */
2686 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
2688 else if (length > 0) {
2689 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
2693 *endoff = start + n + length;
2696 if (err) *err = saved_err;
2698 CHECK_FOR_NULL_TREE_AND_FREE(tree,
2701 g_byte_array_free(created_bytes, TRUE);
2702 created_bytes = NULL;
2706 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
2709 g_byte_array_free(created_bytes, TRUE);
2710 created_bytes = NULL;
2714 /* n will be zero except when it's a FT_UINT_BYTES */
2715 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
2717 if (encoding & ENC_STRING) {
2718 if (saved_err == ERANGE)
2719 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2720 else if (!bytes || saved_err != 0)
2721 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2724 proto_tree_set_bytes_gbytearray(new_fi, bytes);
2726 proto_tree_set_bytes(new_fi, NULL, 0);
2729 g_byte_array_free(created_bytes, TRUE);
2732 /* n will be zero except when it's a FT_UINT_BYTES */
2733 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
2736 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2739 return proto_tree_add_node(tree, new_fi);
2744 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2745 const gint start, gint length, const guint encoding,
2746 nstime_t *retval, gint *endoff, gint *err)
2749 nstime_t time_stamp;
2751 header_field_info *hfinfo;
2753 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2755 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2757 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
2759 /* length has to be -1 or > 0 regardless of encoding */
2760 if (length < -1 || length == 0) {
2761 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2762 "Invalid length %d passed to proto_tree_add_time_item", length));
2765 time_stamp.secs = 0;
2766 time_stamp.nsecs = 0;
2768 if (encoding & ENC_STR_TIME_MASK) {
2769 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
2770 /* grab the errno now before it gets overwritten */
2774 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
2776 if (length != 8 && length != 4) {
2777 const gboolean length_error = length < 4 ? TRUE : FALSE;
2779 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2781 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2784 tvb_ensure_bytes_exist(tvb, start, length);
2785 get_time_value(tvb, start, length, encoding, &time_stamp, is_relative);
2786 if (endoff) *endoff = length;
2789 if (err) *err = saved_err;
2792 retval->secs = time_stamp.secs;
2793 retval->nsecs = time_stamp.nsecs;
2796 CHECK_FOR_NULL_TREE(tree);
2798 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2800 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2802 proto_tree_set_time(new_fi, &time_stamp);
2804 if (encoding & ENC_STRING) {
2805 if (saved_err == ERANGE)
2806 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2807 else if (saved_err == EDOM)
2808 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2812 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2815 return proto_tree_add_node(tree, new_fi);
2818 /* Add a FT_NONE to a proto_tree */
2820 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
2821 const gint start, gint length, const char *format,
2826 header_field_info *hfinfo;
2828 CHECK_FOR_NULL_TREE(tree);
2830 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2832 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
2834 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2836 TRY_TO_FAKE_THIS_REPR(pi);
2838 va_start(ap, format);
2839 proto_tree_set_representation(pi, format, ap);
2842 /* no value to set for FT_NONE */
2846 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
2847 * offset, and returns proto_item* */
2849 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
2850 const guint encoding)
2854 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
2860 /* Advance the ptvcursor's offset within its tvbuff without
2861 * adding anything to the proto_tree. */
2863 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
2865 ptvc->offset += length;
2870 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
2872 fvalue_set_protocol(&fi->value, tvb, field_data);
2875 /* Add a FT_PROTOCOL to a proto_tree */
2877 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2878 gint start, gint length, const char *format, ...)
2882 header_field_info *hfinfo;
2883 gchar* protocol_rep;
2885 CHECK_FOR_NULL_TREE(tree);
2887 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2889 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
2891 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2893 va_start(ap, format);
2894 protocol_rep = g_strdup_vprintf(format, ap);
2895 proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length)), protocol_rep);
2896 g_free(protocol_rep);
2899 TRY_TO_FAKE_THIS_REPR(pi);
2901 va_start(ap, format);
2902 proto_tree_set_representation(pi, format, ap);
2908 /* Add a FT_BYTES to a proto_tree */
2910 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2911 gint length, const guint8 *start_ptr)
2914 header_field_info *hfinfo;
2917 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2918 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2919 test_length(hfinfo, tvb, start, item_length);
2921 CHECK_FOR_NULL_TREE(tree);
2923 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2925 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2927 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2928 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
2933 /* Add a FT_BYTES to a proto_tree */
2935 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2936 gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
2939 header_field_info *hfinfo;
2942 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2943 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length);
2944 test_length(hfinfo, tvb, start, item_length);
2946 CHECK_FOR_NULL_TREE(tree);
2948 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2950 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2952 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
2953 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
2959 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2960 gint start, gint length,
2961 const guint8 *start_ptr,
2962 const char *format, ...)
2966 header_field_info *hfinfo;
2969 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2970 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2971 test_length(hfinfo, tvb, start, item_length);
2973 CHECK_FOR_NULL_TREE(tree);
2975 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2978 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2981 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2982 tvb_get_ptr(tvb, start, length));
2984 va_start(ap, format);
2985 proto_tree_set_representation_value(pi, format, ap);
2992 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2993 gint start, gint length, const guint8 *start_ptr,
2994 const char *format, ...)
2998 header_field_info *hfinfo;
3001 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3002 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
3003 test_length(hfinfo, tvb, start, item_length);
3005 CHECK_FOR_NULL_TREE(tree);
3007 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3010 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
3013 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
3014 tvb_get_ptr(tvb, start, length));
3016 TRY_TO_FAKE_THIS_REPR(pi);
3018 va_start(ap, format);
3019 proto_tree_set_representation(pi, format, ap);
3026 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
3030 DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
3032 bytes = g_byte_array_new();
3034 g_byte_array_append(bytes, start_ptr, length);
3036 fvalue_set_byte_array(&fi->value, bytes);
3041 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
3043 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
3047 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
3051 DISSECTOR_ASSERT(value != NULL);
3053 bytes = byte_array_dup(value);
3055 fvalue_set_byte_array(&fi->value, bytes);
3058 /* Add a FT_*TIME to a proto_tree */
3060 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3061 gint length, const nstime_t *value_ptr)
3064 header_field_info *hfinfo;
3066 CHECK_FOR_NULL_TREE(tree);
3068 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3070 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3072 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3073 proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
3079 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3080 gint start, gint length, nstime_t *value_ptr,
3081 const char *format, ...)
3086 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3088 va_start(ap, format);
3089 proto_tree_set_representation_value(pi, format, ap);
3097 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3098 gint start, gint length, nstime_t *value_ptr,
3099 const char *format, ...)
3104 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3106 TRY_TO_FAKE_THIS_REPR(pi);
3108 va_start(ap, format);
3109 proto_tree_set_representation(pi, format, ap);
3116 /* Set the FT_*TIME value */
3118 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
3120 DISSECTOR_ASSERT(value_ptr != NULL);
3122 fvalue_set_time(&fi->value, value_ptr);
3125 /* Add a FT_IPXNET to a proto_tree */
3127 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3128 gint length, guint32 value)
3131 header_field_info *hfinfo;
3133 CHECK_FOR_NULL_TREE(tree);
3135 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3137 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
3139 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3140 proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
3146 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3147 gint start, gint length, guint32 value,
3148 const char *format, ...)
3153 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3155 va_start(ap, format);
3156 proto_tree_set_representation_value(pi, format, ap);
3164 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3165 gint start, gint length, guint32 value,
3166 const char *format, ...)
3171 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3173 TRY_TO_FAKE_THIS_REPR(pi);
3175 va_start(ap, format);
3176 proto_tree_set_representation(pi, format, ap);
3183 /* Set the FT_IPXNET value */
3185 proto_tree_set_ipxnet(field_info *fi, guint32 value)
3187 fvalue_set_uinteger(&fi->value, value);
3190 /* Add a FT_IPv4 to a proto_tree */
3192 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3193 gint length, guint32 value)
3196 header_field_info *hfinfo;
3198 CHECK_FOR_NULL_TREE(tree);
3200 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3202 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
3204 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3205 proto_tree_set_ipv4(PNODE_FINFO(pi), value);
3211 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3212 gint start, gint length, guint32 value,
3213 const char *format, ...)
3218 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3220 va_start(ap, format);
3221 proto_tree_set_representation_value(pi, format, ap);
3229 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3230 gint start, gint length, guint32 value,
3231 const char *format, ...)
3236 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3238 TRY_TO_FAKE_THIS_REPR(pi);
3240 va_start(ap, format);
3241 proto_tree_set_representation(pi, format, ap);
3248 /* Set the FT_IPv4 value */
3250 proto_tree_set_ipv4(field_info *fi, guint32 value)
3252 fvalue_set_uinteger(&fi->value, value);
3255 /* Add a FT_IPv6 to a proto_tree */
3257 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3258 gint length, const struct e_in6_addr *value_ptr)
3261 header_field_info *hfinfo;
3263 CHECK_FOR_NULL_TREE(tree);
3265 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3267 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
3269 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3270 proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
3276 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3277 gint start, gint length,
3278 const struct e_in6_addr *value_ptr,
3279 const char *format, ...)
3284 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3286 va_start(ap, format);
3287 proto_tree_set_representation_value(pi, format, ap);
3295 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3296 gint start, gint length,
3297 const struct e_in6_addr *value_ptr,
3298 const char *format, ...)
3303 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3305 TRY_TO_FAKE_THIS_REPR(pi);
3307 va_start(ap, format);
3308 proto_tree_set_representation(pi, format, ap);
3315 /* Set the FT_IPv6 value */
3317 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
3319 DISSECTOR_ASSERT(value_ptr != NULL);
3320 fvalue_set_bytes(&fi->value, value_ptr);
3324 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3326 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
3329 /* Set the FT_FCWWN value */
3331 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
3333 DISSECTOR_ASSERT(value_ptr != NULL);
3334 fvalue_set_bytes(&fi->value, value_ptr);
3338 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3340 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
3343 /* Add a FT_GUID to a proto_tree */
3345 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3346 gint length, const e_guid_t *value_ptr)
3349 header_field_info *hfinfo;
3351 CHECK_FOR_NULL_TREE(tree);
3353 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3355 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
3357 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3358 proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
3364 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3365 gint start, gint length,
3366 const e_guid_t *value_ptr,
3367 const char *format, ...)
3372 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3374 va_start(ap, format);
3375 proto_tree_set_representation_value(pi, format, ap);
3383 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3384 gint start, gint length, const e_guid_t *value_ptr,
3385 const char *format, ...)
3390 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3392 TRY_TO_FAKE_THIS_REPR(pi);
3394 va_start(ap, format);
3395 proto_tree_set_representation(pi, format, ap);
3402 /* Set the FT_GUID value */
3404 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
3406 DISSECTOR_ASSERT(value_ptr != NULL);
3407 fvalue_set_guid(&fi->value, value_ptr);
3411 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
3412 const guint encoding)
3416 tvb_get_guid(tvb, start, &guid, encoding);
3417 proto_tree_set_guid(fi, &guid);
3420 /* Add a FT_OID to a proto_tree */
3422 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3423 gint length, const guint8* value_ptr)
3426 header_field_info *hfinfo;
3428 CHECK_FOR_NULL_TREE(tree);
3430 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3432 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
3434 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3435 proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
3441 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3442 gint start, gint length,
3443 const guint8* value_ptr,
3444 const char *format, ...)
3449 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3451 va_start(ap, format);
3452 proto_tree_set_representation_value(pi, format, ap);
3460 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3461 gint start, gint length, const guint8* value_ptr,
3462 const char *format, ...)
3467 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3469 TRY_TO_FAKE_THIS_REPR(pi);
3471 va_start(ap, format);
3472 proto_tree_set_representation(pi, format, ap);
3479 /* Set the FT_OID value */
3481 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
3485 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3487 bytes = g_byte_array_new();
3489 g_byte_array_append(bytes, value_ptr, length);
3491 fvalue_set_byte_array(&fi->value, bytes);
3495 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3497 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
3500 /* Set the FT_SYSTEM_ID value */
3502 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
3506 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3508 bytes = g_byte_array_new();
3510 g_byte_array_append(bytes, value_ptr, length);
3512 fvalue_set_byte_array(&fi->value, bytes);
3516 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3518 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
3521 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
3522 * own copy of string, and frees it when the proto_tree is destroyed. */
3524 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3525 gint length, const char* value)
3528 header_field_info *hfinfo;
3530 CHECK_FOR_NULL_TREE(tree);
3532 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3534 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
3536 if (hfinfo->display == STR_UNICODE) {
3537 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
3540 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3541 DISSECTOR_ASSERT(length >= 0);
3542 proto_tree_set_string(PNODE_FINFO(pi), value);
3548 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3549 gint start, gint length, const char* value,
3556 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3558 va_start(ap, format);
3559 proto_tree_set_representation_value(pi, format, ap);
3567 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3568 gint start, gint length, const char* value,
3569 const char *format, ...)
3574 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3576 TRY_TO_FAKE_THIS_REPR(pi);
3578 va_start(ap, format);
3579 proto_tree_set_representation(pi, format, ap);
3586 /* Set the FT_STRING value */
3588 proto_tree_set_string(field_info *fi, const char* value)
3591 fvalue_set_string(&fi->value, value);
3593 fvalue_set_string(&fi->value, "[ Null ]");
3597 /* Set the FT_AX25 value */
3599 proto_tree_set_ax25(field_info *fi, const guint8* value)
3601 fvalue_set_bytes(&fi->value, value);
3605 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3607 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
3610 /* Set the FT_VINES value */
3612 proto_tree_set_vines(field_info *fi, const guint8* value)
3614 fvalue_set_bytes(&fi->value, value);
3618 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3620 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
3623 /* Add a FT_ETHER to a proto_tree */
3625 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3626 gint length, const guint8* value)
3629 header_field_info *hfinfo;
3631 CHECK_FOR_NULL_TREE(tree);
3633 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3635 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
3637 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3638 proto_tree_set_ether(PNODE_FINFO(pi), value);
3644 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3645 gint start, gint length, const guint8* value,
3646 const char *format, ...)
3651 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3653 va_start(ap, format);
3654 proto_tree_set_representation_value(pi, format, ap);
3662 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3663 gint start, gint length, const guint8* value,
3664 const char *format, ...)
3669 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3671 TRY_TO_FAKE_THIS_REPR(pi);
3673 va_start(ap, format);
3674 proto_tree_set_representation(pi, format, ap);
3681 /* Set the FT_ETHER value */
3683 proto_tree_set_ether(field_info *fi, const guint8* value)
3685 fvalue_set_bytes(&fi->value, value);
3689 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3691 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
3694 /* Add a FT_BOOLEAN to a proto_tree */
3696 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3697 gint length, guint32 value)
3700 header_field_info *hfinfo;
3702 CHECK_FOR_NULL_TREE(tree);
3704 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3706 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3708 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3709 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3715 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
3716 tvbuff_t *tvb, gint start, gint length,
3717 guint32 value, const char *format, ...)
3722 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3724 va_start(ap, format);
3725 proto_tree_set_representation_value(pi, format, ap);
3733 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3734 gint start, gint length, guint32 value,
3735 const char *format, ...)
3740 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3742 TRY_TO_FAKE_THIS_REPR(pi);
3744 va_start(ap, format);
3745 proto_tree_set_representation(pi, format, ap);
3753 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3754 gint length, guint64 value)
3757 header_field_info *hfinfo;
3759 CHECK_FOR_NULL_TREE(tree);
3761 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3763 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3765 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3766 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3771 /* Set the FT_BOOLEAN value */
3773 proto_tree_set_boolean(field_info *fi, guint64 value)
3775 proto_tree_set_uint64(fi, value);
3778 /* Generate, into "buf", a string showing the bits of a bitfield.
3779 Return a pointer to the character after that string. */
3780 /*XXX this needs a buf_len check */
3782 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3790 bit = G_GUINT64_CONSTANT(1) << (width - 1);
3793 /* This bit is part of the field. Show its value. */
3799 /* This bit is not part of the field. */
3814 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3818 p = other_decode_bitfield_value(buf, val, mask, width);
3819 p = g_stpcpy(p, " = ");
3824 /* Add a FT_FLOAT to a proto_tree */
3826 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3827 gint length, float value)
3830 header_field_info *hfinfo;
3832 CHECK_FOR_NULL_TREE(tree);
3834 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3836 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
3838 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3839 proto_tree_set_float(PNODE_FINFO(pi), value);
3845 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3846 gint start, gint length, float value,
3847 const char *format, ...)
3852 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3854 va_start(ap, format);
3855 proto_tree_set_representation_value(pi, format, ap);
3863 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3864 gint start, gint length, float value,
3865 const char *format, ...)
3870 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3872 TRY_TO_FAKE_THIS_REPR(pi);
3874 va_start(ap, format);
3875 proto_tree_set_representation(pi, format, ap);
3882 /* Set the FT_FLOAT value */
3884 proto_tree_set_float(field_info *fi, float value)
3886 fvalue_set_floating(&fi->value, value);
3889 /* Add a FT_DOUBLE to a proto_tree */
3891 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3892 gint length, double value)
3895 header_field_info *hfinfo;
3897 CHECK_FOR_NULL_TREE(tree);
3899 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3901 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
3903 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3904 proto_tree_set_double(PNODE_FINFO(pi), value);
3910 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3911 gint start, gint length, double value,
3912 const char *format, ...)
3917 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3919 va_start(ap, format);
3920 proto_tree_set_representation_value(pi, format, ap);
3928 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3929 gint start, gint length, double value,
3930 const char *format, ...)
3935 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3937 TRY_TO_FAKE_THIS_REPR(pi);
3939 va_start(ap, format);
3940 proto_tree_set_representation(pi, format, ap);
3947 /* Set the FT_DOUBLE value */
3949 proto_tree_set_double(field_info *fi, double value)
3951 fvalue_set_floating(&fi->value, value);
3954 /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
3956 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3957 gint length, guint32 value)
3959 proto_item *pi = NULL;
3960 header_field_info *hfinfo;
3962 CHECK_FOR_NULL_TREE(tree);
3964 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3966 switch (hfinfo->type) {
3973 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3974 proto_tree_set_uint(PNODE_FINFO(pi), value);
3978 DISSECTOR_ASSERT_NOT_REACHED();
3985 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3986 gint start, gint length, guint32 value,
3987 const char *format, ...)
3992 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3994 va_start(ap, format);
3995 proto_tree_set_representation_value(pi, format, ap);
4003 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4004 gint start, gint length, guint32 value,
4005 const char *format, ...)
4010 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
4012 TRY_TO_FAKE_THIS_REPR(pi);
4014 va_start(ap, format);
4015 proto_tree_set_representation(pi, format, ap);
4022 /* Set the FT_UINT{8,16,24,32} value */
4024 proto_tree_set_uint(field_info *fi, guint32 value)
4026 header_field_info *hfinfo;
4029 hfinfo = fi->hfinfo;
4032 if (hfinfo->bitmask) {
4033 /* Mask out irrelevant portions */
4034 integer &= (guint32)(hfinfo->bitmask);
4037 integer >>= hfinfo_bitshift(hfinfo);
4040 fvalue_set_uinteger(&fi->value, integer);
4043 /* Add FT_UINT{40,48,56,64} to a proto_tree */
4045 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4046 gint length, guint64 value)
4048 proto_item *pi = NULL;
4049 header_field_info *hfinfo;
4051 CHECK_FOR_NULL_TREE(tree);
4053 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4055 switch (hfinfo->type) {
4061 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4062 proto_tree_set_uint64(PNODE_FINFO(pi), value);
4066 DISSECTOR_ASSERT_NOT_REACHED();
4073 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4074 gint start, gint length, guint64 value,
4075 const char *format, ...)
4080 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4082 va_start(ap, format);
4083 proto_tree_set_representation_value(pi, format, ap);
4091 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4092 gint start, gint length, guint64 value,
4093 const char *format, ...)
4098 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4100 TRY_TO_FAKE_THIS_REPR(pi);
4102 va_start(ap, format);
4103 proto_tree_set_representation(pi, format, ap);
4110 /* Set the FT_UINT{40,48,56,64} value */
4112 proto_tree_set_uint64(field_info *fi, guint64 value)
4114 header_field_info *hfinfo;
4117 hfinfo = fi->hfinfo;
4120 if (hfinfo->bitmask) {
4121 /* Mask out irrelevant portions */
4122 integer &= hfinfo->bitmask;
4125 integer >>= hfinfo_bitshift(hfinfo);
4128 fvalue_set_uinteger64(&fi->value, integer);
4131 /* Add FT_INT{8,16,24,32} to a proto_tree */
4133 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4134 gint length, gint32 value)
4136 proto_item *pi = NULL;
4137 header_field_info *hfinfo;
4139 CHECK_FOR_NULL_TREE(tree);
4141 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4143 switch (hfinfo->type) {
4148 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4149 proto_tree_set_int(PNODE_FINFO(pi), value);
4153 DISSECTOR_ASSERT_NOT_REACHED();
4160 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4161 gint start, gint length, gint32 value,
4162 const char *format, ...)
4167 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4169 va_start(ap, format);
4170 proto_tree_set_representation_value(pi, format, ap);
4178 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4179 gint start, gint length, gint32 value,
4180 const char *format, ...)
4185 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4187 TRY_TO_FAKE_THIS_REPR(pi);
4189 va_start(ap, format);
4190 proto_tree_set_representation(pi, format, ap);
4197 /* Set the FT_INT{8,16,24,32} value */
4199 proto_tree_set_int(field_info *fi, gint32 value)
4201 header_field_info *hfinfo;
4205 hfinfo = fi->hfinfo;
4206 integer = (guint32) value;
4208 if (hfinfo->bitmask) {
4209 /* Mask out irrelevant portions */
4210 integer &= (guint32)(hfinfo->bitmask);
4213 integer >>= hfinfo_bitshift(hfinfo);
4215 no_of_bits = ws_count_ones(hfinfo->bitmask);
4216 integer = ws_sign_ext32(integer, no_of_bits);
4219 fvalue_set_sinteger(&fi->value, integer);
4222 /* Add FT_INT{40,48,56,64} to a proto_tree */
4224 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4225 gint length, gint64 value)
4227 proto_item *pi = NULL;
4228 header_field_info *hfinfo;
4230 CHECK_FOR_NULL_TREE(tree);
4232 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4234 switch (hfinfo->type) {
4239 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4240 proto_tree_set_int64(PNODE_FINFO(pi), value);
4244 DISSECTOR_ASSERT_NOT_REACHED();
4251 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4252 gint start, gint length, gint64 value,
4253 const char *format, ...)
4258 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4260 va_start(ap, format);
4261 proto_tree_set_representation_value(pi, format, ap);
4268 /* Set the FT_INT{40,48,56,64} value */
4270 proto_tree_set_int64(field_info *fi, gint64 value)
4272 header_field_info *hfinfo;
4276 hfinfo = fi->hfinfo;
4279 if (hfinfo->bitmask) {
4280 /* Mask out irrelevant portions */
4281 integer &= hfinfo->bitmask;
4284 integer >>= hfinfo_bitshift(hfinfo);
4286 no_of_bits = ws_count_ones(hfinfo->bitmask);
4287 integer = ws_sign_ext64(integer, no_of_bits);
4290 fvalue_set_sinteger64(&fi->value, integer);
4294 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4295 gint start, gint length, gint64 value,
4296 const char *format, ...)
4301 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4303 TRY_TO_FAKE_THIS_REPR(pi);
4305 va_start(ap, format);
4306 proto_tree_set_representation(pi, format, ap);
4313 /* Add a FT_EUI64 to a proto_tree */
4315 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4316 gint length, const guint64 value)
4319 header_field_info *hfinfo;
4321 CHECK_FOR_NULL_TREE(tree);
4323 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4325 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
4327 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4328 proto_tree_set_eui64(PNODE_FINFO(pi), value);
4334 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4335 gint start, gint length, const guint64 value,
4336 const char *format, ...)
4341 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4343 va_start(ap, format);
4344 proto_tree_set_representation_value(pi, format, ap);
4352 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4353 gint start, gint length, const guint64 value,
4354 const char *format, ...)
4359 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4361 TRY_TO_FAKE_THIS_REPR(pi);
4363 va_start(ap, format);
4364 proto_tree_set_representation(pi, format, ap);
4371 /* Set the FT_EUI64 value */
4373 proto_tree_set_eui64(field_info *fi, const guint64 value)
4375 fvalue_set_uinteger64(&fi->value, value);
4378 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
4382 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
4384 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
4388 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
4390 proto_tree_add_node(proto_tree *tree, field_info *fi)
4392 proto_node *pnode, *tnode, *sibling;
4397 * Restrict our depth. proto_tree_traverse_pre_order and
4398 * proto_tree_traverse_post_order (and possibly others) are recursive
4399 * so we need to be mindful of our stack size.
4401 if (tree->first_child == NULL) {
4402 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
4404 if (G_UNLIKELY(depth > MAX_TREE_LEVELS)) {
4405 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
4406 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u)",
4408 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
4414 * Make sure "tree" is ready to have subtrees under it, by
4415 * checking whether it's been given an ett_ value.
4417 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
4418 * node of the protocol tree. That node is not displayed,
4419 * so it doesn't need an ett_ value to remember whether it
4423 tfi = PNODE_FINFO(tnode);
4424 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
4425 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4426 "\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
4427 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
4428 /* XXX - is it safe to continue here? */
4431 pnode = wmem_new(PNODE_POOL(tree), proto_node);
4432 PROTO_NODE_INIT(pnode);
4433 pnode->parent = tnode;
4434 PNODE_FINFO(pnode) = fi;
4435 pnode->tree_data = PTREE_DATA(tree);
4437 if (tnode->last_child != NULL) {
4438 sibling = tnode->last_child;
4439 DISSECTOR_ASSERT(sibling->next == NULL);
4440 sibling->next = pnode;
4442 tnode->first_child = pnode;
4443 tnode->last_child = pnode;
4445 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
4447 return (proto_item *)pnode;
4451 /* Generic way to allocate field_info and add to proto_tree.
4452 * Sets *pfi to address of newly-allocated field_info struct */
4454 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
4461 get_hfi_length(hfinfo, tvb, start, length, &item_length);
4462 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4463 pi = proto_tree_add_node(tree, fi);
4470 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
4473 gint length_remaining;
4476 * We only allow a null tvbuff if the item has a zero length,
4477 * i.e. if there's no data backing it.
4479 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
4482 * XXX - in some protocols, there are 32-bit unsigned length
4483 * fields, so lengths in protocol tree and tvbuff routines
4484 * should really be unsigned. We should have, for those
4485 * field types for which "to the end of the tvbuff" makes sense,
4486 * additional routines that take no length argument and
4487 * add fields that run to the end of the tvbuff.
4489 if (*length == -1) {
4491 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
4492 * FT_STRINGZPAD fields, a length of -1 means "set the
4493 * length to what remains in the tvbuff".
4495 * The assumption is either that
4497 * 1) the length of the item can only be determined
4498 * by dissection (typically true of items with
4499 * subitems, which are probably FT_NONE or
4504 * 2) if the tvbuff is "short" (either due to a short
4505 * snapshot length or due to lack of reassembly of
4506 * fragments/segments/whatever), we want to display
4507 * what's available in the field (probably FT_BYTES
4508 * or FT_STRING) and then throw an exception later
4512 * 3) the field is defined to be "what's left in the
4515 * so we set the length to what remains in the tvbuff so
4516 * that, if we throw an exception while dissecting, it
4517 * has what is probably the right value.
4519 * For FT_STRINGZ, it means "the string is null-terminated,
4520 * not null-padded; set the length to the actual length
4521 * of the string", and if the tvbuff if short, we just
4522 * throw an exception.
4524 * It's not valid for any other type of field. For those
4525 * fields, we treat -1 the same way we treat other
4526 * negative values - we assume the length is a Really
4527 * Big Positive Number, and throw a ReportedBoundsError
4528 * exception, under the assumption that the Really Big
4529 * Length would run past the end of the packet.
4531 switch (hfinfo->type) {
4539 * We allow FT_PROTOCOLs to be zero-length -
4540 * for example, an ONC RPC NULL procedure has
4541 * neither arguments nor reply, so the
4542 * payload for that protocol is empty.
4544 * We also allow the others to be zero-length -
4545 * because that's the way the code has been for a
4548 * However, we want to ensure that the start
4549 * offset is not *past* the byte past the end
4550 * of the tvbuff: we throw an exception in that
4553 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
4554 DISSECTOR_ASSERT(*length >= 0);
4559 * Leave the length as -1, so our caller knows
4565 THROW(ReportedBoundsError);
4566 DISSECTOR_ASSERT_NOT_REACHED();
4568 *item_length = *length;
4570 *item_length = *length;
4571 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
4573 * These types are for interior nodes of the
4574 * tree, and don't have data associated with
4575 * them; if the length is negative (XXX - see
4576 * above) or goes past the end of the tvbuff,
4577 * cut it short at the end of the tvbuff.
4578 * That way, if this field is selected in
4579 * Wireshark, we don't highlight stuff past
4580 * the end of the data.
4582 /* XXX - what to do, if we don't have a tvb? */
4584 length_remaining = tvb_captured_length_remaining(tvb, start);
4585 if (*item_length < 0 ||
4586 (*item_length > 0 &&
4587 (length_remaining < *item_length)))
4588 *item_length = length_remaining;
4591 if (*item_length < 0) {
4592 THROW(ReportedBoundsError);
4598 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
4599 gint length, guint item_length, const gint encoding)
4604 * We need to get the correct item length here.
4605 * That's normally done by proto_tree_new_item(),
4606 * but we won't be calling it.
4608 switch (hfinfo->type) {
4614 * The length is the specified length.
4620 * Map all non-zero values to little-endian for
4621 * backwards compatibility.
4623 n = get_uint_value(NULL, tvb, start, length,
4624 encoding ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
4630 /* XXX - make these just FT_UINT? */
4639 /* XXX - make these just FT_INT? */
4664 * The length is the specified length.
4670 report_type_length_mismatch(NULL, "a string", length, TRUE);
4673 /* This can throw an exception */
4674 /* XXX - do this without fetching the string? */
4675 tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
4677 item_length = length;
4680 case FT_UINT_STRING:
4681 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
4686 case FT_ABSOLUTE_TIME:
4687 case FT_RELATIVE_TIME:
4688 case FT_IEEE_11073_SFLOAT:
4689 case FT_IEEE_11073_FLOAT:
4691 * The length is the specified length.
4696 g_error("hfinfo->type %d (%s) not handled\n",
4698 ftype_name(hfinfo->type));
4699 DISSECTOR_ASSERT_NOT_REACHED();
4706 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4707 const gint start, const gint item_length)
4711 FIELD_INFO_NEW(PNODE_POOL(tree), fi);
4713 fi->hfinfo = hfinfo;
4715 fi->start += (tvb)?tvb_raw_offset(tvb):0;
4716 fi->length = item_length;
4719 if (!PTREE_DATA(tree)->visible)
4720 FI_SET_FLAG(fi, FI_HIDDEN);
4721 fvalue_init(&fi->value, fi->hfinfo->type);
4724 /* add the data source tvbuff */
4725 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
4727 fi->appendix_start = 0;
4728 fi->appendix_length = 0;
4733 /* If the protocol tree is to be visible, set the representation of a
4734 proto_tree entry with the name of the field for the item and with
4735 the value formatted with the supplied printf-style format and
4738 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
4742 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
4743 * items string representation */
4744 if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
4746 field_info *fi = PITEM_FINFO(pi);
4747 header_field_info *hf;
4749 DISSECTOR_ASSERT(fi);
4753 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4754 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
4758 if (IS_FT_UINT(hf->type))
4759 val = fvalue_get_uinteger(&fi->value);
4761 val = fvalue_get_uinteger64(&fi->value);
4763 val <<= hfinfo_bitshift(hf);
4765 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
4766 ret = (int) (p - fi->rep->representation);
4769 /* put in the hf name */
4770 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
4772 /* If possible, Put in the value of the string */
4773 if (ret < ITEM_LABEL_LENGTH) {
4774 ret += g_vsnprintf(fi->rep->representation + ret,
4775 ITEM_LABEL_LENGTH - ret, format, ap);
4777 if (ret >= ITEM_LABEL_LENGTH) {
4778 /* Uh oh, we don't have enough room. Tell the user
4779 * that the field is truncated.
4781 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4786 /* If the protocol tree is to be visible, set the representation of a
4787 proto_tree entry with the representation formatted with the supplied
4788 printf-style format and argument list. */
4790 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
4792 int ret; /*tmp return value */
4793 field_info *fi = PITEM_FINFO(pi);
4795 DISSECTOR_ASSERT(fi);
4797 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4798 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4799 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
4801 if (ret >= ITEM_LABEL_LENGTH) {
4802 /* Uh oh, we don't have enough room. Tell the user
4803 * that the field is truncated.
4805 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4811 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
4813 switch (hfinfo->display) {
4815 return format_text(string, strlen(string));
4818 return format_text_wsp(string, strlen(string));
4821 /* XXX, format_unicode_text() */
4825 return format_text(string, strlen(string));
4829 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
4831 gsize res = g_strlcpy(dest, src, dest_size);
4833 if (res > dest_size)
4838 static header_field_info *
4839 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
4841 header_field_info *dup_hfinfo;
4843 if (hfinfo->same_name_prev_id == -1)
4845 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
4850 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
4852 g_free(last_field_name);
4853 last_field_name = NULL;
4855 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
4856 /* No hfinfo with the same name */
4857 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
4861 if (hfinfo->same_name_next) {
4862 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
4865 if (hfinfo->same_name_prev_id != -1) {
4866 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
4867 same_name_prev->same_name_next = hfinfo->same_name_next;
4868 if (!hfinfo->same_name_next) {
4869 /* It's always the latest added hfinfo which is stored in gpa_name_map */
4870 g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
4875 /* -------------------------- */
4877 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
4878 gchar *result, gchar *expr, const int size)
4883 ipv4_addr_and_mask *ipv4;
4884 struct e_in6_addr *ipv6;
4886 guint32 n_addr; /* network-order IPv4 address */
4888 const true_false_string *tfstring;
4890 int len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
4892 field_info *finfo = NULL;
4893 header_field_info* hfinfo;
4894 const gchar *abbrev = NULL;
4896 const char *hf_str_val;
4897 char number_buf[48];
4898 const char *number_out;
4904 g_assert(field_ids != NULL);
4905 while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
4906 field_id = *field_idx;
4907 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
4909 /* do we need to rewind ? */
4913 if (occurrence < 0) {
4914 /* Search other direction */
4915 while (hfinfo->same_name_prev_id != -1) {
4916 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
4921 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
4923 if (!finfos || !(len = g_ptr_array_len(finfos))) {
4924 if (occurrence < 0) {
4925 hfinfo = hfinfo->same_name_next;
4927 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4932 /* Are there enough occurrences of the field? */
4933 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
4934 if (occurrence < 0) {
4935 hfinfo = hfinfo->same_name_next;
4937 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4943 /* Calculate single index or set outer bounderies */
4944 if (occurrence < 0) {
4945 i = occurrence + len + prev_len;
4947 } else if (occurrence > 0) {
4948 i = occurrence - 1 - prev_len;
4955 prev_len += len; /* Count handled occurrences */
4958 finfo = (field_info *)g_ptr_array_index(finfos, i);
4960 if (offset_r && (offset_r < (size - 2)))
4961 result[offset_r++] = ',';
4963 if (offset_e && (offset_e < (size - 2)))
4964 expr[offset_e++] = ',';
4966 switch (hfinfo->type) {
4968 case FT_NONE: /* Nothing to add */
4969 if (offset_r == 0) {
4971 } else if (result[offset_r-1] == ',') {
4972 result[offset_r-1] = '\0';
4977 /* prevent multiple "yes" entries by setting result directly */
4978 g_strlcpy(result, "Yes", size);
4983 bytes = (guint8 *)fvalue_get(&finfo->value);
4985 switch(hfinfo->display)
4988 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
4991 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
4994 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
4997 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5001 if (prefs.display_byte_fields_with_spaces)
5003 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5007 str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
5011 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5012 wmem_free(NULL, str);
5015 if (hfinfo->display & BASE_ALLOW_ZERO) {
5016 offset_r += protoo_strlcpy(result+offset_r, "<none>", size-offset_r);
5018 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
5023 case FT_ABSOLUTE_TIME:
5024 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
5025 offset_r += protoo_strlcpy(result+offset_r,
5028 wmem_free(NULL, tmpbuf);
5031 case FT_RELATIVE_TIME:
5032 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
5033 offset_r += protoo_strlcpy(result+offset_r,
5036 wmem_free(NULL, tmpbuf);
5040 number64 = fvalue_get_uinteger64(&finfo->value);
5041 tfstring = (const true_false_string *)&tfs_true_false;
5042 if (hfinfo->strings) {
5043 tfstring = (const struct true_false_string*) hfinfo->strings;
5045 offset_r += protoo_strlcpy(result+offset_r,
5047 tfstring->true_string :
5048 tfstring->false_string, size-offset_r);
5050 offset_e += protoo_strlcpy(expr+offset_e,
5051 number64 ? "1" : "0", size-offset_e);
5056 number = fvalue_get_uinteger(&finfo->value);
5058 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5059 gchar tmp[ITEM_LABEL_LENGTH];
5060 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5062 DISSECTOR_ASSERT(fmtfunc);
5063 fmtfunc(tmp, number);
5065 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5067 } else if (hfinfo->strings) {
5068 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5071 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
5073 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5076 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5078 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5081 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5082 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5084 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5086 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5089 offset_e = (int)strlen(expr);
5092 /* XXX - make these just FT_NUMBER? */
5103 number = IS_FT_INT(hfinfo->type) ?
5104 (guint32) fvalue_get_sinteger(&finfo->value) :
5105 fvalue_get_uinteger(&finfo->value);
5107 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5108 gchar tmp[ITEM_LABEL_LENGTH];
5109 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5111 DISSECTOR_ASSERT(fmtfunc);
5112 fmtfunc(tmp, number);
5114 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5116 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
5117 if (hfinfo->display & BASE_UNIT_STRING) {
5118 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5119 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5120 hf_str_val = hf_try_val_to_str(number, hfinfo);
5121 offset_r += protoo_strlcpy(result+offset_r, hf_str_val, size-offset_r);
5124 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5127 number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
5129 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5132 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
5134 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5137 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5138 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5140 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5142 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5145 offset_e = (int)strlen(expr);
5157 number64 = IS_FT_INT(hfinfo->type) ?
5158 (guint64) fvalue_get_sinteger64(&finfo->value) :
5159 fvalue_get_uinteger64(&finfo->value);
5161 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5162 gchar tmp[ITEM_LABEL_LENGTH];
5163 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
5165 DISSECTOR_ASSERT(fmtfunc64);
5166 fmtfunc64(tmp, number64);
5167 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5168 } else if (hfinfo->strings) {
5169 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
5172 number_out = hfinfo_number_value_format_display64(hfinfo, BASE_DEC, number_buf, number64);
5174 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5177 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
5179 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5182 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5183 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5185 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
5187 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5190 offset_e = (int)strlen(expr);
5194 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
5195 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5196 wmem_free(NULL, str);
5200 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&finfo->value);
5201 n_addr = ipv4_get_net_order_addr(ipv4);
5202 set_address (&addr, AT_IPv4, 4, &n_addr);
5203 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5204 offset_r = (int)strlen(result);
5208 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
5209 set_address (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
5210 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5211 offset_r = (int)strlen(result);
5215 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
5216 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5217 offset_r = (int)strlen(result);
5221 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
5222 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5223 offset_r = (int)strlen(result);
5227 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
5228 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5229 wmem_free(NULL, str);
5233 bytes = (guint8 *)fvalue_get(&finfo->value);
5234 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5235 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5236 wmem_free(NULL, str);
5238 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5239 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5240 wmem_free(NULL, str);
5244 bytes = (guint8 *)fvalue_get(&finfo->value);
5245 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5246 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5247 wmem_free(NULL, str);
5249 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5250 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5251 wmem_free(NULL, str);
5255 bytes = (guint8 *)fvalue_get(&finfo->value);
5256 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
5257 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5258 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5259 wmem_free(NULL, str);
5263 if (hfinfo->display & BASE_UNIT_STRING) {
5264 double d_value = fvalue_get_floating(&finfo->value);
5265 g_snprintf(result+offset_r, size-offset_r,
5266 "%." G_STRINGIFY(FLT_DIG) "g%s", d_value,
5267 unit_name_string_get_value64((guint64)d_value, (unit_name_string*)hfinfo->strings));
5269 g_snprintf(result+offset_r, size-offset_r,
5270 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
5272 offset_r = (int)strlen(result);
5276 if (hfinfo->display & BASE_UNIT_STRING) {
5277 double d_value = fvalue_get_floating(&finfo->value);
5278 g_snprintf(result+offset_r, size-offset_r,
5279 "%." G_STRINGIFY(DBL_DIG) "g%s", d_value,
5280 unit_name_string_get_value64((guint64)d_value, (unit_name_string*)hfinfo->strings));
5282 g_snprintf(result+offset_r, size-offset_r,
5283 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
5285 offset_r = (int)strlen(result);
5290 case FT_UINT_STRING:
5292 bytes = (guint8 *)fvalue_get(&finfo->value);
5293 offset_r += protoo_strlcpy(result+offset_r,
5294 hfinfo_format_text(hfinfo, bytes),
5298 case FT_IEEE_11073_SFLOAT:
5299 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5300 g_snprintf(result+offset_r, size-offset_r,
5303 wmem_free(NULL, str);
5304 offset_r = (int)strlen(result);
5307 case FT_IEEE_11073_FLOAT:
5308 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5309 g_snprintf(result+offset_r, size-offset_r,
5312 offset_r = (int)strlen(result);
5313 wmem_free(NULL, str);
5316 case FT_IPXNET: /*XXX really No column custom ?*/
5319 g_error("hfinfo->type %d (%s) not handled\n",
5321 ftype_name(hfinfo->type));
5322 DISSECTOR_ASSERT_NOT_REACHED();
5328 switch (hfinfo->type) {
5352 /* for these types, "expr" is filled in the loop above */
5356 /* for all others, just copy "result" to "expr" */
5357 g_strlcpy(expr, result, size);
5362 /* Store abbrev for return value */
5363 abbrev = hfinfo->abbrev;
5366 if (occurrence == 0) {
5367 /* Fetch next hfinfo with same name (abbrev) */
5368 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5375 return abbrev ? abbrev : "";
5379 /* Set text of proto_item after having already been created. */
5381 proto_item_set_text(proto_item *pi, const char *format, ...)
5383 field_info *fi = NULL;
5386 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5388 fi = PITEM_FINFO(pi);
5393 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
5397 va_start(ap, format);
5398 proto_tree_set_representation(pi, format, ap);
5402 /* Append to text of proto_item after having already been created. */
5404 proto_item_append_text(proto_item *pi, const char *format, ...)
5406 field_info *fi = NULL;
5410 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5412 fi = PITEM_FINFO(pi);
5417 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5419 * If we don't already have a representation,
5420 * generate the default representation.
5422 if (fi->rep == NULL) {
5423 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5424 proto_item_fill_label(fi, fi->rep->representation);
5427 curlen = strlen(fi->rep->representation);
5428 if (ITEM_LABEL_LENGTH > curlen) {
5429 va_start(ap, format);
5430 g_vsnprintf(fi->rep->representation + curlen,
5431 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
5437 /* Prepend to text of proto_item after having already been created. */
5439 proto_item_prepend_text(proto_item *pi, const char *format, ...)
5441 field_info *fi = NULL;
5442 char representation[ITEM_LABEL_LENGTH];
5445 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5447 fi = PITEM_FINFO(pi);
5452 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5454 * If we don't already have a representation,
5455 * generate the default representation.
5457 if (fi->rep == NULL) {
5458 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5459 proto_item_fill_label(fi, representation);
5461 g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
5463 va_start(ap, format);
5464 g_vsnprintf(fi->rep->representation,
5465 ITEM_LABEL_LENGTH, format, ap);
5467 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
5472 finfo_set_len(field_info *fi, const gint length)
5474 DISSECTOR_ASSERT(length >= 0);
5475 fi->length = length;
5478 * You cannot just make the "len" field of a GByteArray
5479 * larger, if there's no data to back that length;
5480 * you can only make it smaller.
5482 if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
5483 fi->value.value.bytes->len = length;
5487 proto_item_set_len(proto_item *pi, const gint length)
5491 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5493 fi = PITEM_FINFO(pi);
5497 finfo_set_len(fi, length);
5501 * Sets the length of the item based on its start and on the specified
5502 * offset, which is the offset past the end of the item; as the start
5503 * in the item is relative to the beginning of the data source tvbuff,
5504 * we need to pass in a tvbuff - the end offset is relative to the beginning
5508 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
5513 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5515 fi = PITEM_FINFO(pi);
5519 end += tvb_raw_offset(tvb);
5520 DISSECTOR_ASSERT(end >= fi->start);
5521 length = end - fi->start;
5523 finfo_set_len(fi, length);
5527 proto_item_get_len(const proto_item *pi)
5529 field_info *fi = PITEM_FINFO(pi);
5530 return fi ? fi->length : -1;
5534 proto_tree_create_root(packet_info *pinfo)
5538 /* Initialize the proto_node */
5539 pnode = g_slice_new(proto_tree);
5540 PROTO_NODE_INIT(pnode);
5541 pnode->parent = NULL;
5542 PNODE_FINFO(pnode) = NULL;
5543 pnode->tree_data = g_slice_new(tree_data_t);
5545 /* Make sure we can access pinfo everywhere */
5546 pnode->tree_data->pinfo = pinfo;
5548 /* Don't initialize the tree_data_t. Wait until we know we need it */
5549 pnode->tree_data->interesting_hfids = NULL;
5551 /* Set the default to FALSE so it's easier to
5552 * find errors; if we expect to see the protocol tree
5553 * but for some reason the default 'visible' is not
5554 * changed, then we'll find out very quickly. */
5555 pnode->tree_data->visible = FALSE;
5557 /* Make sure that we fake protocols (if possible) */
5558 pnode->tree_data->fake_protocols = TRUE;
5560 /* Keep track of the number of children */
5561 pnode->tree_data->count = 0;
5563 return (proto_tree *)pnode;
5567 /* "prime" a proto_tree with a single hfid that a dfilter
5568 * is interested in. */
5570 proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
5572 header_field_info *hfinfo;
5574 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
5575 /* this field is referenced by a filter so increase the refcount.
5576 also increase the refcount for the parent, i.e the protocol.
5578 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
5579 /* only increase the refcount if there is a parent.
5580 if this is a protocol and not a field then parent will be -1
5581 and there is no parent to add any refcounting for.
5583 if (hfinfo->parent != -1) {
5584 header_field_info *parent_hfinfo;
5585 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
5587 /* Mark parent as indirectly referenced unless it is already directly
5588 * referenced, i.e. the user has specified the parent in a filter.
5590 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
5591 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
5596 proto_item_add_subtree(proto_item *pi, const gint idx) {
5602 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
5604 fi = PITEM_FINFO(pi);
5606 return (proto_tree *)pi;
5608 fi->tree_type = idx;
5610 return (proto_tree *)pi;
5614 proto_item_get_subtree(proto_item *pi) {
5619 fi = PITEM_FINFO(pi);
5620 if ( (!fi) || (fi->tree_type == -1) )
5622 return (proto_tree *)pi;
5626 proto_item_get_parent(const proto_item *ti) {
5633 proto_item_get_parent_nth(proto_item *ti, int gen) {
5646 proto_tree_get_parent(proto_tree *tree) {
5649 return (proto_item *)tree;
5653 proto_tree_get_parent_tree(proto_tree *tree) {
5657 /* we're the root tree, there's no parent
5658 return ourselves so the caller has at least a tree to attach to */
5662 return (proto_tree *)tree->parent;
5666 proto_tree_get_root(proto_tree *tree) {
5669 while (tree->parent) {
5670 tree = tree->parent;
5676 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
5677 proto_item *item_to_move)
5680 /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
5681 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
5683 /* This function doesn't generate any values. It only reorganizes the prococol tree
5684 * so we can bail out immediately if it isn't visible. */
5685 if (!tree || !PTREE_DATA(tree)->visible)
5688 DISSECTOR_ASSERT(item_to_move->parent == tree);
5689 DISSECTOR_ASSERT(fixed_item->parent == tree);
5691 /*** cut item_to_move out ***/
5693 /* is item_to_move the first? */
5694 if (tree->first_child == item_to_move) {
5695 /* simply change first child to next */
5696 tree->first_child = item_to_move->next;
5698 DISSECTOR_ASSERT(tree->last_child != item_to_move);
5700 proto_item *curr_item;
5701 /* find previous and change it's next */
5702 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
5703 if (curr_item->next == item_to_move) {
5708 DISSECTOR_ASSERT(curr_item);
5710 curr_item->next = item_to_move->next;
5712 /* fix last_child if required */
5713 if (tree->last_child == item_to_move) {
5714 tree->last_child = curr_item;
5718 /*** insert to_move after fixed ***/
5719 item_to_move->next = fixed_item->next;
5720 fixed_item->next = item_to_move;
5721 if (tree->last_child == fixed_item) {
5722 tree->last_child = item_to_move;
5727 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
5735 fi = PTREE_FINFO(tree);
5739 start += tvb_raw_offset(tvb);
5740 DISSECTOR_ASSERT(start >= 0);
5741 DISSECTOR_ASSERT(length >= 0);
5743 fi->appendix_start = start;
5744 fi->appendix_length = length;
5748 proto_register_protocol(const char *name, const char *short_name,
5749 const char *filter_name)
5751 protocol_t *protocol;
5752 const protocol_t *existing_protocol = NULL;
5753 header_field_info *hfinfo;
5755 const char *existing_name;
5759 gboolean found_invalid;
5762 * Make sure there's not already a protocol with any of those
5763 * names. Crash if there is, as that's an error in the code
5764 * or an inappropriate plugin.
5765 * This situation has to be fixed to not register more than one
5766 * protocol with the same name.
5768 * This is done by reducing the number of strcmp (and alike) calls
5769 * as much as possible, as this significally slows down startup time.
5771 * Drawback: As a hash value is used to reduce insert time,
5772 * this might lead to a hash collision.
5773 * However, although we have somewhat over 1000 protocols, we're using
5774 * a 32 bit int so this is very, very unlikely.
5777 key = (gint *)g_malloc (sizeof(gint));
5778 *key = wrs_str_hash(name);
5780 existing_name = (const char *)g_hash_table_lookup(proto_names, key);
5781 if (existing_name != NULL) {
5782 /* g_error will terminate the program */
5783 g_error("Duplicate protocol name \"%s\"!"
5784 " This might be caused by an inappropriate plugin or a development error.", name);
5786 g_hash_table_insert(proto_names, key, (gpointer)name);
5788 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5789 if (existing_protocol != NULL) {
5790 g_error("Duplicate protocol short_name \"%s\"!"
5791 " This might be caused by an inappropriate plugin or a development error.", short_name);
5794 found_invalid = FALSE;
5795 for (i = 0; filter_name[i]; i++) {
5797 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
5798 found_invalid = TRUE;
5801 if (found_invalid) {
5802 g_error("Protocol filter name \"%s\" has one or more invalid characters."
5803 " Allowed are lower characters, digits, '-', '_' and '.'."
5804 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5806 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5807 if (existing_protocol != NULL) {
5808 g_error("Duplicate protocol filter_name \"%s\"!"
5809 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5812 /* Add this protocol to the list of known protocols; the list
5813 is sorted by protocol short name. */
5814 protocol = g_new(protocol_t, 1);
5815 protocol->name = name;
5816 protocol->short_name = short_name;
5817 protocol->filter_name = filter_name;
5818 /*protocol->fields = g_ptr_array_new();*/
5819 /* Delegate until actually needed and use g_ptr_array_sized_new*/
5820 protocol->fields = NULL;
5821 protocol->is_enabled = TRUE; /* protocol is enabled by default */
5822 protocol->enabled_by_default = TRUE; /* see previous comment */
5823 protocol->can_toggle = TRUE;
5824 protocol->heur_list = NULL;
5825 /* list will be sorted later by name, when all protocols completed registering */
5826 protocols = g_list_prepend(protocols, protocol);
5827 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
5828 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
5830 /* Here we allocate a new header_field_info struct */
5831 hfinfo = g_slice_new(header_field_info);
5832 hfinfo->name = name;
5833 hfinfo->abbrev = filter_name;
5834 hfinfo->type = FT_PROTOCOL;
5835 hfinfo->display = BASE_NONE;
5836 hfinfo->strings = protocol;
5837 hfinfo->bitmask = 0;
5838 hfinfo->ref_type = HF_REF_TYPE_NONE;
5839 hfinfo->blurb = NULL;
5840 hfinfo->parent = -1; /* this field differentiates protos and fields */
5842 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
5843 protocol->proto_id = proto_id;
5848 proto_deregister_protocol(const char *short_name)
5850 protocol_t *protocol;
5851 header_field_info *hfinfo;
5856 proto_id = proto_get_id_by_short_name(short_name);
5857 protocol = find_protocol_by_id(proto_id);
5858 if (protocol == NULL)
5861 key = wrs_str_hash(protocol->name);
5862 g_hash_table_remove(proto_names, &key);
5864 g_hash_table_remove(proto_short_names, (gpointer)short_name);
5865 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
5867 if (protocol->fields) {
5868 for (i = 0; i < protocol->fields->len; i++) {
5869 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
5870 hfinfo_remove_from_gpa_name_map(hfinfo);
5871 expert_deregister_expertinfo(hfinfo->abbrev);
5872 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
5874 g_ptr_array_free(protocol->fields, TRUE);
5875 protocol->fields = NULL;
5878 /* Remove this protocol from the list of known protocols */
5879 protocols = g_list_remove(protocols, protocol);
5881 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
5882 g_hash_table_steal(gpa_name_map, protocol->filter_name);
5884 g_free(last_field_name);
5885 last_field_name = NULL;
5891 * Routines to use to iterate over the protocols.
5892 * The argument passed to the iterator routines is an opaque cookie to
5893 * their callers; it's the GList pointer for the current element in
5895 * The ID of the protocol is returned, or -1 if there is no protocol.
5898 proto_get_first_protocol(void **cookie)
5900 protocol_t *protocol;
5902 if (protocols == NULL)
5904 *cookie = protocols;
5905 protocol = (protocol_t *)protocols->data;
5906 return protocol->proto_id;
5910 proto_get_data_protocol(void *cookie)
5912 GList *list_item = (GList *)cookie;
5914 protocol_t *protocol = (protocol_t *)list_item->data;
5915 return protocol->proto_id;
5919 proto_get_next_protocol(void **cookie)
5921 GList *list_item = (GList *)*cookie;
5922 protocol_t *protocol;
5924 list_item = g_list_next(list_item);
5925 if (list_item == NULL)
5927 *cookie = list_item;
5928 protocol = (protocol_t *)list_item->data;
5929 return protocol->proto_id;
5932 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
5933 assume that the cookie stored by
5934 proto_get_(first|next)_protocol_field() will never have a
5935 value of NULL. So, to preserve this semantic, the cookie value
5936 below is adjusted so that the cookie value stored is 1 + the
5937 current (zero-based) array index.
5940 proto_get_first_protocol_field(const int proto_id, void **cookie)
5942 protocol_t *protocol = find_protocol_by_id(proto_id);
5944 if ((protocol == NULL) || (protocol->fields == NULL))
5947 *cookie = GUINT_TO_POINTER(0 + 1);
5948 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
5952 proto_get_next_protocol_field(const int proto_id, void **cookie)
5954 protocol_t *protocol = find_protocol_by_id(proto_id);
5955 guint i = GPOINTER_TO_UINT(*cookie) - 1;
5959 if ((protocol->fields == NULL) || (i >= protocol->fields->len))
5962 *cookie = GUINT_TO_POINTER(i + 1);
5963 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
5967 find_protocol_by_id(const int proto_id)
5969 header_field_info *hfinfo;
5974 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
5975 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
5976 return (protocol_t *)hfinfo->strings;
5980 proto_get_id(const protocol_t *protocol)
5982 return protocol->proto_id;
5986 proto_name_already_registered(const gchar *name)
5990 DISSECTOR_ASSERT_HINT(name, "No name present");
5992 key = wrs_str_hash(name);
5993 if (g_hash_table_lookup(proto_names, &key) != NULL)
5999 proto_get_id_by_filter_name(const gchar *filter_name)
6001 const protocol_t *protocol = NULL;
6003 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
6005 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
6007 if (protocol == NULL)
6009 return protocol->proto_id;
6013 proto_get_id_by_short_name(const gchar *short_name)
6015 const protocol_t *protocol = NULL;
6017 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
6019 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
6021 if (protocol == NULL)
6023 return protocol->proto_id;
6027 proto_get_protocol_name(const int proto_id)
6029 protocol_t *protocol;
6031 protocol = find_protocol_by_id(proto_id);
6033 if (protocol == NULL)
6035 return protocol->name;
6039 proto_get_protocol_short_name(const protocol_t *protocol)
6041 if (protocol == NULL)
6043 return protocol->short_name;
6047 proto_get_protocol_long_name(const protocol_t *protocol)
6049 if (protocol == NULL)
6051 return protocol->name;
6055 proto_get_protocol_filter_name(const int proto_id)
6057 protocol_t *protocol;
6059 protocol = find_protocol_by_id(proto_id);
6060 if (protocol == NULL)
6062 return protocol->filter_name;
6065 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
6067 heur_dtbl_entry_t* heuristic_dissector;
6069 if (protocol == NULL)
6072 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
6073 if (heuristic_dissector != NULL)
6075 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
6079 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
6081 if (protocol == NULL)
6084 g_list_foreach(protocol->heur_list, func, user_data);
6088 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
6089 gboolean *is_tcp, gboolean *is_udp,
6090 gboolean *is_sctp, gboolean *is_ssl,
6092 gboolean *is_lte_rlc)
6094 wmem_list_frame_t *protos = wmem_list_head(layers);
6096 const char *proto_name;
6098 /* Walk the list of a available protocols in the packet and
6099 find "major" ones. */
6100 /* It might make more sense to assemble and return a bitfield. */
6101 while (protos != NULL)
6103 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6104 proto_name = proto_get_protocol_filter_name(proto_id);
6106 if (is_ip && ((!strcmp(proto_name, "ip")) ||
6107 (!strcmp(proto_name, "ipv6")))) {
6109 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
6111 } else if (is_udp && !strcmp(proto_name, "udp")) {
6113 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
6115 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
6117 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
6119 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
6123 protos = wmem_list_frame_next(protos);
6128 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
6130 wmem_list_frame_t *protos = wmem_list_head(layers);
6134 /* Walk the list of a available protocols in the packet and
6135 find "major" ones. */
6136 /* It might make more sense to assemble and return a bitfield. */
6137 while (protos != NULL)
6139 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6140 name = proto_get_protocol_filter_name(proto_id);
6142 if (!strcmp(name, proto_name))
6147 protos = wmem_list_frame_next(protos);
6155 proto_is_protocol_enabled(const protocol_t *protocol)
6157 return protocol->is_enabled;
6161 proto_can_toggle_protocol(const int proto_id)
6163 protocol_t *protocol;
6165 protocol = find_protocol_by_id(proto_id);
6166 return protocol->can_toggle;
6170 proto_disable_by_default(const int proto_id)
6172 protocol_t *protocol;
6174 protocol = find_protocol_by_id(proto_id);
6175 DISSECTOR_ASSERT(protocol->can_toggle);
6176 protocol->is_enabled = FALSE;
6177 protocol->enabled_by_default = FALSE;
6181 proto_set_decoding(const int proto_id, const gboolean enabled)
6183 protocol_t *protocol;
6185 protocol = find_protocol_by_id(proto_id);
6186 DISSECTOR_ASSERT(protocol->can_toggle);
6187 protocol->is_enabled = enabled;
6191 proto_enable_all(void)
6193 protocol_t *protocol;
6194 GList *list_item = protocols;
6196 if (protocols == NULL)
6200 protocol = (protocol_t *)list_item->data;
6201 if (protocol->can_toggle && protocol->enabled_by_default)
6202 protocol->is_enabled = TRUE;
6203 list_item = g_list_next(list_item);
6208 proto_set_cant_toggle(const int proto_id)
6210 protocol_t *protocol;
6212 protocol = find_protocol_by_id(proto_id);
6213 protocol->can_toggle = FALSE;
6217 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
6219 if (proto != NULL) {
6220 g_ptr_array_add(proto->fields, hfi);
6223 return proto_register_field_init(hfi, parent);
6226 /* for use with static arrays only, since we don't allocate our own copies
6227 of the header_field_info struct contained within the hf_register_info struct */
6229 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
6231 hf_register_info *ptr = hf;
6235 proto = find_protocol_by_id(parent);
6237 if (proto->fields == NULL) {
6238 proto->fields = g_ptr_array_sized_new(num_records);
6241 for (i = 0; i < num_records; i++, ptr++) {
6243 * Make sure we haven't registered this yet.
6244 * Most fields have variables associated with them
6245 * that are initialized to -1; some have array elements,
6246 * or possibly uninitialized variables, so we also allow
6247 * 0 (which is unlikely to be the field ID we get back
6248 * from "proto_register_field_init()").
6250 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
6252 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
6253 ptr->hfinfo.abbrev);
6257 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
6262 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
6267 proto = find_protocol_by_id(parent);
6269 if (proto->fields == NULL) {
6270 proto->fields = g_ptr_array_sized_new(num_records);
6273 for (i = 0; i < num_records; i++) {
6275 * Make sure we haven't registered this yet.
6277 if (hfi[i].id != -1) {
6279 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6284 proto_register_field_common(proto, &hfi[i], parent);
6289 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
6294 proto = find_protocol_by_id(parent);
6296 if (proto->fields == NULL) {
6297 proto->fields = g_ptr_array_sized_new(num_records);
6301 for (i = 0; i < num_records; i++) {
6303 * Make sure we haven't registered this yet.
6305 if (hfi[i]->id != -1) {
6307 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6312 proto_register_field_common(proto, hfi[i], parent);
6316 /* deregister already registered fields */
6318 proto_deregister_field (const int parent, gint hf_id)
6320 header_field_info *hfi;
6324 g_free(last_field_name);
6325 last_field_name = NULL;
6327 if (hf_id == -1 || hf_id == 0)
6330 proto = find_protocol_by_id (parent);
6331 if (!proto || proto->fields == NULL) {
6335 for (i = 0; i < proto->fields->len; i++) {
6336 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
6337 if (hfi->id == hf_id) {
6338 /* Found the hf_id in this protocol */
6339 g_hash_table_steal(gpa_name_map, hfi->abbrev);
6340 g_ptr_array_remove_index_fast(proto->fields, i);
6341 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
6348 proto_add_deregistered_data (void *data)
6350 g_ptr_array_add(deregistered_data, data);
6354 free_deregistered_field (gpointer data, gpointer user_data _U_)
6356 header_field_info *hfi = (header_field_info *) data;
6357 gint hf_id = hfi->id;
6359 g_free((char *)hfi->name);
6360 g_free((char *)hfi->abbrev);
6361 g_free((char *)hfi->blurb);
6364 switch (hfi->type) {
6366 /* This is just an integer represented as a pointer */
6369 protocol_t *protocol = (protocol_t *)hfi->strings;
6370 g_free((gchar *)protocol->short_name);
6374 true_false_string *tf = (true_false_string *)hfi->strings;
6375 g_free ((gchar *)tf->true_string);
6376 g_free ((gchar *)tf->false_string);
6381 if (hfi->display & BASE_UNIT_STRING) {
6382 unit_name_string *unit = (unit_name_string*)hfi->strings;
6383 g_free ((gchar *)unit->singular);
6384 g_free ((gchar *)unit->plural);
6386 val64_string *vs64 = (val64_string *)hfi->strings;
6387 while (vs64->strptr) {
6388 g_free((gchar *)vs64->strptr);
6395 /* Other Integer types */
6396 if (hfi->display & BASE_UNIT_STRING) {
6397 unit_name_string *unit = (unit_name_string*)hfi->strings;
6398 g_free ((gchar *)unit->singular);
6399 g_free ((gchar *)unit->plural);
6401 value_string *vs = (value_string *)hfi->strings;
6402 while (vs->strptr) {
6403 g_free((gchar *)vs->strptr);
6410 if (hfi->type != FT_FRAMENUM) {
6411 g_free((void *)hfi->strings);
6415 if (hfi->parent == -1)
6416 g_slice_free(header_field_info, hfi);
6418 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
6422 free_deregistered_data (gpointer data, gpointer user_data _U_)
6427 /* free deregistered fields and data */
6429 proto_free_deregistered_fields (void)
6431 expert_free_deregistered_expertinfos();
6433 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
6434 g_ptr_array_free(deregistered_fields, TRUE);
6435 deregistered_fields = g_ptr_array_new();
6437 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
6438 g_ptr_array_free(deregistered_data, TRUE);
6439 deregistered_data = g_ptr_array_new();
6442 /* chars allowed in field abbrev */
6444 const guint8 fld_abbrev_chars[256] = {
6445 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
6446 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
6447 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
6448 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
6449 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
6450 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
6451 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
6452 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
6453 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
6454 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
6455 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
6456 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
6457 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
6458 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
6459 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
6460 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
6463 static const value_string hf_display[] = {
6464 { BASE_NONE, "BASE_NONE" },
6465 { BASE_DEC, "BASE_DEC" },
6466 { BASE_HEX, "BASE_HEX" },
6467 { BASE_OCT, "BASE_OCT" },
6468 { BASE_DEC_HEX, "BASE_DEC_HEX" },
6469 { BASE_HEX_DEC, "BASE_HEX_DEC" },
6470 { BASE_CUSTOM, "BASE_CUSTOM" },
6471 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
6472 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
6473 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
6474 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
6475 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
6476 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
6477 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
6478 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
6479 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
6480 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
6481 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
6482 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
6483 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
6484 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
6485 /* Alias: BASE_NONE { BASE_FLOAT, "BASE_FLOAT" }, */
6486 /* Alias: BASE_NONE { STR_ASCII, "STR_ASCII" }, */
6487 { STR_UNICODE, "STR_UNICODE" },
6488 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
6489 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
6490 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
6491 { BASE_PT_UDP, "BASE_PT_UDP" },
6492 { BASE_PT_TCP, "BASE_PT_TCP" },
6493 { BASE_PT_DCCP, "BASE_PT_DCCP" },
6494 { BASE_PT_SCTP, "BASE_PT_SCTP" },
6497 const char* proto_field_display_to_string(int field_display)
6499 return val_to_str_const(field_display, hf_display, "Unknown");
6502 static inline port_type
6503 display_to_port_type(field_display_e e)
6520 /* temporary function containing assert part for easier profiling */
6522 tmp_fld_check_assert(header_field_info *hfinfo)
6526 /* The field must have a name (with length > 0) */
6527 if (!hfinfo->name || !hfinfo->name[0]) {
6529 /* Try to identify the field */
6530 g_error("Field (abbrev='%s') does not have a name\n",
6534 g_error("Field does not have a name (nor an abbreviation)\n");
6537 /* fields with an empty string for an abbreviation aren't filterable */
6538 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
6539 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
6541 /* These types of fields are allowed to have value_strings,
6542 * true_false_strings or a protocol_t struct
6544 if (hfinfo->strings != NULL) {
6545 switch(hfinfo->type) {
6569 //allowed to support string if its a unit decsription
6570 if (hfinfo->display & BASE_UNIT_STRING)
6575 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
6576 " (which is not allowed to have strings)\n",
6577 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
6581 /* TODO: This check may slow down startup, and output quite a few warnings.
6582 It would be good to be able to enable this (and possibly other checks?)
6583 in non-release builds. */
6585 /* Check for duplicate value_string values.
6586 There are lots that have the same value *and* string, so for now only
6587 report those that have same value but different string. */
6588 if ((hfinfo->strings != NULL) &&
6589 !(hfinfo->display & BASE_RANGE_STRING) &&
6590 !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
6592 (hfinfo->type == FT_CHAR) ||
6593 (hfinfo->type == FT_UINT8) ||
6594 (hfinfo->type == FT_UINT16) ||
6595 (hfinfo->type == FT_UINT24) ||
6596 (hfinfo->type == FT_UINT32) ||
6597 (hfinfo->type == FT_INT8) ||
6598 (hfinfo->type == FT_INT16) ||
6599 (hfinfo->type == FT_INT24) ||
6600 (hfinfo->type == FT_INT32) ||
6601 (hfinfo->type == FT_FRAMENUM) )) {
6604 const value_string *start_values;
6605 const value_string *current;
6607 if (hfinfo->display & BASE_EXT_STRING)
6608 start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
6610 start_values = (const value_string*)hfinfo->strings;
6611 current = start_values;
6613 for (n=0; current; n++, current++) {
6614 /* Drop out if we reached the end. */
6615 if ((current->value == 0) && (current->strptr == NULL)) {
6619 /* Check value against all previous */
6620 for (m=0; m < n; m++) {
6621 /* There are lots of duplicates with the same string,
6622 so only report if different... */
6623 if ((start_values[m].value == current->value) &&
6624 (strcmp(start_values[m].strptr, current->strptr) != 0)) {
6625 ws_g_warning("Field '%s' (%s) has a conflicting entry in its"
6626 " value_string: %u is at indices %u (%s) and %u (%s))\n",
6627 hfinfo->name, hfinfo->abbrev,
6628 current->value, m, start_values[m].strptr, n, current->strptr);
6636 switch (hfinfo->type) {
6639 /* Require the char type to have BASE_HEX, BASE_OCT,
6640 * BASE_CUSTOM, or BASE_NONE as its base.
6642 * If the display value is BASE_NONE and there is a
6643 * strings conversion then the dissector writer is
6644 * telling us that the field's numerical value is
6645 * meaningless; we'll avoid showing the value to the
6648 switch (FIELD_DISPLAY(hfinfo->display)) {
6651 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6654 if (hfinfo->strings == NULL)
6655 g_error("Field '%s' (%s) is an integral value (%s)"
6656 " but is being displayed as BASE_NONE but"
6657 " without a strings conversion",
6658 hfinfo->name, hfinfo->abbrev,
6659 ftype_name(hfinfo->type));
6662 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6663 g_error("Field '%s' (%s) is a character value (%s)"
6664 " but is being displayed as %s\n",
6665 hfinfo->name, hfinfo->abbrev,
6666 ftype_name(hfinfo->type), tmp_str);
6667 wmem_free(NULL, tmp_str);
6669 if (hfinfo->display & BASE_UNIT_STRING) {
6670 g_error("Field '%s' (%s) is a character value (%s) but has a unit string\n",
6671 hfinfo->name, hfinfo->abbrev,
6672 ftype_name(hfinfo->type));
6683 /* Hexadecimal and octal are, in printf() and everywhere
6684 * else, unsigned so don't allow dissectors to register a
6685 * signed field to be displayed unsigned. (Else how would
6686 * we display negative values?)
6688 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6693 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6694 g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
6695 hfinfo->name, hfinfo->abbrev,
6696 ftype_name(hfinfo->type), tmp_str);
6697 wmem_free(NULL, tmp_str);
6708 if (IS_BASE_PORT(hfinfo->display)) {
6709 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6710 if (hfinfo->type != FT_UINT16) {
6711 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
6712 hfinfo->name, hfinfo->abbrev,
6713 tmp_str, ftype_name(hfinfo->type));
6715 if (hfinfo->strings != NULL) {
6716 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
6717 hfinfo->name, hfinfo->abbrev,
6718 ftype_name(hfinfo->type), tmp_str);
6720 if (hfinfo->bitmask != 0) {
6721 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
6722 hfinfo->name, hfinfo->abbrev,
6723 ftype_name(hfinfo->type), tmp_str);
6725 wmem_free(NULL, tmp_str);
6729 /* Require integral types (other than frame number,
6730 * which is always displayed in decimal) to have a
6733 * If the display value is BASE_NONE and there is a
6734 * strings conversion then the dissector writer is
6735 * telling us that the field's numerical value is
6736 * meaningless; we'll avoid showing the value to the
6739 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6745 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6748 if (hfinfo->strings == NULL) {
6749 g_error("Field '%s' (%s) is an integral value (%s)"
6750 " but is being displayed as BASE_NONE but"
6751 " without a strings conversion",
6752 hfinfo->name, hfinfo->abbrev,
6753 ftype_name(hfinfo->type));
6758 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6759 g_error("Field '%s' (%s) is an integral 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);
6767 /* Require bytes to have a "display type" that could
6768 * add a character between displayed bytes.
6770 switch (FIELD_DISPLAY(hfinfo->display)) {
6778 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6779 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",
6780 hfinfo->name, hfinfo->abbrev, tmp_str);
6781 wmem_free(NULL, tmp_str);
6783 if (hfinfo->bitmask != 0)
6784 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6785 hfinfo->name, hfinfo->abbrev,
6786 ftype_name(hfinfo->type));
6787 if (hfinfo->strings != NULL)
6788 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6789 hfinfo->name, hfinfo->abbrev,
6790 ftype_name(hfinfo->type));
6795 if (hfinfo->display != BASE_NONE) {
6796 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6797 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6798 hfinfo->name, hfinfo->abbrev,
6799 ftype_name(hfinfo->type), tmp_str);
6800 wmem_free(NULL, tmp_str);
6802 if (hfinfo->bitmask != 0)
6803 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6804 hfinfo->name, hfinfo->abbrev,
6805 ftype_name(hfinfo->type));
6811 case FT_ABSOLUTE_TIME:
6812 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
6813 hfinfo->display == ABSOLUTE_TIME_UTC ||
6814 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
6815 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6816 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
6817 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
6818 wmem_free(NULL, tmp_str);
6820 if (hfinfo->bitmask != 0)
6821 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6822 hfinfo->name, hfinfo->abbrev,
6823 ftype_name(hfinfo->type));
6828 case FT_UINT_STRING:
6830 switch (hfinfo->display) {
6836 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6837 g_error("Field '%s' (%s) is an string value (%s)"
6838 " but is being displayed as %s\n",
6839 hfinfo->name, hfinfo->abbrev,
6840 ftype_name(hfinfo->type), tmp_str);
6841 wmem_free(NULL, tmp_str);
6844 if (hfinfo->bitmask != 0)
6845 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6846 hfinfo->name, hfinfo->abbrev,
6847 ftype_name(hfinfo->type));
6848 if (hfinfo->strings != NULL)
6849 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6850 hfinfo->name, hfinfo->abbrev,
6851 ftype_name(hfinfo->type));
6855 switch (hfinfo->display) {
6861 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6862 g_error("Field '%s' (%s) is an IPv4 value (%s)"
6863 " but is being displayed as %s\n",
6864 hfinfo->name, hfinfo->abbrev,
6865 ftype_name(hfinfo->type), tmp_str);
6866 wmem_free(NULL, tmp_str);
6872 if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
6873 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6874 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6875 hfinfo->name, hfinfo->abbrev,
6876 ftype_name(hfinfo->type),
6878 wmem_free(NULL, tmp_str);
6880 if (hfinfo->bitmask != 0)
6881 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6882 hfinfo->name, hfinfo->abbrev,
6883 ftype_name(hfinfo->type));
6884 if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_UNIT_STRING)))
6885 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6886 hfinfo->name, hfinfo->abbrev,
6887 ftype_name(hfinfo->type));
6890 if (hfinfo->display != BASE_NONE) {
6891 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6892 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6893 hfinfo->name, hfinfo->abbrev,
6894 ftype_name(hfinfo->type),
6896 wmem_free(NULL, tmp_str);
6898 if (hfinfo->bitmask != 0)
6899 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6900 hfinfo->name, hfinfo->abbrev,
6901 ftype_name(hfinfo->type));
6902 if (hfinfo->strings != NULL)
6903 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6904 hfinfo->name, hfinfo->abbrev,
6905 ftype_name(hfinfo->type));
6910 #ifdef ENABLE_CHECK_FILTER
6912 _ftype_common(enum ftenum type)
6936 case FT_UINT_STRING:
6949 case FT_ABSOLUTE_TIME:
6950 case FT_RELATIVE_TIME:
6951 return FT_ABSOLUTE_TIME;
6960 register_type_length_mismatch(void)
6962 static ei_register_info ei[] = {
6963 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
6964 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
6967 expert_module_t* expert_type_length_mismatch;
6969 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
6971 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
6972 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
6974 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
6975 disabling them makes no sense. */
6976 proto_set_cant_toggle(proto_type_length_mismatch);
6980 register_number_string_decoding_error(void)
6982 static ei_register_info ei[] = {
6983 { &ei_number_string_decoding_failed_error,
6984 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
6985 "Failed to decode number from string", EXPFILL
6988 { &ei_number_string_decoding_erange_error,
6989 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
6990 "Decoded number from string is out of valid range", EXPFILL
6995 expert_module_t* expert_number_string_decoding_error;
6997 proto_number_string_decoding_error =
6998 proto_register_protocol("Number-String Decoding Error",
6999 "Number-string decoding error",
7000 "_ws.number_string.decoding_error");
7002 expert_number_string_decoding_error =
7003 expert_register_protocol(proto_number_string_decoding_error);
7004 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
7006 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
7007 disabling them makes no sense. */
7008 proto_set_cant_toggle(proto_number_string_decoding_error);
7011 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (183000+PRE_ALLOC_EXPERT_FIELDS_MEM)
7013 proto_register_field_init(header_field_info *hfinfo, const int parent)
7016 tmp_fld_check_assert(hfinfo);
7018 hfinfo->parent = parent;
7019 hfinfo->same_name_next = NULL;
7020 hfinfo->same_name_prev_id = -1;
7022 /* if we always add and never delete, then id == len - 1 is correct */
7023 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
7024 if (!gpa_hfinfo.hfi) {
7025 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
7026 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
7028 gpa_hfinfo.allocated_len += 1000;
7029 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
7030 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
7031 /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
7034 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
7036 hfinfo->id = gpa_hfinfo.len - 1;
7038 /* if we have real names, enter this field in the name tree */
7039 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
7041 header_field_info *same_name_next_hfinfo;
7044 /* Check that the filter name (abbreviation) is legal;
7045 * it must contain only alphanumerics, '-', "_", and ".". */
7046 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
7048 if (g_ascii_isprint(c))
7049 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
7051 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
7052 DISSECTOR_ASSERT_NOT_REACHED();
7055 /* We allow multiple hfinfo's to be registered under the same
7056 * abbreviation. This was done for X.25, as, depending
7057 * on whether it's modulo-8 or modulo-128 operation,
7058 * some bitfield fields may be in different bits of
7059 * a byte, and we want to be able to refer to that field
7060 * with one name regardless of whether the packets
7061 * are modulo-8 or modulo-128 packets. */
7063 same_name_hfinfo = NULL;
7065 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
7066 /* GLIB 2.x - if it is already present
7067 * the previous hfinfo with the same name is saved
7068 * to same_name_hfinfo by value destroy callback */
7069 if (same_name_hfinfo) {
7070 /* There's already a field with this name.
7071 * Put the current field *before* that field
7072 * in the list of fields with this name, Thus,
7073 * we end up with an effectively
7074 * doubly-linked-list of same-named hfinfo's,
7075 * with the head of the list (stored in the
7076 * hash) being the last seen hfinfo.
7078 same_name_next_hfinfo =
7079 same_name_hfinfo->same_name_next;
7081 hfinfo->same_name_next = same_name_next_hfinfo;
7082 if (same_name_next_hfinfo)
7083 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
7085 same_name_hfinfo->same_name_next = hfinfo;
7086 hfinfo->same_name_prev_id = same_name_hfinfo->id;
7087 #ifdef ENABLE_CHECK_FILTER
7088 while (same_name_hfinfo) {
7089 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
7090 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));
7091 same_name_hfinfo = same_name_hfinfo->same_name_next;
7101 proto_register_subtree_array(gint *const *indices, const int num_indices)
7104 gint *const *ptr = indices;
7107 * If we've already allocated the array of tree types, expand
7108 * it; this lets plugins such as mate add tree types after
7109 * the initial startup. (If we haven't already allocated it,
7110 * we don't allocate it; on the first pass, we just assign
7111 * ett values and keep track of how many we've assigned, and
7112 * when we're finished registering all dissectors we allocate
7113 * the array, so that we do only one allocation rather than
7114 * wasting CPU time and memory by growing the array for each
7115 * dissector that registers ett values.)
7117 if (tree_is_expanded != NULL) {
7118 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
7120 /* set new items to 0 */
7121 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
7122 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
7123 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
7127 * Assign "num_indices" subtree numbers starting at "num_tree_types",
7128 * returning the indices through the pointers in the array whose
7129 * first element is pointed to by "indices", and update
7130 * "num_tree_types" appropriately.
7132 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
7134 /* g_error will terminate the program */
7135 g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
7136 " This is a development error:"
7137 " Either the subtree item type has already been assigned or"
7138 " was not initialized to -1.");
7140 **ptr = num_tree_types;
7145 label_concat(char *label_str, gsize pos, const char *str)
7147 if (pos < ITEM_LABEL_LENGTH)
7148 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
7154 label_mark_truncated(char *label_str, gsize name_pos)
7156 static const char trunc_str[] = " [truncated]";
7157 const size_t trunc_len = sizeof(trunc_str)-1;
7160 /* ..... field_name: dataaaaaaaaaaaaa
7164 * ..... field_name [truncated]: dataaaaaaaaaaaaa
7166 * name_pos==0 means that we have only data or only a field_name
7169 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
7170 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
7171 memcpy(label_str + name_pos, trunc_str, trunc_len);
7173 /* in general, label_str is UTF-8
7174 we can truncate it only at the beginning of a new character
7175 we go backwards from the byte right after our buffer and
7176 find the next starting byte of a UTF-8 character, this is
7178 there's no need to use g_utf8_find_prev_char(), the search
7179 will always succeed since we copied trunc_str into the
7181 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH]);
7184 } else if (name_pos < ITEM_LABEL_LENGTH)
7185 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
7189 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
7193 /* "%s: %s", hfinfo->name, text */
7194 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
7195 pos = label_concat(label_str, pos, ": ");
7196 pos = label_concat(label_str, pos, text ? text : "(null)");
7198 if (pos >= ITEM_LABEL_LENGTH) {
7199 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7200 label_mark_truncated(label_str, name_pos);
7207 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
7211 /* "%s: %s (%s)", hfinfo->name, text, descr */
7212 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
7213 pos = label_concat(label_str, pos, ": ");
7214 if (hfinfo->display & BASE_UNIT_STRING) {
7215 pos = label_concat(label_str, pos, descr ? descr : "(null)");
7216 pos = label_concat(label_str, pos, text ? text : "(null)");
7218 pos = label_concat(label_str, pos, text ? text : "(null)");
7219 pos = label_concat(label_str, pos, " (");
7220 pos = label_concat(label_str, pos, descr ? descr : "(null)");
7221 pos = label_concat(label_str, pos, ")");
7224 if (pos >= ITEM_LABEL_LENGTH) {
7225 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7226 label_mark_truncated(label_str, name_pos);
7233 proto_item_fill_label(field_info *fi, gchar *label_str)
7235 header_field_info *hfinfo;
7239 ipv4_addr_and_mask *ipv4;
7241 guint32 n_addr; /* network-order IPv4 address */
7250 /* XXX: Check validity of hfinfo->type */
7254 hfinfo = fi->hfinfo;
7256 switch (hfinfo->type) {
7259 g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
7263 fill_label_boolean(fi, label_str);
7268 bytes = (guint8 *)fvalue_get(&fi->value);
7271 switch(hfinfo->display)
7274 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
7277 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
7280 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
7283 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7287 if (prefs.display_byte_fields_with_spaces)
7289 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7293 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
7297 label_fill(label_str, 0, hfinfo, str);
7298 wmem_free(NULL, str);
7300 if (hfinfo->display & BASE_ALLOW_ZERO) {
7301 label_fill(label_str, 0, hfinfo, "<none>");
7303 label_fill(label_str, 0, hfinfo, "<MISSING>");
7309 if (hfinfo->bitmask) {
7310 fill_label_bitfield_char(fi, label_str);
7312 fill_label_char(fi, label_str);
7316 /* Four types of integers to take care of:
7317 * Bitfield, with val_string
7318 * Bitfield, w/o val_string
7319 * Non-bitfield, with val_string
7320 * Non-bitfield, w/o val_string
7326 if (hfinfo->bitmask) {
7327 fill_label_bitfield(fi, label_str, FALSE);
7329 fill_label_number(fi, label_str, FALSE);
7334 fill_label_number(fi, label_str, FALSE);
7341 if (hfinfo->bitmask) {
7342 fill_label_bitfield64(fi, label_str, FALSE);
7344 fill_label_number64(fi, label_str, FALSE);
7352 if (hfinfo->bitmask) {
7353 fill_label_bitfield(fi, label_str, TRUE);
7355 fill_label_number(fi, label_str, TRUE);
7363 if (hfinfo->bitmask) {
7364 fill_label_bitfield64(fi, label_str, TRUE);
7366 fill_label_number64(fi, label_str, TRUE);
7371 double d_value = fvalue_get_floating(&fi->value);
7372 if (hfinfo->display & BASE_UNIT_STRING) {
7373 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7374 "%s: %." G_STRINGIFY(FLT_DIG) "g%s",
7375 hfinfo->name, d_value,
7376 unit_name_string_get_value64((guint64)d_value, (unit_name_string*)hfinfo->strings));
7378 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7379 "%s: %." G_STRINGIFY(FLT_DIG) "g",
7380 hfinfo->name, d_value);
7386 double d_value = fvalue_get_floating(&fi->value);
7387 if (hfinfo->display & BASE_UNIT_STRING) {
7388 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7389 "%s: %." G_STRINGIFY(DBL_DIG) "g%s",
7390 hfinfo->name, d_value,
7391 unit_name_string_get_value64((guint64)d_value, (unit_name_string*)hfinfo->strings));
7393 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7394 "%s: %." G_STRINGIFY(DBL_DIG) "g",
7395 hfinfo->name, d_value);
7400 case FT_ABSOLUTE_TIME:
7401 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
7402 label_fill(label_str, 0, hfinfo, tmp);
7403 wmem_free(NULL, tmp);
7406 case FT_RELATIVE_TIME:
7407 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
7408 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7409 "%s: %s seconds", hfinfo->name, tmp);
7410 wmem_free(NULL, tmp);
7414 integer = fvalue_get_uinteger(&fi->value);
7415 tmp = get_ipxnet_name(NULL, integer);
7416 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7417 "%s: %s (0x%08X)", hfinfo->name,
7419 wmem_free(NULL, tmp);
7423 addr.type = AT_AX25;
7424 addr.len = AX25_ADDR_LEN;
7425 addr.data = (guint8 *)fvalue_get(&fi->value);
7427 addr_str = (char*)address_to_str(NULL, &addr);
7428 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7429 "%s: %s", hfinfo->name, addr_str);
7430 wmem_free(NULL, addr_str);
7434 addr.type = vines_address_type;
7435 addr.len = VINES_ADDR_LEN;
7436 addr.data = (guint8 *)fvalue_get(&fi->value);
7438 addr_str = (char*)address_to_str(NULL, &addr);
7439 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7440 "%s: %s", hfinfo->name, addr_str);
7441 wmem_free(NULL, addr_str);
7445 bytes = (guint8 *)fvalue_get(&fi->value);
7447 addr.type = AT_ETHER;
7451 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7452 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7453 "%s: %s", hfinfo->name, addr_str);
7454 wmem_free(NULL, addr_str);
7458 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&fi->value);
7459 n_addr = ipv4_get_net_order_addr(ipv4);
7461 addr.type = AT_IPv4;
7463 addr.data = &n_addr;
7465 if (hfinfo->display == BASE_NETMASK)
7467 addr_str = (char*)address_to_str(NULL, &addr);
7471 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7473 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7474 "%s: %s", hfinfo->name, addr_str);
7475 wmem_free(NULL, addr_str);
7479 bytes = (guint8 *)fvalue_get(&fi->value);
7481 addr.type = AT_IPv6;
7485 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7486 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7487 "%s: %s", hfinfo->name, addr_str);
7488 wmem_free(NULL, addr_str);
7492 addr.type = AT_FCWWN;
7493 addr.len = FCWWN_ADDR_LEN;
7494 addr.data = (guint8 *)fvalue_get(&fi->value);
7496 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7497 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7498 "%s: %s", hfinfo->name, addr_str);
7499 wmem_free(NULL, addr_str);
7503 guid = (e_guid_t *)fvalue_get(&fi->value);
7504 tmp = guid_to_str(NULL, guid);
7505 label_fill(label_str, 0, hfinfo, tmp);
7506 wmem_free(NULL, tmp);
7510 bytes = (guint8 *)fvalue_get(&fi->value);
7511 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7512 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7514 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7515 wmem_free(NULL, name);
7517 label_fill(label_str, 0, hfinfo, tmp);
7519 wmem_free(NULL, tmp);
7523 bytes = (guint8 *)fvalue_get(&fi->value);
7524 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7525 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7527 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7528 wmem_free(NULL, name);
7530 label_fill(label_str, 0, hfinfo, tmp);
7532 wmem_free(NULL, tmp);
7536 bytes = (guint8 *)fvalue_get(&fi->value);
7537 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
7538 label_fill(label_str, 0, hfinfo, tmp);
7539 wmem_free(NULL, tmp);
7543 integer64 = fvalue_get_uinteger64(&fi->value);
7544 addr_str = eui64_to_str(NULL, integer64);
7545 tmp = (char*)eui64_to_display(NULL, integer64);
7546 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
7547 wmem_free(NULL, tmp);
7548 wmem_free(NULL, addr_str);
7552 case FT_UINT_STRING:
7554 bytes = (guint8 *)fvalue_get(&fi->value);
7555 label_fill(label_str, 0, hfinfo, hfinfo_format_text(hfinfo, bytes));
7558 case FT_IEEE_11073_SFLOAT:
7559 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7560 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7563 wmem_free(NULL, tmp);
7565 case FT_IEEE_11073_FLOAT:
7566 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7567 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7570 wmem_free(NULL, tmp);
7574 g_error("hfinfo->type %d (%s) not handled\n",
7575 hfinfo->type, ftype_name(hfinfo->type));
7576 DISSECTOR_ASSERT_NOT_REACHED();
7582 fill_label_boolean(field_info *fi, gchar *label_str)
7584 char *p = label_str;
7585 int bitfield_byte_length = 0, bitwidth;
7586 guint64 unshifted_value;
7589 header_field_info *hfinfo = fi->hfinfo;
7590 const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
7592 if (hfinfo->strings) {
7593 tfstring = (const struct true_false_string*) hfinfo->strings;
7596 value = fvalue_get_uinteger64(&fi->value);
7597 if (hfinfo->bitmask) {
7598 /* Figure out the bit width */
7599 bitwidth = hfinfo_container_bitwidth(hfinfo);
7602 unshifted_value = value;
7603 unshifted_value <<= hfinfo_bitshift(hfinfo);
7605 /* Create the bitfield first */
7606 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7607 bitfield_byte_length = (int) (p - label_str);
7610 /* Fill in the textual info */
7611 label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
7615 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
7617 if (hfinfo->display & BASE_RANGE_STRING)
7618 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
7620 if (hfinfo->display & BASE_EXT_STRING)
7621 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
7623 if (hfinfo->display & BASE_VAL64_STRING)
7624 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7626 if (hfinfo->display & BASE_UNIT_STRING)
7627 return unit_name_string_get_value(value, (struct unit_name_string*) hfinfo->strings);
7629 return try_val_to_str(value, (const value_string *) hfinfo->strings);
7633 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
7635 if (hfinfo->display & BASE_VAL64_STRING)
7636 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7638 if (hfinfo->display & BASE_RANGE_STRING)
7639 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
7641 if (hfinfo->display & BASE_UNIT_STRING)
7642 return unit_name_string_get_value64(value, (struct unit_name_string*) hfinfo->strings);
7644 /* If this is reached somebody registered a 64-bit field with a 32-bit
7645 * value-string, which isn't right. */
7646 DISSECTOR_ASSERT_NOT_REACHED();
7648 /* This is necessary to squelch MSVC errors; is there
7649 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
7655 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
7657 const char *str = hf_try_val_to_str(value, hfinfo);
7659 return (str) ? str : unknown_str;
7663 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
7665 const char *str = hf_try_val64_to_str(value, hfinfo);
7667 return (str) ? str : unknown_str;
7670 /* Fills data for bitfield chars with val_strings */
7672 fill_label_bitfield_char(field_info *fi, gchar *label_str)
7675 int bitfield_byte_length, bitwidth;
7676 guint32 unshifted_value;
7682 header_field_info *hfinfo = fi->hfinfo;
7684 /* Figure out the bit width */
7685 bitwidth = hfinfo_container_bitwidth(hfinfo);
7688 value = fvalue_get_uinteger(&fi->value);
7690 unshifted_value = value;
7691 if (hfinfo->bitmask) {
7692 unshifted_value <<= hfinfo_bitshift(hfinfo);
7695 /* Create the bitfield first */
7696 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7697 bitfield_byte_length = (int) (p - label_str);
7699 /* Fill in the textual info using stored (shifted) value */
7700 if (hfinfo->display == BASE_CUSTOM) {
7701 gchar tmp[ITEM_LABEL_LENGTH];
7702 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7704 DISSECTOR_ASSERT(fmtfunc);
7705 fmtfunc(tmp, value);
7706 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7708 else if (hfinfo->strings) {
7709 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7711 out = hfinfo_char_vals_format(hfinfo, buf, value);
7712 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7713 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7715 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7718 out = hfinfo_char_value_format(hfinfo, buf, value);
7720 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7724 /* Fills data for bitfield ints with val_strings */
7726 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
7729 int bitfield_byte_length, bitwidth;
7730 guint32 unshifted_value;
7736 header_field_info *hfinfo = fi->hfinfo;
7738 /* Figure out the bit width */
7739 bitwidth = hfinfo_container_bitwidth(hfinfo);
7743 value = fvalue_get_sinteger(&fi->value);
7745 value = fvalue_get_uinteger(&fi->value);
7747 unshifted_value = value;
7748 if (hfinfo->bitmask) {
7749 unshifted_value <<= hfinfo_bitshift(hfinfo);
7752 /* Create the bitfield first */
7753 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7754 bitfield_byte_length = (int) (p - label_str);
7756 /* Fill in the textual info using stored (shifted) value */
7757 if (hfinfo->display == BASE_CUSTOM) {
7758 gchar tmp[ITEM_LABEL_LENGTH];
7759 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7761 DISSECTOR_ASSERT(fmtfunc);
7762 fmtfunc(tmp, value);
7763 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7765 else if (hfinfo->strings) {
7766 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7768 out = hfinfo_number_vals_format(hfinfo, buf, value);
7769 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7770 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7772 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7775 out = hfinfo_number_value_format(hfinfo, buf, value);
7777 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7782 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
7785 int bitfield_byte_length, bitwidth;
7786 guint64 unshifted_value;
7792 header_field_info *hfinfo = fi->hfinfo;
7794 /* Figure out the bit width */
7795 bitwidth = hfinfo_container_bitwidth(hfinfo);
7799 value = fvalue_get_sinteger64(&fi->value);
7801 value = fvalue_get_uinteger64(&fi->value);
7803 unshifted_value = value;
7804 if (hfinfo->bitmask) {
7805 unshifted_value <<= hfinfo_bitshift(hfinfo);
7808 /* Create the bitfield first */
7809 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7810 bitfield_byte_length = (int) (p - label_str);
7812 /* Fill in the textual info using stored (shifted) value */
7813 if (hfinfo->display == BASE_CUSTOM) {
7814 gchar tmp[ITEM_LABEL_LENGTH];
7815 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7817 DISSECTOR_ASSERT(fmtfunc64);
7818 fmtfunc64(tmp, value);
7819 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7821 else if (hfinfo->strings) {
7822 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7824 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7825 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7826 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7828 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7831 out = hfinfo_number_value_format64(hfinfo, buf, value);
7833 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7838 fill_label_char(field_info *fi, gchar *label_str)
7840 header_field_info *hfinfo = fi->hfinfo;
7846 value = fvalue_get_uinteger(&fi->value);
7848 /* Fill in the textual info */
7849 if (hfinfo->display == BASE_CUSTOM) {
7850 gchar tmp[ITEM_LABEL_LENGTH];
7851 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7853 DISSECTOR_ASSERT(fmtfunc);
7854 fmtfunc(tmp, value);
7855 label_fill(label_str, 0, hfinfo, tmp);
7857 else if (hfinfo->strings) {
7858 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7860 out = hfinfo_char_vals_format(hfinfo, buf, value);
7861 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7864 out = hfinfo_char_value_format(hfinfo, buf, value);
7866 label_fill(label_str, 0, hfinfo, out);
7871 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
7873 header_field_info *hfinfo = fi->hfinfo;
7880 value = fvalue_get_sinteger(&fi->value);
7882 value = fvalue_get_uinteger(&fi->value);
7884 /* Fill in the textual info */
7885 if (hfinfo->display == BASE_CUSTOM) {
7886 gchar tmp[ITEM_LABEL_LENGTH];
7887 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7889 DISSECTOR_ASSERT(fmtfunc);
7890 fmtfunc(tmp, value);
7891 label_fill(label_str, 0, hfinfo, tmp);
7893 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7895 * It makes no sense to have a value-string table for a
7896 * frame-number field - they're just integers giving
7897 * the ordinal frame number.
7899 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7901 out = hfinfo_number_vals_format(hfinfo, buf, value);
7902 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7903 label_fill(label_str, 0, hfinfo, val_str);
7905 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7907 else if (IS_BASE_PORT(hfinfo->display)) {
7908 gchar tmp[ITEM_LABEL_LENGTH];
7910 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
7911 display_to_port_type((field_display_e)hfinfo->display), value);
7912 label_fill(label_str, 0, hfinfo, tmp);
7915 out = hfinfo_number_value_format(hfinfo, buf, value);
7917 label_fill(label_str, 0, hfinfo, out);
7922 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
7924 header_field_info *hfinfo = fi->hfinfo;
7931 value = fvalue_get_sinteger64(&fi->value);
7933 value = fvalue_get_uinteger64(&fi->value);
7935 /* Fill in the textual info */
7936 if (hfinfo->display == BASE_CUSTOM) {
7937 gchar tmp[ITEM_LABEL_LENGTH];
7938 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7940 DISSECTOR_ASSERT(fmtfunc64);
7941 fmtfunc64(tmp, value);
7942 label_fill(label_str, 0, hfinfo, tmp);
7944 else if (hfinfo->strings) {
7945 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7947 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7948 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7949 label_fill(label_str, 0, hfinfo, val_str);
7951 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7954 out = hfinfo_number_value_format64(hfinfo, buf, value);
7956 label_fill(label_str, 0, hfinfo, out);
7961 hfinfo_bitshift(const header_field_info *hfinfo)
7963 return ws_ctz(hfinfo->bitmask);
7967 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
7969 if (!hfinfo->bitmask) {
7973 /* ilog2 = first set bit, ctz = last set bit */
7974 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
7978 hfinfo_type_bitwidth(enum ftenum type)
8017 DISSECTOR_ASSERT_NOT_REACHED();
8025 hfinfo_container_bitwidth(const header_field_info *hfinfo)
8027 if (!hfinfo->bitmask) {
8031 if (hfinfo->type == FT_BOOLEAN) {
8032 return hfinfo->display; /* hacky? :) */
8035 return hfinfo_type_bitwidth(hfinfo->type);
8039 hfinfo_hex_digits(const header_field_info *hfinfo)
8043 /* If we have a bitmask, hfinfo->type is the width of the container, so not
8044 * appropriate to determine the number of hex digits for the field.
8045 * So instead, we compute it from the bitmask.
8047 if (hfinfo->bitmask != 0) {
8048 bitwidth = hfinfo_mask_bitwidth(hfinfo);
8050 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
8053 /* Divide by 4, rounding up, to get number of hex digits. */
8054 return (bitwidth + 3) / 4;
8058 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
8060 char *ptr = &buf[6];
8061 static const gchar hex_digits[16] =
8062 { '0', '1', '2', '3', '4', '5', '6', '7',
8063 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
8067 /* Properly format value */
8068 if (g_ascii_isprint(value)) {
8070 * Printable, so just show the character, and, if it needs
8071 * to be escaped, escape it.
8074 if (value == '\\' || value == '\'')
8078 * Non-printable; show it as an escape sequence.
8084 * Show a NUL with only one digit.
8118 switch (display & FIELD_DISPLAY_E_MASK) {
8121 *(--ptr) = (value & 0x7) + '0';
8123 *(--ptr) = (value & 0x7) + '0';
8125 *(--ptr) = (value & 0x7) + '0';
8129 *(--ptr) = hex_digits[value & 0x0F];
8131 *(--ptr) = hex_digits[value & 0x0F];
8136 g_assert_not_reached();
8146 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
8148 char *ptr = &buf[31];
8149 gboolean isint = IS_FT_INT(hfinfo->type);
8152 /* Properly format value */
8153 switch (display & FIELD_DISPLAY_E_MASK) {
8155 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8159 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8162 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8166 return oct_to_str_back(ptr, value);
8169 return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8173 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8176 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8183 port_with_resolution_to_str_buf(buf, 32,
8184 display_to_port_type((field_display_e)display), value);
8188 g_assert_not_reached();
8194 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
8196 char *ptr = &buf[47];
8197 gboolean isint = IS_FT_INT(hfinfo->type);
8200 /* Properly format value */
8203 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8207 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8210 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8214 return oct64_to_str_back(ptr, value);
8217 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8221 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8224 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8228 g_assert_not_reached();
8234 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8236 int display = hfinfo->display;
8238 if (hfinfo->type == FT_FRAMENUM) {
8240 * Frame numbers are always displayed in decimal.
8245 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8249 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8251 int display = hfinfo->display;
8253 if (hfinfo->type == FT_FRAMENUM) {
8255 * Frame numbers are always displayed in decimal.
8260 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8264 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8266 /* Get the underlying BASE_ value */
8267 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8269 return hfinfo_char_value_format_display(display, buf, value);
8273 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8275 /* Get the underlying BASE_ value */
8276 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8278 if (hfinfo->type == FT_FRAMENUM) {
8280 * Frame numbers are always displayed in decimal.
8285 if (IS_BASE_PORT(display)) {
8291 /* case BASE_DEC: */
8293 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
8298 /* case BASE_HEX: */
8304 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8308 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8310 /* Get the underlying BASE_ value */
8311 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8313 if (hfinfo->type == FT_FRAMENUM) {
8315 * Frame numbers are always displayed in decimal.
8322 /* case BASE_DEC: */
8324 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
8329 /* case BASE_HEX: */
8335 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8339 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8341 /* Get the underlying BASE_ value */
8342 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8344 return hfinfo_char_value_format_display(display, buf, value);
8348 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8350 /* Get the underlying BASE_ value */
8351 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8353 if (display == BASE_NONE)
8356 if (display == BASE_DEC_HEX)
8358 if (display == BASE_HEX_DEC)
8361 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8365 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8367 /* Get the underlying BASE_ value */
8368 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8370 if (display == BASE_NONE)
8373 if (display == BASE_DEC_HEX)
8375 if (display == BASE_HEX_DEC)
8378 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8382 proto_registrar_get_name(const int n)
8384 header_field_info *hfinfo;
8386 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8387 return hfinfo->name;
8391 proto_registrar_get_abbrev(const int n)
8393 header_field_info *hfinfo;
8395 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8396 return hfinfo->abbrev;
8400 proto_registrar_get_ftype(const int n)
8402 header_field_info *hfinfo;
8404 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8405 return hfinfo->type;
8409 proto_registrar_get_parent(const int n)
8411 header_field_info *hfinfo;
8413 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8414 return hfinfo->parent;
8418 proto_registrar_is_protocol(const int n)
8420 header_field_info *hfinfo;
8422 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8423 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
8426 /* Returns length of field in packet (not necessarily the length
8427 * in our internal representation, as in the case of IPv4).
8428 * 0 means undeterminable at time of registration
8429 * -1 means the field is not registered. */
8431 proto_registrar_get_length(const int n)
8433 header_field_info *hfinfo;
8435 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8436 return ftype_length(hfinfo->type);
8439 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
8440 * it exists anywhere, or FALSE if it exists nowhere. */
8442 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
8444 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
8446 if (g_ptr_array_len(ptrs) > 0) {
8454 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
8455 * This only works if the hfindex was "primed" before the dissection
8456 * took place, as we just pass back the already-created GPtrArray*.
8457 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
8460 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
8465 if (PTREE_DATA(tree)->interesting_hfids != NULL)
8466 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
8467 GINT_TO_POINTER(id));
8473 proto_tracking_interesting_fields(const proto_tree *tree)
8475 GHashTable *interesting_hfids;
8480 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
8482 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
8485 /* Helper struct for proto_find_info() and proto_all_finfos() */
8491 /* Helper function for proto_find_info() */
8493 find_finfo(proto_node *node, gpointer data)
8495 field_info *fi = PNODE_FINFO(node);
8496 if (fi && fi->hfinfo) {
8497 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8498 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8502 /* Don't stop traversing. */
8506 /* Helper function for proto_find_first_info() */
8508 find_first_finfo(proto_node *node, gpointer data)
8510 field_info *fi = PNODE_FINFO(node);
8511 if (fi && fi->hfinfo) {
8512 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8513 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8517 /* Stop traversing. */
8521 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
8522 * This works on any proto_tree, primed or unprimed, but actually searches
8523 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8524 * The caller does need to free the returned GPtrArray with
8525 * g_ptr_array_free(<array>, TRUE).
8528 proto_find_finfo(proto_tree *tree, const int id)
8532 ffdata.array = g_ptr_array_new();
8535 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
8537 return ffdata.array;
8540 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
8541 * This works on any proto_tree, primed or unprimed, but actually searches
8542 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8543 * The caller does need to free the returned GPtrArray with
8544 * g_ptr_array_free(<array>, TRUE).
8547 proto_find_first_finfo(proto_tree *tree, const int id)
8551 ffdata.array = g_ptr_array_new();
8554 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
8556 return ffdata.array;
8559 /* Helper function for proto_all_finfos() */
8561 every_finfo(proto_node *node, gpointer data)
8563 field_info *fi = PNODE_FINFO(node);
8564 if (fi && fi->hfinfo) {
8565 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8568 /* Don't stop traversing. */
8572 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
8574 proto_all_finfos(proto_tree *tree)
8578 /* Pre allocate enough space to hold all fields in most cases */
8579 ffdata.array = g_ptr_array_sized_new(512);
8582 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
8584 return ffdata.array;
8595 check_for_offset(proto_node *node, gpointer data)
8597 field_info *fi = PNODE_FINFO(node);
8598 offset_search_t *offsearch = (offset_search_t *)data;
8600 /* !fi == the top most container node which holds nothing */
8601 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
8602 if (offsearch->offset >= (guint) fi->start &&
8603 offsearch->offset < (guint) (fi->start + fi->length)) {
8605 offsearch->finfo = fi;
8606 return FALSE; /* keep traversing */
8609 return FALSE; /* keep traversing */
8612 /* Search a proto_tree backwards (from leaves to root) looking for the field
8613 * whose start/length occupies 'offset' */
8614 /* XXX - I couldn't find an easy way to search backwards, so I search
8615 * forwards, w/o stopping. Therefore, the last finfo I find will the be
8616 * the one I want to return to the user. This algorithm is inefficient
8617 * and could be re-done, but I'd have to handle all the children and
8618 * siblings of each node myself. When I have more time I'll do that.
8621 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
8623 offset_search_t offsearch;
8625 offsearch.offset = offset;
8626 offsearch.finfo = NULL;
8627 offsearch.tvb = tvb;
8629 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
8631 return offsearch.finfo;
8636 check_for_undecoded(proto_node *node, gpointer data)
8638 field_info *fi = PNODE_FINFO(node);
8639 gchar* decoded = (gchar*)data;
8644 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
8645 for (i = fi->start; i < fi->start + fi->length; i++) {
8648 decoded[byte] |= (1 << bit);
8656 proto_find_undecoded_data(proto_tree *tree, guint length)
8658 gchar* decoded = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
8660 proto_tree_traverse_pre_order(tree, check_for_undecoded, decoded);
8664 /* Dumps the protocols in the registration database to stdout. An independent
8665 * program can take this output and format it into nice tables or HTML or
8668 * There is one record per line. The fields are tab-delimited.
8670 * Field 1 = protocol name
8671 * Field 2 = protocol short name
8672 * Field 3 = protocol filter name
8675 proto_registrar_dump_protocols(void)
8677 protocol_t *protocol;
8679 void *cookie = NULL;
8682 i = proto_get_first_protocol(&cookie);
8684 protocol = find_protocol_by_id(i);
8685 ws_debug_printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
8686 protocol->filter_name);
8687 i = proto_get_next_protocol(&cookie);
8691 /* Dumps the value_strings, extended value string headers, range_strings
8692 * or true/false strings for fields that have them.
8693 * There is one record per line. Fields are tab-delimited.
8694 * There are four types of records: Value String, Extended Value String Header,
8695 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
8696 * the type of record.
8698 * Note that a record will be generated only if the value_string,... is referenced
8699 * in a registered hfinfo entry.
8705 * Field 2 = Field abbreviation to which this value string corresponds
8706 * Field 3 = Integer value
8709 * Extended Value String Headers
8710 * -----------------------------
8712 * Field 2 = Field abbreviation to which this extended value string header corresponds
8713 * Field 3 = Extended Value String "Name"
8714 * Field 4 = Number of entries in the associated value_string array
8715 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
8720 * Field 2 = Field abbreviation to which this range string corresponds
8721 * Field 3 = Integer value: lower bound
8722 * Field 4 = Integer value: upper bound
8725 * True/False Strings
8726 * ------------------
8728 * Field 2 = Field abbreviation to which this true/false string corresponds
8729 * Field 3 = True String
8730 * Field 4 = False String
8733 proto_registrar_dump_values(void)
8735 header_field_info *hfinfo;
8737 const value_string *vals;
8738 const val64_string *vals64;
8739 const range_string *range;
8740 const true_false_string *tfs;
8741 const unit_name_string *units;
8743 len = gpa_hfinfo.len;
8744 for (i = 0; i < len ; i++) {
8745 if (gpa_hfinfo.hfi[i] == NULL)
8746 continue; /* This is a deregistered protocol or field */
8748 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8750 if (hfinfo->id == hf_text_only) {
8754 /* ignore protocols */
8755 if (proto_registrar_is_protocol(i)) {
8758 /* process header fields */
8759 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
8761 * If this field isn't at the head of the list of
8762 * fields with this name, skip this field - all
8763 * fields with the same name are really just versions
8764 * of the same field stored in different bits, and
8765 * should have the same type/radix/value list, and
8766 * just differ in their bit masks. (If a field isn't
8767 * a bitfield, but can be, say, 1 or 2 bytes long,
8768 * it can just be made FT_UINT16, meaning the
8769 * *maximum* length is 2 bytes, and be used
8772 if (hfinfo->same_name_prev_id != -1)
8781 if (hfinfo->strings != NULL) {
8782 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) != BASE_CUSTOM &&
8783 (hfinfo->type == FT_CHAR ||
8784 hfinfo->type == FT_UINT8 ||
8785 hfinfo->type == FT_UINT16 ||
8786 hfinfo->type == FT_UINT24 ||
8787 hfinfo->type == FT_UINT32 ||
8788 hfinfo->type == FT_UINT40 ||
8789 hfinfo->type == FT_UINT48 ||
8790 hfinfo->type == FT_UINT56 ||
8791 hfinfo->type == FT_UINT64 ||
8792 hfinfo->type == FT_INT8 ||
8793 hfinfo->type == FT_INT16 ||
8794 hfinfo->type == FT_INT24 ||
8795 hfinfo->type == FT_INT32 ||
8796 hfinfo->type == FT_INT40 ||
8797 hfinfo->type == FT_INT48 ||
8798 hfinfo->type == FT_INT56 ||
8799 hfinfo->type == FT_INT64)) {
8801 if (hfinfo->display & BASE_RANGE_STRING) {
8802 range = (const range_string *)hfinfo->strings;
8803 } else if (hfinfo->display & BASE_EXT_STRING) {
8804 vals = VALUE_STRING_EXT_VS_P((value_string_ext *)hfinfo->strings);
8805 } else if (hfinfo->display & BASE_VAL64_STRING) {
8806 vals64 = (const val64_string *)hfinfo->strings;
8807 } else if (hfinfo->display & BASE_UNIT_STRING) {
8808 units = (const unit_name_string *)hfinfo->strings;
8810 vals = (const value_string *)hfinfo->strings;
8813 else if (hfinfo->type == FT_BOOLEAN) {
8814 tfs = (const struct true_false_string *)hfinfo->strings;
8818 /* Print value strings? */
8820 if (hfinfo->display & BASE_EXT_STRING) {
8821 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
8822 if (!value_string_ext_validate(vse_p)) {
8823 ws_g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
8826 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
8827 ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
8829 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
8830 VALUE_STRING_EXT_VS_NAME(vse_p),
8831 value_string_ext_match_type_str(vse_p));
8834 while (vals[vi].strptr) {
8835 /* Print in the proper base */
8836 if (hfinfo->type == FT_CHAR) {
8837 if (g_ascii_isprint(vals[vi].value)) {
8838 ws_debug_printf("V\t%s\t'%c'\t%s\n",
8843 if (hfinfo->display == BASE_HEX) {
8844 ws_debug_printf("V\t%s\t'\\x%02x'\t%s\n",
8850 ws_debug_printf("V\t%s\t'\\%03o'\t%s\n",
8857 if (hfinfo->display == BASE_HEX) {
8858 ws_debug_printf("V\t%s\t0x%x\t%s\n",
8864 ws_debug_printf("V\t%s\t%u\t%s\n",
8875 while (vals64[vi].strptr) {
8876 ws_debug_printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
8884 /* print range strings? */
8887 while (range[vi].strptr) {
8888 /* Print in the proper base */
8889 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_HEX) {
8890 ws_debug_printf("R\t%s\t0x%x\t0x%x\t%s\n",
8892 range[vi].value_min,
8893 range[vi].value_max,
8897 ws_debug_printf("R\t%s\t%u\t%u\t%s\n",
8899 range[vi].value_min,
8900 range[vi].value_max,
8907 /* Print true/false strings? */
8909 ws_debug_printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
8910 tfs->true_string, tfs->false_string);
8912 /* Print unit strings? */
8914 ws_debug_printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
8915 units->singular, units->plural ? units->plural : "(no plural)");
8920 /* Prints the number of registered fields.
8921 * Useful for determining an appropriate value for
8922 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
8924 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
8925 * the number of fields, TRUE otherwise.
8928 proto_registrar_dump_fieldcount(void)
8931 header_field_info *hfinfo;
8932 guint32 deregistered_count = 0;
8933 guint32 same_name_count = 0;
8934 guint32 protocol_count = 0;
8936 for (i = 0; i < gpa_hfinfo.len; i++) {
8937 if (gpa_hfinfo.hfi[i] == NULL) {
8938 deregistered_count++;
8939 continue; /* This is a deregistered protocol or header field */
8942 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8944 if (proto_registrar_is_protocol(i))
8947 if (hfinfo->same_name_prev_id != -1)
8951 ws_debug_printf("There are %u header fields registered, of which:\n"
8952 "\t%u are deregistered\n"
8953 "\t%u are protocols\n"
8954 "\t%u have the same name as another field\n\n",
8955 gpa_hfinfo.len, deregistered_count, protocol_count,
8958 ws_debug_printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
8959 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
8960 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
8963 ws_debug_printf("The header field table consumes %u KiB of memory.\n",
8964 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
8965 ws_debug_printf("The fields themselves consume %u KiB of memory.\n",
8966 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
8968 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8972 /* Dumps the contents of the registration database to stdout. An independent
8973 * program can take this output and format it into nice tables or HTML or
8976 * There is one record per line. Each record is either a protocol or a header
8977 * field, differentiated by the first field. The fields are tab-delimited.
8982 * Field 2 = descriptive protocol name
8983 * Field 3 = protocol abbreviation
8988 * Field 2 = descriptive field name
8989 * Field 3 = field abbreviation
8990 * Field 4 = type ( textual representation of the the ftenum type )
8991 * Field 5 = parent protocol abbreviation
8992 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
8993 * Field 7 = bitmask: format: hex: 0x....
8994 * Field 8 = blurb describing field
8997 proto_registrar_dump_fields(void)
8999 header_field_info *hfinfo, *parent_hfinfo;
9001 const char *enum_name;
9002 const char *base_name;
9006 len = gpa_hfinfo.len;
9007 for (i = 0; i < len ; i++) {
9008 if (gpa_hfinfo.hfi[i] == NULL)
9009 continue; /* This is a deregistered protocol or header field */
9011 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
9014 * Skip the pseudo-field for "proto_tree_add_text()" since
9015 * we don't want it in the list of filterable fields.
9017 if (hfinfo->id == hf_text_only)
9020 /* format for protocols */
9021 if (proto_registrar_is_protocol(i)) {
9022 ws_debug_printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
9024 /* format for header fields */
9027 * If this field isn't at the head of the list of
9028 * fields with this name, skip this field - all
9029 * fields with the same name are really just versions
9030 * of the same field stored in different bits, and
9031 * should have the same type/radix/value list, and
9032 * just differ in their bit masks. (If a field isn't
9033 * a bitfield, but can be, say, 1 or 2 bytes long,
9034 * it can just be made FT_UINT16, meaning the
9035 * *maximum* length is 2 bytes, and be used
9038 if (hfinfo->same_name_prev_id != -1)
9041 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
9043 enum_name = ftype_name(hfinfo->type);
9046 if (hfinfo->type == FT_CHAR ||
9047 hfinfo->type == FT_UINT8 ||
9048 hfinfo->type == FT_UINT16 ||
9049 hfinfo->type == FT_UINT24 ||
9050 hfinfo->type == FT_UINT32 ||
9051 hfinfo->type == FT_UINT40 ||
9052 hfinfo->type == FT_UINT48 ||
9053 hfinfo->type == FT_UINT56 ||
9054 hfinfo->type == FT_UINT64 ||
9055 hfinfo->type == FT_INT8 ||
9056 hfinfo->type == FT_INT16 ||
9057 hfinfo->type == FT_INT24 ||
9058 hfinfo->type == FT_INT32 ||
9059 hfinfo->type == FT_INT40 ||
9060 hfinfo->type == FT_INT48 ||
9061 hfinfo->type == FT_INT56 ||
9062 hfinfo->type == FT_INT64) {
9064 switch (FIELD_DISPLAY(hfinfo->display)) {
9076 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
9082 } else if (hfinfo->type == FT_BOOLEAN) {
9083 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
9084 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
9088 blurb = hfinfo->blurb;
9091 else if (strlen(blurb) == 0)
9094 ws_debug_printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
9095 hfinfo->name, hfinfo->abbrev, enum_name,
9096 parent_hfinfo->abbrev, base_name,
9097 hfinfo->bitmask, blurb);
9102 /* Dumps field types and descriptive names to stdout. An independent
9103 * program can take this output and format it into nice tables or HTML or
9106 * There is one record per line. The fields are tab-delimited.
9108 * Field 1 = field type name, e.g. FT_UINT8
9109 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
9112 proto_registrar_dump_ftypes(void)
9116 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
9117 ws_debug_printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
9121 /* This function indicates whether it's possible to construct a
9122 * "match selected" display filter string for the specified field,
9123 * returns an indication of whether it's possible, and, if it's
9124 * possible and "filter" is non-null, constructs the filter and
9125 * sets "*filter" to point to it.
9126 * You do not need to [g_]free() this string since it will be automatically
9127 * freed once the next packet is dissected.
9130 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
9133 header_field_info *hfinfo;
9138 gint start, length, length_remaining;
9140 gchar is_signed_num = FALSE;
9145 hfinfo = finfo->hfinfo;
9146 DISSECTOR_ASSERT(hfinfo);
9147 abbrev_len = (int) strlen(hfinfo->abbrev);
9149 if (hfinfo->strings && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
9150 const gchar *str = NULL;
9152 switch (hfinfo->type) {
9158 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
9166 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
9173 if (str != NULL && filter != NULL) {
9174 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
9180 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
9181 * functions for FT_UINT and FT_INT types, as we choose the base in
9182 * the string expression based on the display base of the field.
9184 * Note that the base does matter, as this is also used for
9185 * the protocolinfo tap.
9187 * It might be nice to use them in "proto_item_fill_label()"
9188 * as well, although, there, you'd have to deal with the base
9189 * *and* with resolved values for addresses.
9191 * Perhaps we need two different val_to_string routines, one
9192 * to generate items for display filters and one to generate
9193 * strings for display, and pass to both of them the
9194 * "display" and "strings" values in the header_field_info
9195 * structure for the field, so they can get the base and,
9196 * if the field is Boolean or an enumerated integer type,
9197 * the tables used to generate human-readable values.
9199 switch (hfinfo->type) {
9202 if (filter != NULL) {
9208 number = fvalue_get_uinteger(&finfo->value);
9210 out = hfinfo_char_value_format(hfinfo, buf, number);
9212 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9220 is_signed_num = TRUE;
9227 if (filter != NULL) {
9234 number = fvalue_get_sinteger(&finfo->value);
9236 number = fvalue_get_uinteger(&finfo->value);
9238 out = hfinfo_numeric_value_format(hfinfo, buf, number);
9240 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9248 is_signed_num = TRUE;
9254 if (filter != NULL) {
9261 number = fvalue_get_sinteger64(&finfo->value);
9263 number = fvalue_get_uinteger64(&finfo->value);
9265 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
9267 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9273 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
9278 * If the length is 0, just match the name of the
9281 * (Also check for negative values, just in case,
9282 * as we'll cast it to an unsigned value later.)
9284 length = finfo->length;
9287 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
9294 * This doesn't have a value, so we'd match
9295 * on the raw bytes at this address.
9297 * Should we be allowed to access to the raw bytes?
9298 * If "edt" is NULL, the answer is "no".
9304 * Is this field part of the raw frame tvbuff?
9305 * If not, we can't use "frame[N:M]" to match
9308 * XXX - should this be frame-relative, or
9309 * protocol-relative?
9311 * XXX - does this fallback for non-registered
9312 * fields even make sense?
9314 if (finfo->ds_tvb != edt->tvb)
9315 return FALSE; /* you lose */
9318 * Don't go past the end of that tvbuff.
9320 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
9321 if (length > length_remaining)
9322 length = length_remaining;
9326 if (filter != NULL) {
9327 start = finfo->start;
9328 buf_len = 32 + length * 3;
9329 *filter = (char *)wmem_alloc0(NULL, buf_len);
9332 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
9333 "frame[%d:%d] == ", finfo->start, length);
9334 for (i=0; i<length; i++) {
9335 c = tvb_get_guint8(finfo->ds_tvb, start);
9338 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
9341 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
9348 /* FT_PCRE never appears as a type for a registered field. It is
9349 * only used internally. */
9350 DISSECTOR_ASSERT_NOT_REACHED();
9353 /* By default, use the fvalue's "to_string_repr" method. */
9355 /* Figure out the string length needed.
9356 * The ft_repr length.
9357 * 4 bytes for " == ".
9358 * 1 byte for trailing NUL.
9360 if (filter != NULL) {
9362 dfilter_len = fvalue_string_repr_len(&finfo->value,
9363 FTREPR_DFILTER, finfo->hfinfo->display);
9364 dfilter_len += abbrev_len + 4 + 1;
9365 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
9367 /* Create the string */
9368 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
9369 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
9370 wmem_free(NULL, str);
9379 * Returns TRUE if we can do a "match selected" on the field, FALSE
9383 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
9385 return construct_match_selected_string(finfo, edt, NULL);
9388 /* This function attempts to construct a "match selected" display filter
9389 * string for the specified field; if it can do so, it returns a pointer
9390 * to the string, otherwise it returns NULL.
9392 * The string is allocated with packet lifetime scope.
9393 * You do not need to [g_]free() this string since it will be automatically
9394 * freed once the next packet is dissected.
9397 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
9399 char *filter = NULL;
9401 if (!construct_match_selected_string(finfo, edt, &filter))
9403 wmem_free(NULL, filter);
9409 /* This function is common code for all proto_tree_add_bitmask... functions.
9413 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
9414 const int len, const gint ett, const int **fields,
9415 const int flags, gboolean first,
9416 gboolean use_parent_tree,
9417 proto_tree* tree, guint64 value)
9420 guint64 available_bits = 0;
9422 header_field_info *hf;
9426 if (len < 0 || len > 8)
9427 g_assert_not_reached();
9428 bitshift = (8 - (guint)len)*8;
9429 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
9431 if (use_parent_tree == FALSE)
9432 tree = proto_item_add_subtree(item, ett);
9435 guint64 present_bits;
9436 PROTO_REGISTRAR_GET_NTH(**fields,hf);
9437 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
9439 /* Skip fields that aren't fully present */
9440 present_bits = available_bits & hf->bitmask;
9441 if (present_bits != hf->bitmask) {
9452 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
9459 proto_tree_add_int(tree, **fields, tvb, offset, len, (gint32)value);
9466 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
9473 proto_tree_add_int64(tree, **fields, tvb, offset, len, (gint64)value);
9477 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
9481 DISSECTOR_ASSERT_NOT_REACHED();
9484 if (flags & BMT_NO_APPEND) {
9488 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
9492 if (hf->display == BASE_CUSTOM) {
9493 gchar lbl[ITEM_LABEL_LENGTH];
9494 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9496 DISSECTOR_ASSERT(fmtfunc);
9497 fmtfunc(lbl, (guint32) tmpval);
9498 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9502 else if (hf->strings) {
9503 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9504 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
9507 else if (!(flags & BMT_NO_INT)) {
9512 proto_item_append_text(item, ", ");
9515 out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
9516 proto_item_append_text(item, "%s: %s", hf->name, out);
9526 if (hf->display == BASE_CUSTOM) {
9527 gchar lbl[ITEM_LABEL_LENGTH];
9528 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9530 DISSECTOR_ASSERT(fmtfunc);
9531 fmtfunc(lbl, (guint32) tmpval);
9532 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9536 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
9537 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9538 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
9541 else if (!(flags & BMT_NO_INT)) {
9546 proto_item_append_text(item, ", ");
9549 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
9550 if (hf->display & BASE_UNIT_STRING) {
9551 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (unit_name_string*)hf->strings));
9553 proto_item_append_text(item, "%s: %s", hf->name, out);
9564 integer32 = (guint32) tmpval;
9566 no_of_bits = ws_count_ones(hf->bitmask);
9567 integer32 = ws_sign_ext32(integer32, no_of_bits);
9569 if (hf->display == BASE_CUSTOM) {
9570 gchar lbl[ITEM_LABEL_LENGTH];
9571 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9573 DISSECTOR_ASSERT(fmtfunc);
9574 fmtfunc(lbl, (gint32) integer32);
9575 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9579 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
9580 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9581 hf->name, hf_try_val_to_str_const((gint32) integer32, hf, "Unknown"));
9584 else if (!(flags & BMT_NO_INT)) {
9589 proto_item_append_text(item, ", ");
9592 out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
9593 if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
9594 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (unit_name_string*)hf->strings));
9596 proto_item_append_text(item, "%s: %s", hf->name, out);
9607 if (hf->display == BASE_CUSTOM) {
9608 gchar lbl[ITEM_LABEL_LENGTH];
9609 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
9611 DISSECTOR_ASSERT(fmtfunc);
9612 fmtfunc(lbl, tmpval);
9613 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9617 else if (hf->strings) {
9618 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9619 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
9622 else if (!(flags & BMT_NO_INT)) {
9627 proto_item_append_text(item, ", ");
9630 out = hfinfo_number_value_format64(hf, buf, tmpval);
9631 proto_item_append_text(item, "%s: %s", hf->name, out);
9642 no_of_bits = ws_count_ones(hf->bitmask);
9643 tmpval = ws_sign_ext64(tmpval, no_of_bits);
9645 if (hf->display == BASE_CUSTOM) {
9646 gchar lbl[ITEM_LABEL_LENGTH];
9647 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
9649 DISSECTOR_ASSERT(fmtfunc);
9650 fmtfunc(lbl, (gint64) tmpval);
9651 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9655 else if (hf->strings) {
9656 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9657 hf->name, hf_try_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
9660 else if (!(flags & BMT_NO_INT)) {
9665 proto_item_append_text(item, ", ");
9668 out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
9669 proto_item_append_text(item, "%s: %s", hf->name, out);
9676 if (hf->strings && !(flags & BMT_NO_TFS)) {
9677 /* If we have true/false strings, emit full - otherwise messages
9679 const struct true_false_string *tfs =
9680 (const struct true_false_string *)hf->strings;
9683 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9684 hf->name, tfs->true_string);
9686 } else if (!(flags & BMT_NO_FALSE)) {
9687 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9688 hf->name, tfs->false_string);
9691 } else if (hf->bitmask & value) {
9692 /* If the flag is set, show the name */
9693 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
9698 DISSECTOR_ASSERT_NOT_REACHED();
9708 /* This function will dissect a sequence of bytes that describe a
9709 * bitmask and supply the value of that sequence through a pointer.
9710 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9712 * This field will form an expansion under which the individual fields of the
9713 * bitmask is dissected and displayed.
9714 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9716 * fields is an array of pointers to int that lists all the fields of the
9717 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9718 * or another integer of the same type/size as hf_hdr with a mask specified.
9719 * This array is terminated by a NULL entry.
9721 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9722 * FT_integer fields that have a value_string attached will have the
9723 * matched string displayed on the expansion line.
9726 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
9727 const guint offset, const int hf_hdr,
9728 const gint ett, const int **fields,
9729 const guint encoding, guint64 *retval)
9731 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);
9734 /* This function will dissect a sequence of bytes that describe a
9736 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9738 * This field will form an expansion under which the individual fields of the
9739 * bitmask is dissected and displayed.
9740 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9742 * fields is an array of pointers to int that lists all the fields of the
9743 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9744 * or another integer of the same type/size as hf_hdr with a mask specified.
9745 * This array is terminated by a NULL entry.
9747 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9748 * FT_integer fields that have a value_string attached will have the
9749 * matched string displayed on the expansion line.
9752 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
9753 const guint offset, const int hf_hdr,
9754 const gint ett, const int **fields,
9755 const guint encoding)
9757 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
9760 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9761 * what data is appended to the header.
9764 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9765 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
9768 proto_item *item = NULL;
9769 header_field_info *hf;
9773 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9774 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9775 len = ftype_length(hf->type);
9776 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9779 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9780 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9781 flags, FALSE, FALSE, NULL, value);
9786 /* Mask out irrelevant portions */
9787 *retval &= hf->bitmask;
9789 *retval >>= hfinfo_bitshift(hf);
9795 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9796 * what data is appended to the header.
9799 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9800 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
9802 proto_item *item = NULL;
9803 header_field_info *hf;
9807 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9808 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9811 len = ftype_length(hf->type);
9812 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9813 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9814 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9815 flags, FALSE, FALSE, NULL, value);
9821 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
9822 can't be retrieved directly from tvb) */
9824 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9825 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
9827 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
9828 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
9831 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
9832 WS_DLL_PUBLIC proto_item *
9833 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9834 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
9836 proto_item *item = NULL;
9837 header_field_info *hf;
9840 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9841 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9842 /* the proto_tree_add_uint/_uint64() calls below
9843 will fail if tvb==NULL and len!=0 */
9844 len = tvb ? ftype_length(hf->type) : 0;
9848 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
9850 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
9852 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9853 flags, FALSE, FALSE, NULL, value);
9859 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
9861 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9862 const int len, const int **fields, const guint encoding)
9867 value = get_uint64_value(tree, tvb, offset, len, encoding);
9868 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9869 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9874 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9875 const int len, const int **fields, const guint64 value)
9878 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9879 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9884 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
9885 * This is intended to support bitmask fields whose lengths can vary, perhaps
9886 * as the underlying standard evolves over time.
9887 * With this API there is the possibility of being called to display more or
9888 * less data than the dissector was coded to support.
9889 * In such cases, it is assumed that bitmasks are extended on the MSb end.
9890 * Thus when presented with "too much" or "too little" data, MSbits will be
9891 * ignored or MSfields sacrificed.
9893 * Only fields for which all defined bits are available are displayed.
9896 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
9897 const guint offset, const guint len, const int hf_hdr,
9898 const gint ett, const int **fields, struct expert_field* exp,
9899 const guint encoding)
9901 proto_item *item = NULL;
9902 header_field_info *hf;
9903 guint decodable_len;
9904 guint decodable_offset;
9905 guint32 decodable_value;
9908 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
9909 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9911 decodable_offset = offset;
9912 decodable_len = MIN(len, (guint) ftype_length(hf->type));
9914 /* If we are ftype_length-limited,
9915 * make sure we decode as many LSBs as possible.
9917 if (encoding == ENC_BIG_ENDIAN) {
9918 decodable_offset += (len - decodable_len);
9922 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
9923 decodable_len, encoding);
9925 /* The root item covers all the bytes even if we can't decode them all */
9926 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
9930 if (decodable_len < len) {
9931 /* Dissector likely requires updating for new protocol revision */
9932 expert_add_info_format(NULL, item, exp,
9933 "Only least-significant %d of %d bytes decoded",
9934 decodable_len, len);
9938 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
9939 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
9940 ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
9946 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
9948 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
9949 const guint offset, const guint len,
9950 const char *name, const char *fallback,
9951 const gint ett, const int **fields,
9952 const guint encoding, const int flags)
9954 proto_item *item = NULL;
9958 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
9959 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9960 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9961 flags, TRUE, FALSE, NULL, value) && fallback) {
9962 /* Still at first item - append 'fallback' text if any */
9963 proto_item_append_text(item, "%s", fallback);
9971 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9972 const guint bit_offset, const gint no_of_bits,
9973 const guint encoding)
9975 header_field_info *hfinfo;
9979 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9981 octet_length = (no_of_bits + 7) >> 3;
9982 octet_offset = bit_offset >> 3;
9983 test_length(hfinfo, tvb, octet_offset, octet_length);
9985 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
9986 * but only after doing a bunch more work (which we can, in the common
9987 * case, shortcut here).
9989 CHECK_FOR_NULL_TREE(tree);
9990 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9992 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
9996 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
9997 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
9998 * Offset should be given in bits from the start of the tvb.
10001 static proto_item *
10002 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10003 const guint bit_offset, const gint no_of_bits,
10004 guint64 *return_value, const guint encoding)
10008 guint8 tot_no_bits;
10010 char lbl_str[ITEM_LABEL_LENGTH];
10014 header_field_info *hf_field;
10016 const true_false_string *tfstring;
10018 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
10019 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
10021 if (hf_field->bitmask != 0) {
10022 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10023 "Incompatible use of proto_tree_add_bits_ret_val"
10024 " with field '%s' (%s) with bitmask != 0",
10025 hf_field->abbrev, hf_field->name));
10028 DISSECTOR_ASSERT(no_of_bits > 0);
10030 /* Byte align offset */
10031 offset = bit_offset>>3;
10034 * Calculate the number of octets used to hold the bits
10036 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
10037 length = (tot_no_bits + 7) >> 3;
10039 if (no_of_bits < 65) {
10040 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
10042 DISSECTOR_ASSERT_NOT_REACHED();
10046 /* Sign extend for signed types */
10047 switch (hf_field->type) {
10056 value = ws_sign_ext64(value, no_of_bits);
10063 if (return_value) {
10064 *return_value = value;
10067 /* Coast clear. Try and fake it */
10068 CHECK_FOR_NULL_TREE(tree);
10069 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10071 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
10073 switch (hf_field->type) {
10075 /* Boolean field */
10076 tfstring = (const true_false_string *) &tfs_true_false;
10077 if (hf_field->strings)
10078 tfstring = (const true_false_string *)hf_field->strings;
10079 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
10081 bf_str, hf_field->name,
10082 (guint64)value ? tfstring->true_string : tfstring->false_string);
10086 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
10087 fill_label_char(PITEM_FINFO(pi), lbl_str);
10094 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
10095 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
10102 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
10103 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
10110 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
10111 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
10118 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
10119 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
10123 DISSECTOR_ASSERT_NOT_REACHED();
10128 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
10133 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10134 const guint bit_offset, const crumb_spec_t *crumb_spec,
10135 guint64 *return_value)
10140 guint mask_initial_bit_offset;
10141 guint mask_greatest_bit_offset;
10142 guint octet_length;
10145 char lbl_str[ITEM_LABEL_LENGTH];
10147 guint64 composite_bitmask;
10148 guint64 composite_bitmap;
10150 header_field_info *hf_field;
10151 const true_false_string *tfstring;
10153 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
10154 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
10156 if (hf_field->bitmask != 0) {
10157 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10158 "Incompatible use of proto_tree_add_split_bits_item_ret_val"
10159 " with field '%s' (%s) with bitmask != 0",
10160 hf_field->abbrev, hf_field->name));
10163 mask_initial_bit_offset = bit_offset % 8;
10168 mask_greatest_bit_offset = 0;
10169 composite_bitmask = 0;
10170 composite_bitmap = 0;
10172 while (crumb_spec[i].crumb_bit_length != 0) {
10173 guint64 crumb_mask, crumb_value;
10174 guint8 crumb_end_bit_offset;
10176 DISSECTOR_ASSERT(i < 64);
10177 crumb_value = tvb_get_bits64(tvb,
10178 bit_offset + crumb_spec[i].crumb_bit_offset,
10179 crumb_spec[i].crumb_bit_length,
10181 value += crumb_value;
10182 no_of_bits += crumb_spec[i].crumb_bit_length;
10184 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
10185 octet containing the initial offset.
10186 If the mask is beyond 32 bits, then give up on bit map display.
10187 This could be improved in future, probably showing a table
10188 of 32 or 64 bits per row */
10189 if (mask_greatest_bit_offset < 32) {
10190 crumb_end_bit_offset = mask_initial_bit_offset
10191 + crumb_spec[i].crumb_bit_offset
10192 + crumb_spec[i].crumb_bit_length;
10193 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
10195 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
10196 mask_greatest_bit_offset = crumb_end_bit_offset;
10198 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
10199 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
10201 /* Shift left for the next segment */
10202 value <<= crumb_spec[++i].crumb_bit_length;
10205 /* Sign extend for signed types */
10206 switch (hf_field->type) {
10215 value = ws_sign_ext64(value, no_of_bits);
10221 if (return_value) {
10222 *return_value = value;
10225 /* Coast clear. Try and fake it */
10226 CHECK_FOR_NULL_TREE(tree);
10227 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10229 /* initialise the format string */
10232 octet_offset = bit_offset >> 3;
10234 /* Round up mask length to nearest octet */
10235 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
10236 mask_greatest_bit_offset = octet_length << 3;
10238 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
10239 It would be a useful enhancement to eliminate this restriction. */
10240 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
10241 other_decode_bitfield_value(bf_str,
10242 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
10243 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
10244 mask_greatest_bit_offset);
10247 switch (hf_field->type) {
10248 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
10249 /* Boolean field */
10250 tfstring = (const true_false_string *) &tfs_true_false;
10251 if (hf_field->strings)
10252 tfstring = (const true_false_string *) hf_field->strings;
10253 return proto_tree_add_boolean_format(tree, hfindex,
10254 tvb, octet_offset, octet_length, (guint32)value,
10256 bf_str, hf_field->name,
10257 (guint64)value ? tfstring->true_string : tfstring->false_string);
10261 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
10262 fill_label_char(PITEM_FINFO(pi), lbl_str);
10269 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
10270 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
10277 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
10278 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
10285 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
10286 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
10293 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
10294 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
10298 DISSECTOR_ASSERT_NOT_REACHED();
10302 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
10307 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
10308 const crumb_spec_t *crumb_spec, guint16 crumb_index)
10310 header_field_info *hfinfo;
10312 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
10313 proto_tree_add_text_internal(tree, tvb,
10315 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
10316 "%s crumb %d of %s (decoded above)",
10317 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
10320 crumb_spec[crumb_index].crumb_bit_length,
10327 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10328 const guint bit_offset, const gint no_of_bits,
10329 guint64 *return_value, const guint encoding)
10333 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
10334 bit_offset, no_of_bits,
10335 return_value, encoding))) {
10336 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
10337 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
10342 static proto_item *
10343 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
10344 tvbuff_t *tvb, const guint bit_offset,
10345 const gint no_of_bits, void *value_ptr,
10350 guint8 tot_no_bits;
10353 header_field_info *hf_field;
10355 /* We do not have to return a value, try to fake it as soon as possible */
10356 CHECK_FOR_NULL_TREE(tree);
10357 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10359 if (hf_field->bitmask != 0) {
10360 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10361 "Incompatible use of proto_tree_add_bits_format_value"
10362 " with field '%s' (%s) with bitmask != 0",
10363 hf_field->abbrev, hf_field->name));
10366 DISSECTOR_ASSERT(no_of_bits > 0);
10368 /* Byte align offset */
10369 offset = bit_offset>>3;
10372 * Calculate the number of octets used to hold the bits
10374 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
10375 length = tot_no_bits>>3;
10376 /* If we are using part of the next octet, increase length by 1 */
10377 if (tot_no_bits & 0x07)
10380 if (no_of_bits < 65) {
10381 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
10383 DISSECTOR_ASSERT_NOT_REACHED();
10387 str = decode_bits_in_field(bit_offset, no_of_bits, value);
10389 g_strlcat(str, " = ", 256+64);
10390 g_strlcat(str, hf_field->name, 256+64);
10393 * This function does not receive an actual value but a dimensionless pointer to that value.
10394 * For this reason, the type of the header field is examined in order to determine
10395 * what kind of value we should read from this address.
10396 * The caller of this function must make sure that for the specific header field type the address of
10397 * a compatible value is provided.
10399 switch (hf_field->type) {
10401 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
10402 "%s: %s", str, value_str);
10410 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
10411 "%s: %s", str, value_str);
10418 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
10419 "%s: %s", str, value_str);
10426 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
10427 "%s: %s", str, value_str);
10434 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
10435 "%s: %s", str, value_str);
10439 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
10440 "%s: %s", str, value_str);
10444 DISSECTOR_ASSERT_NOT_REACHED();
10450 static proto_item *
10451 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
10452 tvbuff_t *tvb, const guint bit_offset,
10453 const gint no_of_bits, void *value_ptr,
10458 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
10459 tvb, bit_offset, no_of_bits,
10460 value_ptr, value_str))) {
10461 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
10462 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
10467 #define CREATE_VALUE_STRING(dst,format,ap) \
10468 va_start(ap, format); \
10469 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
10473 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
10474 tvbuff_t *tvb, const guint bit_offset,
10475 const gint no_of_bits, guint32 value,
10476 const char *format, ...)
10480 header_field_info *hf_field;
10482 CHECK_FOR_NULL_TREE(tree);
10484 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10486 switch (hf_field->type) {
10494 DISSECTOR_ASSERT_NOT_REACHED();
10499 CREATE_VALUE_STRING(dst, format, ap);
10501 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10505 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
10506 tvbuff_t *tvb, const guint bit_offset,
10507 const gint no_of_bits, guint64 value,
10508 const char *format, ...)
10512 header_field_info *hf_field;
10514 CHECK_FOR_NULL_TREE(tree);
10516 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10518 switch (hf_field->type) {
10526 DISSECTOR_ASSERT_NOT_REACHED();
10531 CREATE_VALUE_STRING(dst, format, ap);
10533 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10537 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
10538 tvbuff_t *tvb, const guint bit_offset,
10539 const gint no_of_bits, float value,
10540 const char *format, ...)
10544 header_field_info *hf_field;
10546 CHECK_FOR_NULL_TREE(tree);
10548 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10550 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
10552 CREATE_VALUE_STRING(dst, format, ap);
10554 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10558 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
10559 tvbuff_t *tvb, const guint bit_offset,
10560 const gint no_of_bits, gint32 value,
10561 const char *format, ...)
10565 header_field_info *hf_field;
10567 CHECK_FOR_NULL_TREE(tree);
10569 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10571 switch (hf_field->type) {
10579 DISSECTOR_ASSERT_NOT_REACHED();
10584 CREATE_VALUE_STRING(dst, format, ap);
10586 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10590 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
10591 tvbuff_t *tvb, const guint bit_offset,
10592 const gint no_of_bits, gint64 value,
10593 const char *format, ...)
10597 header_field_info *hf_field;
10599 CHECK_FOR_NULL_TREE(tree);
10601 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10603 switch (hf_field->type) {
10611 DISSECTOR_ASSERT_NOT_REACHED();
10616 CREATE_VALUE_STRING(dst, format, ap);
10618 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10622 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
10623 tvbuff_t *tvb, const guint bit_offset,
10624 const gint no_of_bits, guint32 value,
10625 const char *format, ...)
10629 header_field_info *hf_field;
10631 CHECK_FOR_NULL_TREE(tree);
10633 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10635 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
10637 CREATE_VALUE_STRING(dst, format, ap);
10639 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10643 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
10644 tvbuff_t *tvb, const guint bit_offset,
10645 const gint no_of_bits, guint64 value,
10646 const char *format, ...)
10650 header_field_info *hf_field;
10652 CHECK_FOR_NULL_TREE(tree);
10654 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10656 DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
10658 CREATE_VALUE_STRING(dst, format, ap);
10660 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10664 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10665 const guint bit_offset, const gint no_of_chars)
10668 header_field_info *hfinfo;
10673 CHECK_FOR_NULL_TREE(tree);
10675 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10677 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
10679 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
10680 byte_offset = bit_offset >> 3;
10682 string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
10684 if (hfinfo->display == STR_UNICODE) {
10685 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
10688 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
10689 DISSECTOR_ASSERT(byte_length >= 0);
10690 proto_tree_set_string(PNODE_FINFO(pi), string);
10696 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10697 const guint bit_offset, const gint no_of_chars)
10700 header_field_info *hfinfo;
10705 CHECK_FOR_NULL_TREE(tree);
10707 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10709 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
10711 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
10712 byte_offset = bit_offset >> 3;
10714 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
10716 if (hfinfo->display == STR_UNICODE) {
10717 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
10720 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
10721 DISSECTOR_ASSERT(byte_length >= 0);
10722 proto_tree_set_string(PNODE_FINFO(pi), string);
10727 const value_string proto_checksum_vals[] = {
10728 { PROTO_CHECKSUM_E_BAD, "Bad" },
10729 { PROTO_CHECKSUM_E_GOOD, "Good" },
10730 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
10731 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
10737 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
10738 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
10739 packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
10741 header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
10744 proto_item* ti = NULL;
10746 gboolean incorrect_checksum = TRUE;
10748 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
10750 if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
10751 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, 0, 0, "[missing]");
10752 PROTO_ITEM_SET_GENERATED(ti);
10753 if (hf_checksum_status != -1) {
10754 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_NOT_PRESENT);
10755 PROTO_ITEM_SET_GENERATED(ti2);
10760 switch (hfinfo->type){
10774 DISSECTOR_ASSERT_NOT_REACHED();
10777 if (flags & PROTO_CHECKSUM_GENERATED) {
10778 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, 0, computed_checksum);
10779 PROTO_ITEM_SET_GENERATED(ti);
10781 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
10782 if (flags & PROTO_CHECKSUM_VERIFY) {
10783 if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
10784 if (computed_checksum == 0) {
10785 proto_item_append_text(ti, " [correct]");
10786 if (hf_checksum_status != -1) {
10787 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
10788 PROTO_ITEM_SET_GENERATED(ti2);
10790 incorrect_checksum = FALSE;
10791 } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
10792 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
10795 if (checksum == computed_checksum) {
10796 proto_item_append_text(ti, " [correct]");
10797 if (hf_checksum_status != -1) {
10798 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
10799 PROTO_ITEM_SET_GENERATED(ti2);
10801 incorrect_checksum = FALSE;
10805 if (incorrect_checksum) {
10806 if (hf_checksum_status != -1) {
10807 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
10808 PROTO_ITEM_SET_GENERATED(ti2);
10810 if (flags & PROTO_CHECKSUM_ZERO) {
10811 proto_item_append_text(ti, " [incorrect]");
10812 if (bad_checksum_expert != NULL)
10813 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum");
10815 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
10816 if (bad_checksum_expert != NULL)
10817 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum [should be 0x%0*x]", len*2, computed_checksum);
10821 if (hf_checksum_status != -1) {
10822 proto_item_append_text(ti, " [unverified]");
10823 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
10824 PROTO_ITEM_SET_GENERATED(ti2);
10833 proto_check_field_name(const gchar *field_name)
10835 return wrs_check_charset(fld_abbrev_chars, field_name);
10839 tree_expanded(int tree_type)
10841 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10842 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
10846 tree_expanded_set(int tree_type, gboolean value)
10848 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10851 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
10853 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
10857 * Editor modelines - http://www.wireshark.org/tools/modelines.html
10860 * c-basic-offset: 8
10862 * indent-tabs-mode: t
10865 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
10866 * :indentSize=8:tabSize=8:noTabs=false: