2 * Routines for protocol tree
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include <wsutil/bits_ctz.h>
32 #include <wsutil/bits_count_ones.h>
33 #include <wsutil/sign_ext.h>
35 #include <ftypes/ftypes-int.h>
38 #include "exceptions.h"
39 #include "ptvcursor.h"
41 #include "addr_resolv.h"
42 #include "address_types.h"
45 #include "epan_dissect.h"
47 #include "wmem/wmem.h"
49 #include "asm_utils.h"
50 #include "column-utils.h"
51 #include "to_str-int.h"
53 #include "osi-utils.h"
55 #include "show_exception.h"
58 #include <wsutil/plugins.h>
59 #include <wsutil/ws_printf.h> /* ws_debug_printf/ws_g_warning */
61 /* Ptvcursor limits */
62 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
63 #define SUBTREE_MAX_LEVELS 256
65 /* Throw an exception if our tree exceeds these. */
66 /* XXX - These should probably be preferences */
67 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
68 #define MAX_TREE_LEVELS (5 * 100)
70 typedef struct __subtree_lvl {
77 subtree_lvl *pushed_tree;
78 guint8 pushed_tree_index;
79 guint8 pushed_tree_max;
85 #define cVALS(x) (const value_string*)(x)
87 /** See inlined comments.
88 @param tree the tree to append this item to
89 @param free_block a code block to call to free resources if this returns
90 @return NULL if 'tree' is null */
91 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block) \
97 /** See inlined comments.
98 @param tree the tree to append this item to
99 @param free_block a code block to call to free resources if this returns
100 @return NULL if 'tree' is null */
101 #define CHECK_FOR_NULL_TREE(tree) \
102 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
104 /** See inlined comments.
105 @param tree the tree to append this item to
106 @param hfindex field index
107 @param hfinfo header_field
108 @param free_block a code block to call to free resources if this returns
109 @return the header field matching 'hfinfo' */
110 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
111 /* If this item is not referenced we don't have to do much work \
112 at all but we should still return a node so that field items \
113 below this node (think proto_item_add_subtree()) will still \
114 have somewhere to attach to or else filtering will not work \
115 (they would be ignored since tree would be NULL). \
116 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
117 since dissectors that want to do proto_item_set_len() or \
118 other operations that dereference this would crash. \
119 We fake FT_PROTOCOL unless some clients have requested us \
122 PTREE_DATA(tree)->count++; \
123 if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
125 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
126 g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
127 /* Let the exception handler add items to the tree */ \
128 PTREE_DATA(tree)->count = 0; \
129 THROW_MESSAGE(DissectorError, \
130 wmem_strdup_printf(wmem_packet_scope(), "More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
132 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
133 if (!(PTREE_DATA(tree)->visible)) { \
134 if (PTREE_FINFO(tree)) { \
135 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
136 && (hfinfo->type != FT_PROTOCOL || \
137 PTREE_DATA(tree)->fake_protocols)) { \
139 /* just return tree back to the caller */\
145 /** See inlined comments.
146 @param tree the tree to append this item to
147 @param hfindex field index
148 @param hfinfo header_field
149 @return the header field matching 'hfinfo' */
150 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
151 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
154 /** See inlined comments.
155 @param pi the created protocol item we're about to return */
156 #define TRY_TO_FAKE_THIS_REPR(pi) \
158 if (!(PTREE_DATA(pi)->visible)) { \
159 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
160 * items string representation */ \
163 /* Same as above but returning void */
164 #define TRY_TO_FAKE_THIS_REPR_VOID(pi) \
167 if (!(PTREE_DATA(pi)->visible)) { \
168 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
169 * items string representation */ \
173 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
174 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
175 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
177 static void label_mark_truncated(char *label_str, gsize name_pos);
178 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
180 static void fill_label_boolean(field_info *fi, gchar *label_str);
181 static void fill_label_bitfield_char(field_info *fi, gchar *label_str);
182 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
183 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
184 static void fill_label_char(field_info *fi, gchar *label_str);
185 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
186 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
188 static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value);
189 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
190 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
191 static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
192 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
193 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
194 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
195 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
196 static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
197 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
198 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
201 proto_tree_add_node(proto_tree *tree, field_info *fi);
204 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
208 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
209 gint length, guint item_length, const gint encoding);
212 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
213 const gint start, const gint item_length);
216 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
217 gint start, gint *length);
220 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
222 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
225 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
227 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
229 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
231 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
233 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
235 proto_tree_set_string(field_info *fi, const char* value);
237 proto_tree_set_ax25(field_info *fi, const guint8* value);
239 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
241 proto_tree_set_vines(field_info *fi, const guint8* value);
243 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
245 proto_tree_set_ether(field_info *fi, const guint8* value);
247 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
249 proto_tree_set_ipxnet(field_info *fi, guint32 value);
251 proto_tree_set_ipv4(field_info *fi, guint32 value);
253 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
255 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
257 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
259 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
261 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
263 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
265 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
267 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
269 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
271 proto_tree_set_boolean(field_info *fi, guint64 value);
273 proto_tree_set_float(field_info *fi, float value);
275 proto_tree_set_double(field_info *fi, double value);
277 proto_tree_set_uint(field_info *fi, guint32 value);
279 proto_tree_set_int(field_info *fi, gint32 value);
281 proto_tree_set_uint64(field_info *fi, guint64 value);
283 proto_tree_set_int64(field_info *fi, gint64 value);
285 proto_tree_set_eui64(field_info *fi, const guint64 value);
287 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
289 /* Handle type length mismatch (now filterable) expert info */
290 static int proto_type_length_mismatch = -1;
291 static expert_field ei_type_length_mismatch_error = EI_INIT;
292 static expert_field ei_type_length_mismatch_warn = EI_INIT;
293 static void register_type_length_mismatch(void);
295 /* Handle number string decoding errors with expert info */
296 static int proto_number_string_decoding_error = -1;
297 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
298 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
299 static void register_number_string_decoding_error(void);
301 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
303 /* special-case header field used within proto.c */
304 static header_field_info hfi_text_only =
305 { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
306 int hf_text_only = -1;
308 /* Structure for information about a protocol */
310 const char *name; /* long description */
311 const char *short_name; /* short description */
312 const char *filter_name; /* name of this protocol in filters */
313 GPtrArray *fields; /* fields for this protocol */
314 int proto_id; /* field ID for this protocol */
315 gboolean is_enabled; /* TRUE if protocol is enabled */
316 gboolean enabled_by_default; /* TRUE if protocol is enabled by default */
317 gboolean can_toggle; /* TRUE if is_enabled can be changed */
318 GList *heur_list; /* Heuristic dissectors associated with this protocol */
321 /* List of all protocols */
322 static GList *protocols = NULL;
324 /* Deregistered fields */
325 static GPtrArray *deregistered_fields = NULL;
326 static GPtrArray *deregistered_data = NULL;
328 /* Contains information about a field when a dissector calls
329 * proto_tree_add_item. */
330 #define FIELD_INFO_NEW(pool, fi) fi = wmem_new(pool, field_info)
331 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
333 /* Contains the space for proto_nodes. */
334 #define PROTO_NODE_INIT(node) \
335 node->first_child = NULL; \
336 node->last_child = NULL; \
339 #define PROTO_NODE_FREE(pool, node) \
340 wmem_free(pool, node)
342 /* String space for protocol and field items for the GUI */
343 #define ITEM_LABEL_NEW(pool, il) \
344 il = wmem_new(pool, item_label_t);
345 #define ITEM_LABEL_FREE(pool, il) \
348 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
349 if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
350 g_error("Unregistered hf! index=%d", hfindex); \
351 DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
352 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
353 hfinfo = gpa_hfinfo.hfi[hfindex];
355 /* List which stores protocols and fields that have been registered */
356 typedef struct _gpa_hfinfo_t {
358 guint32 allocated_len;
359 header_field_info **hfi;
362 static gpa_hfinfo_t gpa_hfinfo;
364 /* Hash table of abbreviations and IDs */
365 static GHashTable *gpa_name_map = NULL;
366 static header_field_info *same_name_hfinfo;
368 * We're called repeatedly with the same field name when sorting a column.
369 * Cache our last gpa_name_map hit for faster lookups.
371 static char *last_field_name = NULL;
372 static header_field_info *last_hfinfo;
374 static void save_same_name_hfinfo(gpointer data)
376 same_name_hfinfo = (header_field_info*)data;
379 /* Cached value for VINES address type (used for FT_VINES) */
380 static int vines_address_type = -1;
382 /* Points to the first element of an array of bits, indexed by
383 a subtree item type; that array element is TRUE if subtrees of
384 an item of that type are to be expanded. */
385 static guint32 *tree_is_expanded;
387 /* Number of elements in that array. */
390 /* Name hashtables for fast detection of duplicate names */
391 static GHashTable* proto_names = NULL;
392 static GHashTable* proto_short_names = NULL;
393 static GHashTable* proto_filter_names = NULL;
396 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
398 const protocol_t *p1 = (const protocol_t *)p1_arg;
399 const protocol_t *p2 = (const protocol_t *)p2_arg;
401 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
406 * List of dissector plugins.
409 void (*register_protoinfo)(void); /* routine to call to register protocol information */
410 void (*reg_handoff)(void); /* routine to call to register dissector handoff */
413 static GSList *dissector_plugins = NULL;
416 * Callback for each plugin found.
419 check_for_dissector_plugin(GModule *handle)
422 void (*register_protoinfo)(void);
423 void (*reg_handoff)(void);
424 dissector_plugin *plugin;
427 * Do we have a register routine?
429 if (g_module_symbol(handle, "plugin_register", &gp)) {
431 register_protoinfo = (void (*)(void))gp;
435 register_protoinfo = NULL;
439 * Do we have a reg_handoff routine?
441 if (g_module_symbol(handle, "plugin_reg_handoff", &gp)) {
443 reg_handoff = (void (*)(void))gp;
451 * If we have neither, we're not a dissector plugin.
453 if (register_protoinfo == NULL && reg_handoff == NULL)
457 * Add this one to the list of dissector plugins.
459 plugin = (dissector_plugin *)g_malloc(sizeof (dissector_plugin));
460 plugin->register_protoinfo = register_protoinfo;
461 plugin->reg_handoff = reg_handoff;
462 dissector_plugins = g_slist_append(dissector_plugins, plugin);
467 register_dissector_plugin(gpointer data, gpointer user_data _U_)
469 dissector_plugin *plugin = (dissector_plugin *)data;
471 if (plugin->register_protoinfo)
472 (plugin->register_protoinfo)();
476 reg_handoff_dissector_plugin(gpointer data, gpointer user_data _U_)
478 dissector_plugin *plugin = (dissector_plugin *)data;
480 if (plugin->reg_handoff)
481 (plugin->reg_handoff)();
485 * Register dissector plugin type.
488 register_dissector_plugin_type(void)
490 add_plugin_type("dissector", check_for_dissector_plugin);
492 #endif /* HAVE_PLUGINS */
494 /* initialize data structures and register protocols and fields */
496 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
497 void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
499 gpointer client_data)
503 proto_names = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
504 proto_short_names = g_hash_table_new(wrs_str_hash, g_str_equal);
505 proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
508 gpa_hfinfo.allocated_len = 0;
509 gpa_hfinfo.hfi = NULL;
510 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
511 deregistered_fields = g_ptr_array_new();
512 deregistered_data = g_ptr_array_new();
514 /* Initialize the ftype subsystem */
517 /* Initialize the addres type subsystem */
518 address_types_initialize();
520 /* Register one special-case FT_TEXT_ONLY field for use when
521 converting wireshark to new-style proto_tree. These fields
522 are merely strings on the GUI tree; they are not filterable */
523 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
525 /* Register the pseudo-protocols used for exceptions. */
526 register_show_exception();
527 register_type_length_mismatch();
528 register_number_string_decoding_error();
530 /* Have each built-in dissector register its protocols, fields,
531 dissector tables, and dissectors to be called through a
532 handle, and do whatever one-time initialization it needs to
534 register_all_protocols_func(cb, client_data);
536 /* Now that the VINES dissector has registered it's address
537 type, grab the value for the field type */
538 vines_address_type = address_type_get_by_name("AT_VINES");
540 /* Now call the registration routines for all disssector
543 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
544 g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL);
547 /* Now call the "handoff registration" routines of all built-in
548 dissectors; those routines register the dissector in other
549 dissectors' handoff tables, and fetch any dissector handles
551 register_all_handoffs_func(cb, client_data);
554 /* Now do the same with plugins. */
556 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
557 g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL);
560 /* sort the protocols by protocol name */
561 protocols = g_list_sort(protocols, proto_compare_name);
563 /* We've assigned all the subtree type values; allocate the array
564 for them, and zero it out. */
565 tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
571 /* Free the abbrev/ID hash table */
573 g_hash_table_destroy(gpa_name_map);
576 g_free(last_field_name);
577 last_field_name = NULL;
580 protocol_t *protocol = (protocol_t *)protocols->data;
581 header_field_info *hfinfo;
582 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
583 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
585 g_slice_free(header_field_info, hfinfo);
586 if (protocol->fields) {
587 g_ptr_array_free(protocol->fields, TRUE);
589 g_list_free(protocol->heur_list);
590 protocols = g_list_remove(protocols, protocol);
595 g_hash_table_destroy(proto_names);
599 if (proto_short_names) {
600 g_hash_table_destroy(proto_short_names);
601 proto_short_names = NULL;
604 if (proto_filter_names) {
605 g_hash_table_destroy(proto_filter_names);
606 proto_filter_names = NULL;
609 if (gpa_hfinfo.allocated_len) {
611 gpa_hfinfo.allocated_len = 0;
612 g_free(gpa_hfinfo.hfi);
613 gpa_hfinfo.hfi = NULL;
616 if (deregistered_fields) {
617 g_ptr_array_free(deregistered_fields, FALSE);
618 deregistered_fields = NULL;
621 if (deregistered_data) {
622 g_ptr_array_free(deregistered_data, FALSE);
623 deregistered_data = NULL;
626 g_free(tree_is_expanded);
627 tree_is_expanded = NULL;
631 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
634 proto_node *pnode = tree;
638 if (func(pnode, data))
641 child = pnode->first_child;
642 while (child != NULL) {
644 * The routine we call might modify the child, e.g. by
645 * freeing it, so we get the child's successor before
646 * calling that routine.
649 child = current->next;
650 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
658 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
661 proto_node *pnode = tree;
665 child = pnode->first_child;
666 while (child != NULL) {
668 * The routine we call might modify the child, e.g. by
669 * freeing it, so we get the child's successor before
670 * calling that routine.
673 child = current->next;
674 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
677 if (func(pnode, data))
684 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
687 proto_node *node = tree;
693 node = node->first_child;
694 while (node != NULL) {
696 node = current->next;
697 func((proto_tree *)current, data);
702 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
704 GPtrArray *ptrs = (GPtrArray *)value;
705 gint hfid = GPOINTER_TO_UINT(key);
706 header_field_info *hfinfo;
708 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
709 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
710 /* when a field is referenced by a filter this also
711 affects the refcount for the parent protocol so we need
712 to adjust the refcount for the parent as well
714 if (hfinfo->parent != -1) {
715 header_field_info *parent_hfinfo;
716 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
717 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
719 hfinfo->ref_type = HF_REF_TYPE_NONE;
722 g_ptr_array_free(ptrs, TRUE);
726 proto_tree_free_node(proto_node *node, gpointer data _U_)
728 field_info *finfo = PNODE_FINFO(node);
730 proto_tree_children_foreach(node, proto_tree_free_node, NULL);
732 FVALUE_CLEANUP(&finfo->value);
736 proto_tree_reset(proto_tree *tree)
738 tree_data_t *tree_data = PTREE_DATA(tree);
740 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
743 if (tree_data->interesting_hfids) {
744 /* Free all the GPtrArray's in the interesting_hfids hash. */
745 g_hash_table_foreach(tree_data->interesting_hfids,
746 free_GPtrArray_value, NULL);
748 /* And then remove all values. */
749 g_hash_table_remove_all(tree_data->interesting_hfids);
752 /* Reset track of the number of children */
753 tree_data->count = 0;
755 PROTO_NODE_INIT(tree);
758 /* frees the resources that the dissection a proto_tree uses */
760 proto_tree_free(proto_tree *tree)
762 tree_data_t *tree_data = PTREE_DATA(tree);
764 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
767 if (tree_data->interesting_hfids) {
768 /* Free all the GPtrArray's in the interesting_hfids hash. */
769 g_hash_table_foreach(tree_data->interesting_hfids,
770 free_GPtrArray_value, NULL);
772 /* And then destroy the hash. */
773 g_hash_table_destroy(tree_data->interesting_hfids);
776 g_slice_free(tree_data_t, tree_data);
778 g_slice_free(proto_tree, tree);
781 /* Is the parsing being done for a visible proto_tree or an invisible one?
782 * By setting this correctly, the proto_tree creation is sped up by not
783 * having to call g_vsnprintf and copy strings around.
786 proto_tree_set_visible(proto_tree *tree, gboolean visible)
788 gboolean old_visible = PTREE_DATA(tree)->visible;
790 PTREE_DATA(tree)->visible = visible;
796 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
798 PTREE_DATA(tree)->fake_protocols = fake_protocols;
801 /* Assume dissector set only its protocol fields.
802 This function is called by dissectors and allows the speeding up of filtering
803 in wireshark; if this function returns FALSE it is safe to reset tree to NULL
804 and thus skip calling most of the expensive proto_tree_add_...()
806 If the tree is visible we implicitly assume the field is referenced.
809 proto_field_is_referenced(proto_tree *tree, int proto_id)
811 register header_field_info *hfinfo;
817 if (PTREE_DATA(tree)->visible)
820 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
821 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
824 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
831 /* Finds a record in the hfinfo array by id. */
833 proto_registrar_get_nth(guint hfindex)
835 register header_field_info *hfinfo;
837 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
842 /* Prefix initialization
843 * this allows for a dissector to register a display filter name prefix
844 * so that it can delay the initialization of the hf array as long as
848 /* compute a hash for the part before the dot of a display filter */
850 prefix_hash (gconstpointer key) {
851 /* end the string at the dot and compute its hash */
852 gchar* copy = g_strdup((const gchar *)key);
863 tmp = g_str_hash(copy);
868 /* are both strings equal up to the end or the dot? */
870 prefix_equal (gconstpointer ap, gconstpointer bp) {
871 const gchar* a = (const gchar *)ap;
872 const gchar* b = (const gchar *)bp;
878 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
880 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
881 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
883 if (ac != bc) return FALSE;
890 /* indexed by prefix, contains initializers */
891 static GHashTable* prefixes = NULL;
894 /* Register a new prefix for "delayed" initialization of field arrays */
896 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
898 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
901 g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
904 /* helper to call all prefix initializers */
906 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
907 ((prefix_initializer_t)v)((const char *)k);
911 /** Initialize every remaining uninitialized prefix. */
913 proto_initialize_all_prefixes(void) {
914 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
917 /* Finds a record in the hfinfo array by name.
918 * If it fails to find it in the already registered fields,
919 * it tries to find and call an initializer in the prefixes
920 * table and if so it looks again.
924 proto_registrar_get_byname(const char *field_name)
926 header_field_info *hfinfo;
927 prefix_initializer_t pi;
932 if (g_strcmp0(field_name, last_field_name) == 0) {
936 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
939 g_free(last_field_name);
940 last_field_name = g_strdup(field_name);
941 last_hfinfo = hfinfo;
948 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
950 g_hash_table_remove(prefixes, field_name);
955 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
958 g_free(last_field_name);
959 last_field_name = g_strdup(field_name);
960 last_hfinfo = hfinfo;
966 proto_registrar_get_id_byname(const char *field_name)
968 header_field_info *hfinfo;
970 hfinfo = proto_registrar_get_byname(field_name);
980 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
982 subtree_lvl *pushed_tree;
984 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
985 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
987 pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
988 DISSECTOR_ASSERT(pushed_tree != NULL);
989 if (ptvc->pushed_tree)
990 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
991 ptvc->pushed_tree = pushed_tree;
995 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
997 ptvc->pushed_tree = NULL;
998 ptvc->pushed_tree_max = 0;
999 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1000 ptvc->pushed_tree_index = 0;
1003 /* Allocates an initializes a ptvcursor_t with 3 variables:
1004 * proto_tree, tvbuff, and offset. */
1006 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
1010 ptvc = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
1013 ptvc->offset = offset;
1014 ptvc->pushed_tree = NULL;
1015 ptvc->pushed_tree_max = 0;
1016 ptvc->pushed_tree_index = 0;
1021 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1023 ptvcursor_free(ptvcursor_t *ptvc)
1025 ptvcursor_free_subtree_levels(ptvc);
1029 /* Returns tvbuff. */
1031 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1036 /* Returns current offset. */
1038 ptvcursor_current_offset(ptvcursor_t *ptvc)
1040 return ptvc->offset;
1044 ptvcursor_tree(ptvcursor_t *ptvc)
1053 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1058 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1060 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1062 subtree_lvl *subtree;
1063 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1064 ptvcursor_new_subtree_levels(ptvc);
1066 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1067 subtree->tree = ptvc->tree;
1069 ptvc->pushed_tree_index++;
1070 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1073 /* pops a subtree */
1075 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1077 subtree_lvl *subtree;
1079 if (ptvc->pushed_tree_index <= 0)
1082 ptvc->pushed_tree_index--;
1083 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1084 if (subtree->it != NULL)
1085 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1087 ptvc->tree = subtree->tree;
1090 /* saves the current tvb offset and the item in the current subtree level */
1092 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1094 subtree_lvl *subtree;
1096 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1098 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1100 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1103 /* Creates a subtree and adds it to the cursor as the working tree but does not
1104 * save the old working tree */
1106 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1108 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1113 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1115 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1116 if (length == SUBTREE_UNDEFINED_LENGTH)
1117 ptvcursor_subtree_set_item(ptvc, it);
1118 return ptvcursor_tree(ptvc);
1121 /* Add an item to the tree and create a subtree
1122 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1123 * In this case, when the subtree will be closed, the parent item length will
1124 * be equal to the advancement of the cursor since the creation of the subtree.
1127 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1128 const guint encoding, gint ett_subtree)
1132 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1133 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1137 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1139 /* Add a text node to the tree and create a subtree
1140 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1141 * In this case, when the subtree will be closed, the item length will be equal
1142 * to the advancement of the cursor since the creation of the subtree.
1145 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1146 gint ett_subtree, const char *format, ...)
1150 header_field_info *hfinfo;
1153 tree = ptvcursor_tree(ptvc);
1155 CHECK_FOR_NULL_TREE(tree);
1157 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1159 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1160 ptvcursor_current_offset(ptvc), length);
1162 TRY_TO_FAKE_THIS_REPR(pi);
1164 va_start(ap, format);
1165 proto_tree_set_representation(pi, format, ap);
1168 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1171 /* Add a text-only node, leaving it to our caller to fill the text in */
1173 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1180 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1185 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1187 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1188 const char *format, ...)
1192 header_field_info *hfinfo;
1195 /* If we're fetching until the end of the TVB, only validate
1196 * that the offset is within range.
1200 tvb_ensure_bytes_exist(tvb, start, length);
1202 CHECK_FOR_NULL_TREE(tree);
1204 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1206 pi = proto_tree_add_text_node(tree, tvb, start, length);
1208 TRY_TO_FAKE_THIS_REPR(pi);
1210 va_start(ap, format);
1211 proto_tree_set_representation(pi, format, ap);
1217 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1219 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1220 gint length, const char *format, va_list ap)
1223 header_field_info *hfinfo;
1226 /* If we're fetching until the end of the TVB, only validate
1227 * that the offset is within range.
1231 tvb_ensure_bytes_exist(tvb, start, length);
1233 CHECK_FOR_NULL_TREE(tree);
1235 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1237 pi = proto_tree_add_text_node(tree, tvb, start, length);
1239 TRY_TO_FAKE_THIS_REPR(pi);
1241 proto_tree_set_representation(pi, format, ap);
1246 /* Add a text-only node that creates a subtree underneath.
1249 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1251 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1254 /* Add a text-only node that creates a subtree underneath.
1257 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1263 va_start(ap, format);
1264 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1267 if (tree_item != NULL)
1270 pt = proto_item_add_subtree(pi, idx);
1275 /* Add a text-only node for debugging purposes. The caller doesn't need
1276 * to worry about tvbuff, start, or length. Debug message gets sent to
1279 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1284 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1287 va_start(ap, format);
1288 proto_tree_set_representation(pi, format, ap);
1291 va_start(ap, format);
1292 vprintf(format, ap);
1294 ws_debug_printf("\n");
1300 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1303 header_field_info *hfinfo;
1305 CHECK_FOR_NULL_TREE(tree);
1307 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1309 pi = proto_tree_add_text_node(tree, tvb, start, length);
1311 TRY_TO_FAKE_THIS_REPR(pi);
1313 proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1319 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1322 header_field_info *hfinfo;
1324 CHECK_FOR_NULL_TREE(tree);
1326 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1328 pi = proto_tree_add_text_node(tree, tvb, start, length);
1330 TRY_TO_FAKE_THIS_REPR(pi);
1332 proto_item_set_text(pi, "%s", tvb_format_text_wsp(tvb, start, length));
1337 void proto_report_dissector_bug(const char *message)
1339 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1342 THROW_MESSAGE(DissectorError, message);
1345 /* We could probably get away with changing is_error to a minimum length value. */
1347 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1350 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1352 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1356 THROW(ReportedBoundsError);
1361 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1364 gboolean length_error;
1369 value = tvb_get_guint8(tvb, offset);
1373 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1374 : tvb_get_ntohs(tvb, offset);
1378 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1379 : tvb_get_ntoh24(tvb, offset);
1383 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1384 : tvb_get_ntohl(tvb, offset);
1389 length_error = TRUE;
1392 length_error = FALSE;
1393 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1394 : tvb_get_ntohl(tvb, offset);
1396 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1402 static inline guint64
1403 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1406 gboolean length_error;
1411 value = tvb_get_guint8(tvb, offset);
1415 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1416 : tvb_get_ntohs(tvb, offset);
1420 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1421 : tvb_get_ntoh24(tvb, offset);
1425 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1426 : tvb_get_ntohl(tvb, offset);
1430 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1431 : tvb_get_ntoh40(tvb, offset);
1435 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1436 : tvb_get_ntoh48(tvb, offset);
1440 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1441 : tvb_get_ntoh56(tvb, offset);
1445 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1446 : tvb_get_ntoh64(tvb, offset);
1451 length_error = TRUE;
1454 length_error = FALSE;
1455 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1456 : tvb_get_ntoh64(tvb, offset);
1458 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1465 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1468 gboolean length_error;
1473 value = (gint8)tvb_get_guint8(tvb, offset);
1477 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1478 : tvb_get_ntohs(tvb, offset));
1482 value = encoding ? tvb_get_letoh24(tvb, offset)
1483 : tvb_get_ntoh24(tvb, offset);
1484 if (value & 0x00800000) {
1485 /* Sign bit is set; sign-extend it. */
1486 value |= 0xFF000000;
1491 value = encoding ? tvb_get_letohl(tvb, offset)
1492 : tvb_get_ntohl(tvb, offset);
1497 length_error = TRUE;
1500 length_error = FALSE;
1501 value = encoding ? tvb_get_letohl(tvb, offset)
1502 : tvb_get_ntohl(tvb, offset);
1504 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1510 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1511 * be cast-able as a gint64. This is weird, but what the code has always done.
1513 static inline guint64
1514 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1516 guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1521 value = ws_sign_ext64(value, 56);
1524 value = ws_sign_ext64(value, 48);
1527 value = ws_sign_ext64(value, 40);
1530 value = ws_sign_ext64(value, 32);
1533 value = ws_sign_ext64(value, 24);
1536 value = ws_sign_ext64(value, 16);
1539 value = ws_sign_ext64(value, 8);
1547 static inline const guint8 *
1548 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1549 gint length, gint *ret_length, const guint encoding)
1552 length = tvb_ensure_captured_length_remaining(tvb, start);
1554 *ret_length = length;
1555 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1558 /* For FT_STRINGZ */
1559 static inline const guint8 *
1560 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1561 gint start, gint length, gint *ret_length, const guint encoding)
1563 const guint8 *value;
1566 report_type_length_mismatch(tree, "a string", length, TRUE);
1569 /* This can throw an exception */
1570 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1571 } else if (length == 0) {
1574 /* In this case, length signifies the length of the string.
1576 * This could either be a null-padded string, which doesn't
1577 * necessarily have a '\0' at the end, or a null-terminated
1578 * string, with a trailing '\0'. (Yes, there are cases
1579 * where you have a string that's both counted and null-
1582 * In the first case, we must allocate a buffer of length
1583 * "length+1", to make room for a trailing '\0'.
1585 * In the second case, we don't assume that there is a
1586 * trailing '\0' there, as the packet might be malformed.
1587 * (XXX - should we throw an exception if there's no
1588 * trailing '\0'?) Therefore, we allocate a buffer of
1589 * length "length+1", and put in a trailing '\0', just to
1592 * (XXX - this would change if we made string values counted
1593 * rather than null-terminated.)
1595 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1597 *ret_length = length;
1601 /* For FT_UINT_STRING */
1602 static inline const guint8 *
1603 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1604 tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1605 const guint encoding)
1608 const guint8 *value;
1610 /* I believe it's ok if this is called with a NULL tree */
1611 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1612 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1614 *ret_length = length;
1618 /* For FT_STRINGZPAD */
1619 static inline const guint8 *
1620 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1621 gint length, gint *ret_length, const guint encoding)
1624 * XXX - currently, string values are null-
1625 * terminated, so a "zero-padded" string
1626 * isn't special. If we represent string
1627 * values as something that includes a counted
1628 * array of bytes, we'll need to strip
1632 length = tvb_ensure_captured_length_remaining(tvb, start);
1634 *ret_length = length;
1635 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1638 /* this can be called when there is no tree, so don't add that as a param */
1640 get_time_value(tvbuff_t *tvb, const gint start, const gint length, const guint encoding,
1641 nstime_t *time_stamp, const gboolean is_relative)
1646 /* relative timestamps don't do TOD/NTP */
1648 (encoding != (ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN)) &&
1649 (encoding != (ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN)) )
1651 /* XXX: I think this should call REPORT_DISSECTOR_BUG(), but
1652 the existing code didn't do that, so I'm not either */
1658 case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1660 * 4-byte UNIX epoch, possibly followed by
1661 * 4-byte fractional time in nanoseconds,
1664 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1666 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1668 time_stamp->nsecs = 0;
1671 case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1673 * 4-byte UNIX epoch, possibly followed by
1674 * 4-byte fractional time in nanoseconds,
1675 * both little-endian.
1677 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1679 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1681 time_stamp->nsecs = 0;
1684 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1686 * TOD time stamp, big-endian.
1688 /* XXX - where should this go? */
1689 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800)
1691 todsecs = tvb_get_ntoh64(tvb, start) >> 12;
1692 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1693 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1696 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1698 * TOD time stamp, big-endian.
1700 todsecs = tvb_get_letoh64(tvb, start) >> 12 ;
1701 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1702 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1705 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1707 * NTP time stamp, big-endian.
1710 /* XXX - where should this go? */
1711 #define NTP_BASETIME G_GUINT64_CONSTANT(2208988800)
1713 /* We need a temporary variable here so the unsigned math
1714 * works correctly (for years > 2036 according to RFC 2030
1717 tmpsecs = tvb_get_ntohl(tvb, start);
1719 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1721 time_stamp->secs = tmpsecs; /* 0 */
1725 * We're using nanoseconds here (and we will
1726 * display nanoseconds), but NTP's timestamps
1727 * have a precision in microseconds or greater.
1728 * Round to 1 microsecond.
1730 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1731 time_stamp->nsecs *= 1000;
1733 time_stamp->nsecs = 0;
1737 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1739 * NTP time stamp, big-endian.
1741 tmpsecs = tvb_get_letohl(tvb, start);
1743 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1745 time_stamp->secs = tmpsecs; /* 0 */
1749 * We're using nanoseconds here (and we will
1750 * display nanoseconds), but NTP's timestamps
1751 * have a precision in microseconds or greater.
1752 * Round to 1 microsecond.
1754 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1755 time_stamp->nsecs *= 1000;
1757 time_stamp->nsecs = 0;
1760 case ENC_TIME_NTP_BASE_ZERO|ENC_BIG_ENDIAN:
1762 * DDS NTP time stamp, big-endian.
1765 #define NTP_BASETIME_ZERO G_GUINT64_CONSTANT(0)
1767 tmpsecs = tvb_get_ntohl(tvb, start);
1769 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1771 time_stamp->secs = tmpsecs; /* 0 */
1775 * We're using nanoseconds here (and we will
1776 * display nanoseconds), but NTP's timestamps
1777 * have a precision in microseconds or greater.
1778 * Round to 1 microsecond.
1780 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1781 time_stamp->nsecs *= 1000;
1783 time_stamp->nsecs = 0;
1787 case ENC_TIME_NTP_BASE_ZERO|ENC_LITTLE_ENDIAN:
1789 * NTP time stamp, big-endian.
1791 tmpsecs = tvb_get_letohl(tvb, start);
1793 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1795 time_stamp->secs = tmpsecs; /* 0 */
1796 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1799 * We're using nanoseconds here (and we will
1800 * display nanoseconds), but NTP's timestamps
1801 * have a precision in microseconds or greater.
1802 * Round to 1 microsecond.
1804 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1805 time_stamp->nsecs *= 1000;
1807 time_stamp->nsecs = 0;
1812 DISSECTOR_ASSERT_NOT_REACHED();
1818 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
1820 const header_field_info *hfinfo = fi->hfinfo;
1822 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
1823 GPtrArray *ptrs = NULL;
1825 if (tree_data->interesting_hfids == NULL) {
1826 /* Initialize the hash because we now know that it is needed */
1827 tree_data->interesting_hfids =
1828 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
1829 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
1830 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
1831 GINT_TO_POINTER(hfinfo->id));
1835 /* First element triggers the creation of pointer array */
1836 ptrs = g_ptr_array_new();
1837 g_hash_table_insert(tree_data->interesting_hfids,
1838 GINT_TO_POINTER(hfinfo->id), ptrs);
1841 g_ptr_array_add(ptrs, fi);
1845 /* Add an item to a proto_tree, using the text label registered to that item;
1846 the item is extracted from the tvbuff handed to it. */
1848 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
1849 tvbuff_t *tvb, gint start, gint length,
1856 const char *stringval;
1857 nstime_t time_stamp;
1858 gboolean length_error;
1860 switch (new_fi->hfinfo->type) {
1862 /* no value to set for FT_NONE */
1866 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
1870 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
1875 * Map all non-zero values to little-endian for
1876 * backwards compatibility.
1879 encoding = ENC_LITTLE_ENDIAN;
1880 n = get_uint_value(tree, tvb, start, length, encoding);
1881 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
1883 /* Instead of calling proto_item_set_len(), since we don't yet
1884 * have a proto_item, we set the field_info's length ourselves. */
1885 new_fi->length = n + length;
1890 * Map all non-zero values to little-endian for
1891 * backwards compatibility.
1894 encoding = ENC_LITTLE_ENDIAN;
1895 proto_tree_set_boolean(new_fi,
1896 get_uint64_value(tree, tvb, start, length, encoding));
1900 /* XXX - make these just FT_UINT? */
1906 * Map all non-zero values to little-endian for
1907 * backwards compatibility.
1910 encoding = ENC_LITTLE_ENDIAN;
1911 proto_tree_set_uint(new_fi,
1912 get_uint_value(tree, tvb, start, length, encoding));
1920 * Map all non-zero values to little-endian for
1921 * backwards compatibility.
1924 encoding = ENC_LITTLE_ENDIAN;
1925 proto_tree_set_uint64(new_fi,
1926 get_uint64_value(tree, tvb, start, length, encoding));
1929 /* XXX - make these just FT_INT? */
1935 * Map all non-zero values to little-endian for
1936 * backwards compatibility.
1939 encoding = ENC_LITTLE_ENDIAN;
1940 proto_tree_set_int(new_fi,
1941 get_int_value(tree, tvb, start, length, encoding));
1949 * Map all non-zero values to little-endian for
1950 * backwards compatibility.
1953 encoding = ENC_LITTLE_ENDIAN;
1954 proto_tree_set_int64(new_fi,
1955 get_int64_value(tree, tvb, start, length, encoding));
1960 * Map all non-zero values to little-endian for
1961 * backwards compatibility.
1964 encoding = ENC_LITTLE_ENDIAN;
1965 if (length != FT_IPv4_LEN) {
1966 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
1967 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
1969 value = tvb_get_ipv4(tvb, start);
1971 * NOTE: to support code written when
1972 * proto_tree_add_item() took a gboolean as its
1973 * last argument, with FALSE meaning "big-endian"
1974 * and TRUE meaning "little-endian", we treat any
1975 * non-zero value of "encoding" as meaning
1978 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
1982 if (length != FT_IPXNET_LEN) {
1983 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
1984 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
1986 proto_tree_set_ipxnet(new_fi,
1987 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
1991 if (length != FT_IPv6_LEN) {
1992 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
1993 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
1995 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
1999 if (length != FT_FCWWN_LEN) {
2000 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2001 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2003 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2008 length_error = length < 7 ? TRUE : FALSE;
2009 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2011 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2015 if (length != VINES_ADDR_LEN) {
2016 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2017 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2019 proto_tree_set_vines_tvb(new_fi, tvb, start);
2023 if (length != FT_ETHER_LEN) {
2024 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2025 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2027 proto_tree_set_ether_tvb(new_fi, tvb, start);
2032 * Map all non-zero values to little-endian for
2033 * backwards compatibility.
2036 encoding = ENC_LITTLE_ENDIAN;
2037 if (length != FT_EUI64_LEN) {
2038 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2039 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2041 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2045 * Map all non-zero values to little-endian for
2046 * backwards compatibility.
2049 encoding = ENC_LITTLE_ENDIAN;
2050 if (length != FT_GUID_LEN) {
2051 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2052 report_type_length_mismatch(tree, "a GUID", length, length_error);
2054 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2059 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2063 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2068 * NOTE: to support code written when
2069 * proto_tree_add_item() took a gboolean as its
2070 * last argument, with FALSE meaning "big-endian"
2071 * and TRUE meaning "little-endian", we treat any
2072 * non-zero value of "encoding" as meaning
2075 * At some point in the future, we might
2076 * support non-IEEE-binary floating-point
2077 * formats in the encoding as well
2078 * (IEEE decimal, System/3x0, VAX).
2081 encoding = ENC_LITTLE_ENDIAN;
2083 length_error = length < 4 ? TRUE : FALSE;
2084 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2087 floatval = tvb_get_letohieee_float(tvb, start);
2089 floatval = tvb_get_ntohieee_float(tvb, start);
2090 proto_tree_set_float(new_fi, floatval);
2095 * NOTE: to support code written when
2096 * proto_tree_add_item() took a gboolean as its
2097 * last argument, with FALSE meaning "big-endian"
2098 * and TRUE meaning "little-endian", we treat any
2099 * non-zero value of "encoding" as meaning
2102 * At some point in the future, we might
2103 * support non-IEEE-binary floating-point
2104 * formats in the encoding as well
2105 * (IEEE decimal, System/3x0, VAX).
2107 if (encoding == TRUE)
2108 encoding = ENC_LITTLE_ENDIAN;
2110 length_error = length < 8 ? TRUE : FALSE;
2111 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2114 doubleval = tvb_get_letohieee_double(tvb, start);
2116 doubleval = tvb_get_ntohieee_double(tvb, start);
2117 proto_tree_set_double(new_fi, doubleval);
2121 stringval = get_string_value(wmem_packet_scope(),
2122 tvb, start, length, &length, encoding);
2123 proto_tree_set_string(new_fi, stringval);
2125 /* Instead of calling proto_item_set_len(), since we
2126 * don't yet have a proto_item, we set the
2127 * field_info's length ourselves.
2129 * XXX - our caller can't use that length to
2130 * advance an offset unless they arrange that
2131 * there always be a protocol tree into which
2132 * we're putting this item.
2134 new_fi->length = length;
2138 stringval = get_stringz_value(wmem_packet_scope(),
2139 tree, tvb, start, length, &length, encoding);
2140 proto_tree_set_string(new_fi, stringval);
2142 /* Instead of calling proto_item_set_len(),
2143 * since we don't yet have a proto_item, we
2144 * set the field_info's length ourselves.
2146 * XXX - our caller can't use that length to
2147 * advance an offset unless they arrange that
2148 * there always be a protocol tree into which
2149 * we're putting this item.
2151 new_fi->length = length;
2154 case FT_UINT_STRING:
2156 * NOTE: to support code written when
2157 * proto_tree_add_item() took a gboolean as its
2158 * last argument, with FALSE meaning "big-endian"
2159 * and TRUE meaning "little-endian", if the
2160 * encoding value is TRUE, treat that as
2161 * ASCII with a little-endian length.
2163 * This won't work for code that passes
2164 * arbitrary non-zero values; that code
2165 * will need to be fixed.
2167 if (encoding == TRUE)
2168 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2169 stringval = get_uint_string_value(wmem_packet_scope(),
2170 tree, tvb, start, length, &length, encoding);
2171 proto_tree_set_string(new_fi, stringval);
2173 /* Instead of calling proto_item_set_len(), since we
2174 * don't yet have a proto_item, we set the
2175 * field_info's length ourselves.
2177 * XXX - our caller can't use that length to
2178 * advance an offset unless they arrange that
2179 * there always be a protocol tree into which
2180 * we're putting this item.
2182 new_fi->length = length;
2186 stringval = get_stringzpad_value(wmem_packet_scope(),
2187 tvb, start, length, &length, encoding);
2188 proto_tree_set_string(new_fi, stringval);
2190 /* Instead of calling proto_item_set_len(), since we
2191 * don't yet have a proto_item, we set the
2192 * field_info's length ourselves.
2194 * XXX - our caller can't use that length to
2195 * advance an offset unless they arrange that
2196 * there always be a protocol tree into which
2197 * we're putting this item.
2199 new_fi->length = length;
2202 case FT_ABSOLUTE_TIME:
2204 * Absolute times can be in any of a number of
2205 * formats, and they can be big-endian or
2208 * Historically FT_TIMEs were only timespecs;
2209 * the only question was whether they were stored
2210 * in big- or little-endian format.
2212 * For backwards compatibility, we interpret an
2213 * encoding of 1 as meaning "little-endian timespec",
2214 * so that passing TRUE is interpreted as that.
2216 if (encoding == TRUE)
2217 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2219 if (length != 8 && length != 4) {
2220 length_error = length < 4 ? TRUE : FALSE;
2221 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2224 get_time_value(tvb, start, length, encoding, &time_stamp, FALSE);
2226 proto_tree_set_time(new_fi, &time_stamp);
2229 case FT_RELATIVE_TIME:
2231 * Relative times can be in any of a number of
2232 * formats, and they can be big-endian or
2235 * Historically FT_TIMEs were only timespecs;
2236 * the only question was whether they were stored
2237 * in big- or little-endian format.
2239 * For backwards compatibility, we interpret an
2240 * encoding of 1 as meaning "little-endian timespec",
2241 * so that passing TRUE is interpreted as that.
2243 if (encoding == TRUE)
2244 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2246 if (length != 8 && length != 4) {
2247 length_error = length < 4 ? TRUE : FALSE;
2248 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2251 get_time_value(tvb, start, length, encoding, &time_stamp, TRUE);
2253 proto_tree_set_time(new_fi, &time_stamp);
2255 case FT_IEEE_11073_SFLOAT:
2257 encoding = ENC_LITTLE_ENDIAN;
2259 length_error = length < 2 ? TRUE : FALSE;
2260 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2263 fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2266 case FT_IEEE_11073_FLOAT:
2268 encoding = ENC_LITTLE_ENDIAN;
2270 length_error = length < 4 ? TRUE : FALSE;
2271 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2276 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2277 new_fi->hfinfo->type,
2278 ftype_name(new_fi->hfinfo->type));
2279 DISSECTOR_ASSERT_NOT_REACHED();
2282 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2284 /* Don't add new node to proto_tree until now so that any exceptions
2285 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2286 /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2287 * to know which item caused exception? */
2288 pi = proto_tree_add_node(tree, new_fi);
2294 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2295 const gint start, gint length,
2296 const guint encoding, gint32 *retval)
2298 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2302 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2304 switch (hfinfo->type){
2311 DISSECTOR_ASSERT_NOT_REACHED();
2314 /* length validation for native number encoding caught by get_uint_value() */
2315 /* length has to be -1 or > 0 regardless of encoding */
2316 if (length < -1 || length == 0)
2317 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2318 "Invalid length %d passed to proto_tree_add_item_ret_int",
2321 if (encoding & ENC_STRING) {
2322 REPORT_DISSECTOR_BUG("wrong encoding");
2324 /* I believe it's ok if this is called with a NULL tree */
2325 value = get_int_value(tree, tvb, start, length, encoding);
2330 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, length);
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 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5120 number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
5122 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5125 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
5127 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5130 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5131 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5133 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5135 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5138 offset_e = (int)strlen(expr);
5150 number64 = IS_FT_INT(hfinfo->type) ?
5151 (guint64) fvalue_get_sinteger64(&finfo->value) :
5152 fvalue_get_uinteger64(&finfo->value);
5154 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5155 gchar tmp[ITEM_LABEL_LENGTH];
5156 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
5158 DISSECTOR_ASSERT(fmtfunc64);
5159 fmtfunc64(tmp, number64);
5160 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5161 } else if (hfinfo->strings) {
5162 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
5165 number_out = hfinfo_number_value_format_display64(hfinfo, BASE_DEC, number_buf, number64);
5167 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5170 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
5172 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5175 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5176 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5178 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
5180 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5183 offset_e = (int)strlen(expr);
5187 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
5188 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5189 wmem_free(NULL, str);
5193 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&finfo->value);
5194 n_addr = ipv4_get_net_order_addr(ipv4);
5195 set_address (&addr, AT_IPv4, 4, &n_addr);
5196 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5197 offset_r = (int)strlen(result);
5201 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
5202 set_address (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
5203 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5204 offset_r = (int)strlen(result);
5208 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
5209 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5210 offset_r = (int)strlen(result);
5214 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
5215 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5216 offset_r = (int)strlen(result);
5220 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
5221 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5222 wmem_free(NULL, str);
5226 bytes = (guint8 *)fvalue_get(&finfo->value);
5227 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5228 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5229 wmem_free(NULL, str);
5231 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5232 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5233 wmem_free(NULL, str);
5237 bytes = (guint8 *)fvalue_get(&finfo->value);
5238 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5239 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5240 wmem_free(NULL, str);
5242 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5243 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5244 wmem_free(NULL, str);
5248 bytes = (guint8 *)fvalue_get(&finfo->value);
5249 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
5250 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5251 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5252 wmem_free(NULL, str);
5256 g_snprintf(result+offset_r, size-offset_r,
5257 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
5258 offset_r = (int)strlen(result);
5262 g_snprintf(result+offset_r, size-offset_r,
5263 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
5264 offset_r = (int)strlen(result);
5269 case FT_UINT_STRING:
5271 bytes = (guint8 *)fvalue_get(&finfo->value);
5272 offset_r += protoo_strlcpy(result+offset_r,
5273 hfinfo_format_text(hfinfo, bytes),
5277 case FT_IEEE_11073_SFLOAT:
5278 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5279 g_snprintf(result+offset_r, size-offset_r,
5282 wmem_free(NULL, str);
5283 offset_r = (int)strlen(result);
5286 case FT_IEEE_11073_FLOAT:
5287 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5288 g_snprintf(result+offset_r, size-offset_r,
5291 offset_r = (int)strlen(result);
5292 wmem_free(NULL, str);
5295 case FT_IPXNET: /*XXX really No column custom ?*/
5298 g_error("hfinfo->type %d (%s) not handled\n",
5300 ftype_name(hfinfo->type));
5301 DISSECTOR_ASSERT_NOT_REACHED();
5307 switch (hfinfo->type) {
5331 /* for these types, "expr" is filled in the loop above */
5335 /* for all others, just copy "result" to "expr" */
5336 g_strlcpy(expr, result, size);
5341 /* Store abbrev for return value */
5342 abbrev = hfinfo->abbrev;
5345 if (occurrence == 0) {
5346 /* Fetch next hfinfo with same name (abbrev) */
5347 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5354 return abbrev ? abbrev : "";
5358 /* Set text of proto_item after having already been created. */
5360 proto_item_set_text(proto_item *pi, const char *format, ...)
5362 field_info *fi = NULL;
5365 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5367 fi = PITEM_FINFO(pi);
5372 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
5376 va_start(ap, format);
5377 proto_tree_set_representation(pi, format, ap);
5381 /* Append to text of proto_item after having already been created. */
5383 proto_item_append_text(proto_item *pi, const char *format, ...)
5385 field_info *fi = NULL;
5389 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5391 fi = PITEM_FINFO(pi);
5396 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5398 * If we don't already have a representation,
5399 * generate the default representation.
5401 if (fi->rep == NULL) {
5402 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5403 proto_item_fill_label(fi, fi->rep->representation);
5406 curlen = strlen(fi->rep->representation);
5407 if (ITEM_LABEL_LENGTH > curlen) {
5408 va_start(ap, format);
5409 g_vsnprintf(fi->rep->representation + curlen,
5410 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
5416 /* Prepend to text of proto_item after having already been created. */
5418 proto_item_prepend_text(proto_item *pi, const char *format, ...)
5420 field_info *fi = NULL;
5421 char representation[ITEM_LABEL_LENGTH];
5424 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5426 fi = PITEM_FINFO(pi);
5431 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5433 * If we don't already have a representation,
5434 * generate the default representation.
5436 if (fi->rep == NULL) {
5437 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5438 proto_item_fill_label(fi, representation);
5440 g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
5442 va_start(ap, format);
5443 g_vsnprintf(fi->rep->representation,
5444 ITEM_LABEL_LENGTH, format, ap);
5446 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
5451 proto_item_set_len(proto_item *pi, const gint length)
5455 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5457 fi = PITEM_FINFO(pi);
5461 DISSECTOR_ASSERT(length >= 0);
5462 fi->length = length;
5465 * You cannot just make the "len" field of a GByteArray
5466 * larger, if there's no data to back that length;
5467 * you can only make it smaller.
5469 if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
5470 fi->value.value.bytes->len = length;
5474 * Sets the length of the item based on its start and on the specified
5475 * offset, which is the offset past the end of the item; as the start
5476 * in the item is relative to the beginning of the data source tvbuff,
5477 * we need to pass in a tvbuff - the end offset is relative to the beginning
5481 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
5485 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5487 fi = PITEM_FINFO(pi);
5491 end += tvb_raw_offset(tvb);
5492 DISSECTOR_ASSERT(end >= fi->start);
5493 fi->length = end - fi->start;
5497 proto_item_get_len(const proto_item *pi)
5499 field_info *fi = PITEM_FINFO(pi);
5500 return fi ? fi->length : -1;
5504 proto_tree_create_root(packet_info *pinfo)
5508 /* Initialize the proto_node */
5509 pnode = g_slice_new(proto_tree);
5510 PROTO_NODE_INIT(pnode);
5511 pnode->parent = NULL;
5512 PNODE_FINFO(pnode) = NULL;
5513 pnode->tree_data = g_slice_new(tree_data_t);
5515 /* Make sure we can access pinfo everywhere */
5516 pnode->tree_data->pinfo = pinfo;
5518 /* Don't initialize the tree_data_t. Wait until we know we need it */
5519 pnode->tree_data->interesting_hfids = NULL;
5521 /* Set the default to FALSE so it's easier to
5522 * find errors; if we expect to see the protocol tree
5523 * but for some reason the default 'visible' is not
5524 * changed, then we'll find out very quickly. */
5525 pnode->tree_data->visible = FALSE;
5527 /* Make sure that we fake protocols (if possible) */
5528 pnode->tree_data->fake_protocols = TRUE;
5530 /* Keep track of the number of children */
5531 pnode->tree_data->count = 0;
5533 return (proto_tree *)pnode;
5537 /* "prime" a proto_tree with a single hfid that a dfilter
5538 * is interested in. */
5540 proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
5542 header_field_info *hfinfo;
5544 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
5545 /* this field is referenced by a filter so increase the refcount.
5546 also increase the refcount for the parent, i.e the protocol.
5548 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
5549 /* only increase the refcount if there is a parent.
5550 if this is a protocol and not a field then parent will be -1
5551 and there is no parent to add any refcounting for.
5553 if (hfinfo->parent != -1) {
5554 header_field_info *parent_hfinfo;
5555 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
5557 /* Mark parent as indirectly referenced unless it is already directly
5558 * referenced, i.e. the user has specified the parent in a filter.
5560 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
5561 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
5566 proto_item_add_subtree(proto_item *pi, const gint idx) {
5572 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
5574 fi = PITEM_FINFO(pi);
5576 return (proto_tree *)pi;
5578 fi->tree_type = idx;
5580 return (proto_tree *)pi;
5584 proto_item_get_subtree(proto_item *pi) {
5589 fi = PITEM_FINFO(pi);
5590 if ( (!fi) || (fi->tree_type == -1) )
5592 return (proto_tree *)pi;
5596 proto_item_get_parent(const proto_item *ti) {
5603 proto_item_get_parent_nth(proto_item *ti, int gen) {
5616 proto_tree_get_parent(proto_tree *tree) {
5619 return (proto_item *)tree;
5623 proto_tree_get_parent_tree(proto_tree *tree) {
5627 /* we're the root tree, there's no parent
5628 return ourselves so the caller has at least a tree to attach to */
5632 return (proto_tree *)tree->parent;
5636 proto_tree_get_root(proto_tree *tree) {
5639 while (tree->parent) {
5640 tree = tree->parent;
5646 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
5647 proto_item *item_to_move)
5650 /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
5651 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
5653 /* This function doesn't generate any values. It only reorganizes the prococol tree
5654 * so we can bail out immediately if it isn't visible. */
5655 if (!tree || !PTREE_DATA(tree)->visible)
5658 DISSECTOR_ASSERT(item_to_move->parent == tree);
5659 DISSECTOR_ASSERT(fixed_item->parent == tree);
5661 /*** cut item_to_move out ***/
5663 /* is item_to_move the first? */
5664 if (tree->first_child == item_to_move) {
5665 /* simply change first child to next */
5666 tree->first_child = item_to_move->next;
5668 DISSECTOR_ASSERT(tree->last_child != item_to_move);
5670 proto_item *curr_item;
5671 /* find previous and change it's next */
5672 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
5673 if (curr_item->next == item_to_move) {
5678 DISSECTOR_ASSERT(curr_item);
5680 curr_item->next = item_to_move->next;
5682 /* fix last_child if required */
5683 if (tree->last_child == item_to_move) {
5684 tree->last_child = curr_item;
5688 /*** insert to_move after fixed ***/
5689 item_to_move->next = fixed_item->next;
5690 fixed_item->next = item_to_move;
5691 if (tree->last_child == fixed_item) {
5692 tree->last_child = item_to_move;
5697 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
5705 fi = PTREE_FINFO(tree);
5709 start += tvb_raw_offset(tvb);
5710 DISSECTOR_ASSERT(start >= 0);
5711 DISSECTOR_ASSERT(length >= 0);
5713 fi->appendix_start = start;
5714 fi->appendix_length = length;
5718 proto_register_protocol(const char *name, const char *short_name,
5719 const char *filter_name)
5721 protocol_t *protocol;
5722 const protocol_t *existing_protocol = NULL;
5723 header_field_info *hfinfo;
5725 const char *existing_name;
5729 gboolean found_invalid;
5732 * Make sure there's not already a protocol with any of those
5733 * names. Crash if there is, as that's an error in the code
5734 * or an inappropriate plugin.
5735 * This situation has to be fixed to not register more than one
5736 * protocol with the same name.
5738 * This is done by reducing the number of strcmp (and alike) calls
5739 * as much as possible, as this significally slows down startup time.
5741 * Drawback: As a hash value is used to reduce insert time,
5742 * this might lead to a hash collision.
5743 * However, although we have somewhat over 1000 protocols, we're using
5744 * a 32 bit int so this is very, very unlikely.
5747 key = (gint *)g_malloc (sizeof(gint));
5748 *key = wrs_str_hash(name);
5750 existing_name = (const char *)g_hash_table_lookup(proto_names, key);
5751 if (existing_name != NULL) {
5752 /* g_error will terminate the program */
5753 g_error("Duplicate protocol name \"%s\"!"
5754 " This might be caused by an inappropriate plugin or a development error.", name);
5756 g_hash_table_insert(proto_names, key, (gpointer)name);
5758 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5759 if (existing_protocol != NULL) {
5760 g_error("Duplicate protocol short_name \"%s\"!"
5761 " This might be caused by an inappropriate plugin or a development error.", short_name);
5764 found_invalid = FALSE;
5765 for (i = 0; filter_name[i]; i++) {
5767 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
5768 found_invalid = TRUE;
5771 if (found_invalid) {
5772 g_error("Protocol filter name \"%s\" has one or more invalid characters."
5773 " Allowed are lower characters, digits, '-', '_' and '.'."
5774 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5776 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5777 if (existing_protocol != NULL) {
5778 g_error("Duplicate protocol filter_name \"%s\"!"
5779 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5782 /* Add this protocol to the list of known protocols; the list
5783 is sorted by protocol short name. */
5784 protocol = g_new(protocol_t, 1);
5785 protocol->name = name;
5786 protocol->short_name = short_name;
5787 protocol->filter_name = filter_name;
5788 /*protocol->fields = g_ptr_array_new();*/
5789 /* Delegate until actually needed and use g_ptr_array_sized_new*/
5790 protocol->fields = NULL;
5791 protocol->is_enabled = TRUE; /* protocol is enabled by default */
5792 protocol->enabled_by_default = TRUE; /* see previous comment */
5793 protocol->can_toggle = TRUE;
5794 protocol->heur_list = NULL;
5795 /* list will be sorted later by name, when all protocols completed registering */
5796 protocols = g_list_prepend(protocols, protocol);
5797 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
5798 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
5800 /* Here we allocate a new header_field_info struct */
5801 hfinfo = g_slice_new(header_field_info);
5802 hfinfo->name = name;
5803 hfinfo->abbrev = filter_name;
5804 hfinfo->type = FT_PROTOCOL;
5805 hfinfo->display = BASE_NONE;
5806 hfinfo->strings = protocol;
5807 hfinfo->bitmask = 0;
5808 hfinfo->ref_type = HF_REF_TYPE_NONE;
5809 hfinfo->blurb = NULL;
5810 hfinfo->parent = -1; /* this field differentiates protos and fields */
5812 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
5813 protocol->proto_id = proto_id;
5818 proto_deregister_protocol(const char *short_name)
5820 protocol_t *protocol;
5821 header_field_info *hfinfo;
5826 proto_id = proto_get_id_by_short_name(short_name);
5827 protocol = find_protocol_by_id(proto_id);
5828 if (protocol == NULL)
5831 key = wrs_str_hash(protocol->name);
5832 g_hash_table_remove(proto_names, &key);
5834 g_hash_table_remove(proto_short_names, (gpointer)short_name);
5835 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
5837 if (protocol->fields) {
5838 for (i = 0; i < protocol->fields->len; i++) {
5839 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
5840 hfinfo_remove_from_gpa_name_map(hfinfo);
5841 expert_deregister_expertinfo(hfinfo->abbrev);
5842 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
5844 g_ptr_array_free(protocol->fields, TRUE);
5845 protocol->fields = NULL;
5848 /* Remove this protocol from the list of known protocols */
5849 protocols = g_list_remove(protocols, protocol);
5851 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
5852 g_hash_table_steal(gpa_name_map, protocol->filter_name);
5854 g_free(last_field_name);
5855 last_field_name = NULL;
5861 * Routines to use to iterate over the protocols.
5862 * The argument passed to the iterator routines is an opaque cookie to
5863 * their callers; it's the GList pointer for the current element in
5865 * The ID of the protocol is returned, or -1 if there is no protocol.
5868 proto_get_first_protocol(void **cookie)
5870 protocol_t *protocol;
5872 if (protocols == NULL)
5874 *cookie = protocols;
5875 protocol = (protocol_t *)protocols->data;
5876 return protocol->proto_id;
5880 proto_get_data_protocol(void *cookie)
5882 GList *list_item = (GList *)cookie;
5884 protocol_t *protocol = (protocol_t *)list_item->data;
5885 return protocol->proto_id;
5889 proto_get_next_protocol(void **cookie)
5891 GList *list_item = (GList *)*cookie;
5892 protocol_t *protocol;
5894 list_item = g_list_next(list_item);
5895 if (list_item == NULL)
5897 *cookie = list_item;
5898 protocol = (protocol_t *)list_item->data;
5899 return protocol->proto_id;
5902 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
5903 assume that the cookie stored by
5904 proto_get_(first|next)_protocol_field() will never have a
5905 value of NULL. So, to preserve this semantic, the cookie value
5906 below is adjusted so that the cookie value stored is 1 + the
5907 current (zero-based) array index.
5910 proto_get_first_protocol_field(const int proto_id, void **cookie)
5912 protocol_t *protocol = find_protocol_by_id(proto_id);
5914 if ((protocol == NULL) || (protocol->fields == NULL))
5917 *cookie = GUINT_TO_POINTER(0 + 1);
5918 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
5922 proto_get_next_protocol_field(const int proto_id, void **cookie)
5924 protocol_t *protocol = find_protocol_by_id(proto_id);
5925 guint i = GPOINTER_TO_UINT(*cookie) - 1;
5929 if ((protocol->fields == NULL) || (i >= protocol->fields->len))
5932 *cookie = GUINT_TO_POINTER(i + 1);
5933 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
5937 find_protocol_by_id(const int proto_id)
5939 header_field_info *hfinfo;
5944 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
5945 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
5946 return (protocol_t *)hfinfo->strings;
5950 proto_get_id(const protocol_t *protocol)
5952 return protocol->proto_id;
5956 proto_name_already_registered(const gchar *name)
5960 DISSECTOR_ASSERT_HINT(name, "No name present");
5962 key = wrs_str_hash(name);
5963 if (g_hash_table_lookup(proto_names, &key) != NULL)
5969 proto_get_id_by_filter_name(const gchar *filter_name)
5971 const protocol_t *protocol = NULL;
5973 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
5975 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5977 if (protocol == NULL)
5979 return protocol->proto_id;
5983 proto_get_id_by_short_name(const gchar *short_name)
5985 const protocol_t *protocol = NULL;
5987 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
5989 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5991 if (protocol == NULL)
5993 return protocol->proto_id;
5997 proto_get_protocol_name(const int proto_id)
5999 protocol_t *protocol;
6001 protocol = find_protocol_by_id(proto_id);
6003 if (protocol == NULL)
6005 return protocol->name;
6009 proto_get_protocol_short_name(const protocol_t *protocol)
6011 if (protocol == NULL)
6013 return protocol->short_name;
6017 proto_get_protocol_long_name(const protocol_t *protocol)
6019 if (protocol == NULL)
6021 return protocol->name;
6025 proto_get_protocol_filter_name(const int proto_id)
6027 protocol_t *protocol;
6029 protocol = find_protocol_by_id(proto_id);
6030 if (protocol == NULL)
6032 return protocol->filter_name;
6035 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
6037 heur_dtbl_entry_t* heuristic_dissector;
6039 if (protocol == NULL)
6042 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
6043 if (heuristic_dissector != NULL)
6045 protocol->heur_list = g_list_append (protocol->heur_list, heuristic_dissector);
6049 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
6051 if (protocol == NULL)
6054 g_list_foreach(protocol->heur_list, func, user_data);
6058 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
6059 gboolean *is_tcp, gboolean *is_udp,
6060 gboolean *is_sctp, gboolean *is_ssl,
6062 gboolean *is_lte_rlc)
6064 wmem_list_frame_t *protos = wmem_list_head(layers);
6066 const char *proto_name;
6068 /* Walk the list of a available protocols in the packet and
6069 find "major" ones. */
6070 /* It might make more sense to assemble and return a bitfield. */
6071 while (protos != NULL)
6073 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6074 proto_name = proto_get_protocol_filter_name(proto_id);
6076 if (is_ip && ((!strcmp(proto_name, "ip")) ||
6077 (!strcmp(proto_name, "ipv6")))) {
6079 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
6081 } else if (is_udp && !strcmp(proto_name, "udp")) {
6083 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
6085 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
6087 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
6089 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
6093 protos = wmem_list_frame_next(protos);
6098 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
6100 wmem_list_frame_t *protos = wmem_list_head(layers);
6104 /* Walk the list of a available protocols in the packet and
6105 find "major" ones. */
6106 /* It might make more sense to assemble and return a bitfield. */
6107 while (protos != NULL)
6109 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6110 name = proto_get_protocol_filter_name(proto_id);
6112 if (!strcmp(name, proto_name))
6117 protos = wmem_list_frame_next(protos);
6125 proto_is_protocol_enabled(const protocol_t *protocol)
6127 return protocol->is_enabled;
6131 proto_can_toggle_protocol(const int proto_id)
6133 protocol_t *protocol;
6135 protocol = find_protocol_by_id(proto_id);
6136 return protocol->can_toggle;
6140 proto_disable_by_default(const int proto_id)
6142 protocol_t *protocol;
6144 protocol = find_protocol_by_id(proto_id);
6145 DISSECTOR_ASSERT(protocol->can_toggle);
6146 protocol->is_enabled = FALSE;
6147 protocol->enabled_by_default = FALSE;
6151 proto_set_decoding(const int proto_id, const gboolean enabled)
6153 protocol_t *protocol;
6155 protocol = find_protocol_by_id(proto_id);
6156 DISSECTOR_ASSERT(protocol->can_toggle);
6157 protocol->is_enabled = enabled;
6161 proto_enable_all(void)
6163 protocol_t *protocol;
6164 GList *list_item = protocols;
6166 if (protocols == NULL)
6170 protocol = (protocol_t *)list_item->data;
6171 if (protocol->can_toggle && protocol->enabled_by_default)
6172 protocol->is_enabled = TRUE;
6173 list_item = g_list_next(list_item);
6178 proto_set_cant_toggle(const int proto_id)
6180 protocol_t *protocol;
6182 protocol = find_protocol_by_id(proto_id);
6183 protocol->can_toggle = FALSE;
6187 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
6189 if (proto != NULL) {
6190 g_ptr_array_add(proto->fields, hfi);
6193 return proto_register_field_init(hfi, parent);
6196 /* for use with static arrays only, since we don't allocate our own copies
6197 of the header_field_info struct contained within the hf_register_info struct */
6199 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
6201 hf_register_info *ptr = hf;
6205 proto = find_protocol_by_id(parent);
6207 if (proto->fields == NULL) {
6208 proto->fields = g_ptr_array_sized_new(num_records);
6211 for (i = 0; i < num_records; i++, ptr++) {
6213 * Make sure we haven't registered this yet.
6214 * Most fields have variables associated with them
6215 * that are initialized to -1; some have array elements,
6216 * or possibly uninitialized variables, so we also allow
6217 * 0 (which is unlikely to be the field ID we get back
6218 * from "proto_register_field_init()").
6220 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
6222 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
6223 ptr->hfinfo.abbrev);
6227 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
6232 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
6237 proto = find_protocol_by_id(parent);
6239 if (proto->fields == NULL) {
6240 proto->fields = g_ptr_array_sized_new(num_records);
6243 for (i = 0; i < num_records; i++) {
6245 * Make sure we haven't registered this yet.
6247 if (hfi[i].id != -1) {
6249 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6254 proto_register_field_common(proto, &hfi[i], parent);
6259 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
6264 proto = find_protocol_by_id(parent);
6266 if (proto->fields == NULL) {
6267 proto->fields = g_ptr_array_sized_new(num_records);
6271 for (i = 0; i < num_records; i++) {
6273 * Make sure we haven't registered this yet.
6275 if (hfi[i]->id != -1) {
6277 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6282 proto_register_field_common(proto, hfi[i], parent);
6286 /* deregister already registered fields */
6288 proto_deregister_field (const int parent, gint hf_id)
6290 header_field_info *hfi;
6294 g_free(last_field_name);
6295 last_field_name = NULL;
6297 if (hf_id == -1 || hf_id == 0)
6300 proto = find_protocol_by_id (parent);
6301 if (!proto || proto->fields == NULL) {
6305 for (i = 0; i < proto->fields->len; i++) {
6306 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
6307 if (hfi->id == hf_id) {
6308 /* Found the hf_id in this protocol */
6309 g_hash_table_steal(gpa_name_map, hfi->abbrev);
6310 g_ptr_array_remove_index_fast(proto->fields, i);
6311 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
6318 proto_add_deregistered_data (void *data)
6320 g_ptr_array_add(deregistered_data, data);
6324 free_deregistered_field (gpointer data, gpointer user_data _U_)
6326 header_field_info *hfi = (header_field_info *) data;
6327 gint hf_id = hfi->id;
6329 g_free((char *)hfi->name);
6330 g_free((char *)hfi->abbrev);
6331 g_free((char *)hfi->blurb);
6334 switch (hfi->type) {
6336 /* This is just an integer represented as a pointer */
6339 protocol_t *protocol = (protocol_t *)hfi->strings;
6340 g_free((gchar *)protocol->short_name);
6344 true_false_string *tf = (true_false_string *)hfi->strings;
6345 g_free ((gchar *)tf->true_string);
6346 g_free ((gchar *)tf->false_string);
6351 val64_string *vs64 = (val64_string *)hfi->strings;
6352 while (vs64->strptr) {
6353 g_free((gchar *)vs64->strptr);
6359 /* Other Integer types */
6360 value_string *vs = (value_string *)hfi->strings;
6361 while (vs->strptr) {
6362 g_free((gchar *)vs->strptr);
6368 if (hfi->type != FT_FRAMENUM) {
6369 g_free((void *)hfi->strings);
6373 if (hfi->parent == -1)
6374 g_slice_free(header_field_info, hfi);
6376 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
6380 free_deregistered_data (gpointer data, gpointer user_data _U_)
6385 /* free deregistered fields and data */
6387 proto_free_deregistered_fields (void)
6389 expert_free_deregistered_expertinfos();
6391 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
6392 g_ptr_array_free(deregistered_fields, TRUE);
6393 deregistered_fields = g_ptr_array_new();
6395 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
6396 g_ptr_array_free(deregistered_data, TRUE);
6397 deregistered_data = g_ptr_array_new();
6400 /* chars allowed in field abbrev */
6402 const guint8 fld_abbrev_chars[256] = {
6403 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
6404 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
6405 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
6406 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
6407 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
6408 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
6409 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
6410 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
6411 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
6412 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
6413 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
6414 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
6415 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
6416 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
6417 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
6418 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
6421 static const value_string hf_display[] = {
6422 { BASE_NONE, "BASE_NONE" },
6423 { BASE_DEC, "BASE_DEC" },
6424 { BASE_HEX, "BASE_HEX" },
6425 { BASE_OCT, "BASE_OCT" },
6426 { BASE_DEC_HEX, "BASE_DEC_HEX" },
6427 { BASE_HEX_DEC, "BASE_HEX_DEC" },
6428 { BASE_CUSTOM, "BASE_CUSTOM" },
6429 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
6430 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
6431 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
6432 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
6433 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
6434 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
6435 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
6436 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
6437 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
6438 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
6439 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
6440 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
6441 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
6442 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
6443 /* Alias: BASE_NONE { BASE_FLOAT, "BASE_FLOAT" }, */
6444 /* Alias: BASE_NONE { STR_ASCII, "STR_ASCII" }, */
6445 { STR_UNICODE, "STR_UNICODE" },
6446 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
6447 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
6448 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
6449 { BASE_PT_UDP, "BASE_PT_UDP" },
6450 { BASE_PT_TCP, "BASE_PT_TCP" },
6451 { BASE_PT_DCCP, "BASE_PT_DCCP" },
6452 { BASE_PT_SCTP, "BASE_PT_SCTP" },
6455 const char* proto_field_display_to_string(int field_display)
6457 return val_to_str_const(field_display, hf_display, "Unknown");
6460 static inline port_type
6461 display_to_port_type(field_display_e e)
6478 /* temporary function containing assert part for easier profiling */
6480 tmp_fld_check_assert(header_field_info *hfinfo)
6484 /* The field must have a name (with length > 0) */
6485 if (!hfinfo->name || !hfinfo->name[0]) {
6487 /* Try to identify the field */
6488 g_error("Field (abbrev='%s') does not have a name\n",
6492 g_error("Field does not have a name (nor an abbreviation)\n");
6495 /* fields with an empty string for an abbreviation aren't filterable */
6496 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
6497 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
6499 /* These types of fields are allowed to have value_strings,
6500 * true_false_strings or a protocol_t struct
6502 if (hfinfo->strings != NULL && !(
6503 (hfinfo->type == FT_CHAR) ||
6504 (hfinfo->type == FT_UINT8) ||
6505 (hfinfo->type == FT_UINT16) ||
6506 (hfinfo->type == FT_UINT24) ||
6507 (hfinfo->type == FT_UINT32) ||
6508 (hfinfo->type == FT_UINT40) ||
6509 (hfinfo->type == FT_UINT48) ||
6510 (hfinfo->type == FT_UINT56) ||
6511 (hfinfo->type == FT_UINT64) ||
6512 (hfinfo->type == FT_INT8) ||
6513 (hfinfo->type == FT_INT16) ||
6514 (hfinfo->type == FT_INT24) ||
6515 (hfinfo->type == FT_INT32) ||
6516 (hfinfo->type == FT_INT40) ||
6517 (hfinfo->type == FT_INT48) ||
6518 (hfinfo->type == FT_INT56) ||
6519 (hfinfo->type == FT_INT64) ||
6520 (hfinfo->type == FT_BOOLEAN) ||
6521 (hfinfo->type == FT_PROTOCOL) ||
6522 (hfinfo->type == FT_FRAMENUM) ))
6523 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
6524 " (which is not allowed to have strings)\n",
6525 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
6527 /* TODO: This check may slow down startup, and output quite a few warnings.
6528 It would be good to be able to enable this (and possibly other checks?)
6529 in non-release builds. */
6531 /* Check for duplicate value_string values.
6532 There are lots that have the same value *and* string, so for now only
6533 report those that have same value but different string. */
6534 if ((hfinfo->strings != NULL) &&
6535 !(hfinfo->display & BASE_RANGE_STRING) &&
6536 !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
6538 (hfinfo->type == FT_CHAR) ||
6539 (hfinfo->type == FT_UINT8) ||
6540 (hfinfo->type == FT_UINT16) ||
6541 (hfinfo->type == FT_UINT24) ||
6542 (hfinfo->type == FT_UINT32) ||
6543 (hfinfo->type == FT_INT8) ||
6544 (hfinfo->type == FT_INT16) ||
6545 (hfinfo->type == FT_INT24) ||
6546 (hfinfo->type == FT_INT32) ||
6547 (hfinfo->type == FT_FRAMENUM) )) {
6550 const value_string *start_values;
6551 const value_string *current;
6553 if (hfinfo->display & BASE_EXT_STRING)
6554 start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
6556 start_values = (const value_string*)hfinfo->strings;
6557 current = start_values;
6559 for (n=0; current; n++, current++) {
6560 /* Drop out if we reached the end. */
6561 if ((current->value == 0) && (current->strptr == NULL)) {
6565 /* Check value against all previous */
6566 for (m=0; m < n; m++) {
6567 /* There are lots of duplicates with the same string,
6568 so only report if different... */
6569 if ((start_values[m].value == current->value) &&
6570 (strcmp(start_values[m].strptr, current->strptr) != 0)) {
6571 ws_g_warning("Field '%s' (%s) has a conflicting entry in its"
6572 " value_string: %u is at indices %u (%s) and %u (%s))\n",
6573 hfinfo->name, hfinfo->abbrev,
6574 current->value, m, start_values[m].strptr, n, current->strptr);
6582 switch (hfinfo->type) {
6585 /* Require the char type to have BASE_HEX, BASE_OCT,
6586 * BASE_CUSTOM, or BASE_NONE as its base.
6588 * If the display value is BASE_NONE and there is a
6589 * strings conversion then the dissector writer is
6590 * telling us that the field's numerical value is
6591 * meaningless; we'll avoid showing the value to the
6594 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6597 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6600 if (hfinfo->strings == NULL)
6601 g_error("Field '%s' (%s) is an integral value (%s)"
6602 " but is being displayed as BASE_NONE but"
6603 " without a strings conversion",
6604 hfinfo->name, hfinfo->abbrev,
6605 ftype_name(hfinfo->type));
6608 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6609 g_error("Field '%s' (%s) is a character value (%s)"
6610 " but is being displayed as %s\n",
6611 hfinfo->name, hfinfo->abbrev,
6612 ftype_name(hfinfo->type), tmp_str);
6613 wmem_free(NULL, tmp_str);
6624 /* Hexadecimal and octal are, in printf() and everywhere
6625 * else, unsigned so don't allow dissectors to register a
6626 * signed field to be displayed unsigned. (Else how would
6627 * we display negative values?)
6629 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6634 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6635 g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
6636 hfinfo->name, hfinfo->abbrev,
6637 ftype_name(hfinfo->type), tmp_str);
6638 wmem_free(NULL, tmp_str);
6649 if (IS_BASE_PORT(hfinfo->display)) {
6650 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6651 if (hfinfo->type != FT_UINT16) {
6652 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
6653 hfinfo->name, hfinfo->abbrev,
6654 tmp_str, ftype_name(hfinfo->type));
6656 if (hfinfo->strings != NULL) {
6657 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
6658 hfinfo->name, hfinfo->abbrev,
6659 ftype_name(hfinfo->type), tmp_str);
6661 if (hfinfo->bitmask != 0) {
6662 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
6663 hfinfo->name, hfinfo->abbrev,
6664 ftype_name(hfinfo->type), tmp_str);
6666 wmem_free(NULL, tmp_str);
6670 /* Require integral types (other than frame number,
6671 * which is always displayed in decimal) to have a
6674 * If the display value is BASE_NONE and there is a
6675 * strings conversion then the dissector writer is
6676 * telling us that the field's numerical value is
6677 * meaningless; we'll avoid showing the value to the
6680 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6686 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6689 if (hfinfo->strings == NULL)
6690 g_error("Field '%s' (%s) is an integral value (%s)"
6691 " but is being displayed as BASE_NONE but"
6692 " without a strings conversion",
6693 hfinfo->name, hfinfo->abbrev,
6694 ftype_name(hfinfo->type));
6697 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6698 g_error("Field '%s' (%s) is an integral value (%s)"
6699 " but is being displayed as %s\n",
6700 hfinfo->name, hfinfo->abbrev,
6701 ftype_name(hfinfo->type), tmp_str);
6702 wmem_free(NULL, tmp_str);
6706 /* Require bytes to have a "display type" that could
6707 * add a character between displayed bytes.
6709 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6717 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6718 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",
6719 hfinfo->name, hfinfo->abbrev, tmp_str);
6720 wmem_free(NULL, tmp_str);
6722 if (hfinfo->bitmask != 0)
6723 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6724 hfinfo->name, hfinfo->abbrev,
6725 ftype_name(hfinfo->type));
6726 if (hfinfo->strings != NULL)
6727 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6728 hfinfo->name, hfinfo->abbrev,
6729 ftype_name(hfinfo->type));
6734 if (hfinfo->display != BASE_NONE) {
6735 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6736 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6737 hfinfo->name, hfinfo->abbrev,
6738 ftype_name(hfinfo->type), tmp_str);
6739 wmem_free(NULL, tmp_str);
6741 if (hfinfo->bitmask != 0)
6742 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6743 hfinfo->name, hfinfo->abbrev,
6744 ftype_name(hfinfo->type));
6750 case FT_ABSOLUTE_TIME:
6751 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
6752 hfinfo->display == ABSOLUTE_TIME_UTC ||
6753 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
6754 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6755 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
6756 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
6757 wmem_free(NULL, tmp_str);
6759 if (hfinfo->bitmask != 0)
6760 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6761 hfinfo->name, hfinfo->abbrev,
6762 ftype_name(hfinfo->type));
6767 case FT_UINT_STRING:
6769 switch (hfinfo->display) {
6775 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6776 g_error("Field '%s' (%s) is an string value (%s)"
6777 " but is being displayed as %s\n",
6778 hfinfo->name, hfinfo->abbrev,
6779 ftype_name(hfinfo->type), tmp_str);
6780 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));
6794 switch (hfinfo->display) {
6800 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6801 g_error("Field '%s' (%s) is an IPv4 value (%s)"
6802 " but is being displayed as %s\n",
6803 hfinfo->name, hfinfo->abbrev,
6804 ftype_name(hfinfo->type), tmp_str);
6805 wmem_free(NULL, tmp_str);
6810 if (hfinfo->display != BASE_NONE) {
6811 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6812 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6813 hfinfo->name, hfinfo->abbrev,
6814 ftype_name(hfinfo->type),
6816 wmem_free(NULL, tmp_str);
6818 if (hfinfo->bitmask != 0)
6819 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6820 hfinfo->name, hfinfo->abbrev,
6821 ftype_name(hfinfo->type));
6822 if (hfinfo->strings != NULL)
6823 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6824 hfinfo->name, hfinfo->abbrev,
6825 ftype_name(hfinfo->type));
6830 #ifdef ENABLE_CHECK_FILTER
6832 _ftype_common(enum ftenum type)
6856 case FT_UINT_STRING:
6869 case FT_ABSOLUTE_TIME:
6870 case FT_RELATIVE_TIME:
6871 return FT_ABSOLUTE_TIME;
6880 register_type_length_mismatch(void)
6882 static ei_register_info ei[] = {
6883 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
6884 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
6887 expert_module_t* expert_type_length_mismatch;
6889 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
6891 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
6892 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
6894 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
6895 disabling them makes no sense. */
6896 proto_set_cant_toggle(proto_type_length_mismatch);
6900 register_number_string_decoding_error(void)
6902 static ei_register_info ei[] = {
6903 { &ei_number_string_decoding_failed_error,
6904 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
6905 "Failed to decode number from string", EXPFILL
6908 { &ei_number_string_decoding_erange_error,
6909 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
6910 "Decoded number from string is out of valid range", EXPFILL
6915 expert_module_t* expert_number_string_decoding_error;
6917 proto_number_string_decoding_error =
6918 proto_register_protocol("Number-String Decoding Error",
6919 "Number-string decoding error",
6920 "_ws.number_string.decoding_error");
6922 expert_number_string_decoding_error =
6923 expert_register_protocol(proto_number_string_decoding_error);
6924 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
6926 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
6927 disabling them makes no sense. */
6928 proto_set_cant_toggle(proto_number_string_decoding_error);
6931 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (183000+PRE_ALLOC_EXPERT_FIELDS_MEM)
6933 proto_register_field_init(header_field_info *hfinfo, const int parent)
6936 tmp_fld_check_assert(hfinfo);
6938 hfinfo->parent = parent;
6939 hfinfo->same_name_next = NULL;
6940 hfinfo->same_name_prev_id = -1;
6942 /* if we always add and never delete, then id == len - 1 is correct */
6943 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
6944 if (!gpa_hfinfo.hfi) {
6945 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
6946 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
6948 gpa_hfinfo.allocated_len += 1000;
6949 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
6950 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
6951 /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
6954 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
6956 hfinfo->id = gpa_hfinfo.len - 1;
6958 /* if we have real names, enter this field in the name tree */
6959 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
6961 header_field_info *same_name_next_hfinfo;
6964 /* Check that the filter name (abbreviation) is legal;
6965 * it must contain only alphanumerics, '-', "_", and ".". */
6966 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
6968 if (g_ascii_isprint(c))
6969 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
6971 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
6972 DISSECTOR_ASSERT_NOT_REACHED();
6975 /* We allow multiple hfinfo's to be registered under the same
6976 * abbreviation. This was done for X.25, as, depending
6977 * on whether it's modulo-8 or modulo-128 operation,
6978 * some bitfield fields may be in different bits of
6979 * a byte, and we want to be able to refer to that field
6980 * with one name regardless of whether the packets
6981 * are modulo-8 or modulo-128 packets. */
6983 same_name_hfinfo = NULL;
6985 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
6986 /* GLIB 2.x - if it is already present
6987 * the previous hfinfo with the same name is saved
6988 * to same_name_hfinfo by value destroy callback */
6989 if (same_name_hfinfo) {
6990 /* There's already a field with this name.
6991 * Put the current field *before* that field
6992 * in the list of fields with this name, Thus,
6993 * we end up with an effectively
6994 * doubly-linked-list of same-named hfinfo's,
6995 * with the head of the list (stored in the
6996 * hash) being the last seen hfinfo.
6998 same_name_next_hfinfo =
6999 same_name_hfinfo->same_name_next;
7001 hfinfo->same_name_next = same_name_next_hfinfo;
7002 if (same_name_next_hfinfo)
7003 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
7005 same_name_hfinfo->same_name_next = hfinfo;
7006 hfinfo->same_name_prev_id = same_name_hfinfo->id;
7007 #ifdef ENABLE_CHECK_FILTER
7008 while (same_name_hfinfo) {
7009 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
7010 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));
7011 same_name_hfinfo = same_name_hfinfo->same_name_next;
7021 proto_register_subtree_array(gint *const *indices, const int num_indices)
7024 gint *const *ptr = indices;
7027 * If we've already allocated the array of tree types, expand
7028 * it; this lets plugins such as mate add tree types after
7029 * the initial startup. (If we haven't already allocated it,
7030 * we don't allocate it; on the first pass, we just assign
7031 * ett values and keep track of how many we've assigned, and
7032 * when we're finished registering all dissectors we allocate
7033 * the array, so that we do only one allocation rather than
7034 * wasting CPU time and memory by growing the array for each
7035 * dissector that registers ett values.)
7037 if (tree_is_expanded != NULL) {
7038 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
7040 /* set new items to 0 */
7041 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
7042 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
7043 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
7047 * Assign "num_indices" subtree numbers starting at "num_tree_types",
7048 * returning the indices through the pointers in the array whose
7049 * first element is pointed to by "indices", and update
7050 * "num_tree_types" appropriately.
7052 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
7054 /* g_error will terminate the program */
7055 g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
7056 " This is a development error:"
7057 " Either the subtree item type has already been assigned or"
7058 " was not initialized to -1.");
7060 **ptr = num_tree_types;
7065 label_concat(char *label_str, gsize pos, const char *str)
7067 if (pos < ITEM_LABEL_LENGTH)
7068 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
7074 label_mark_truncated(char *label_str, gsize name_pos)
7076 static const char trunc_str[] = " [truncated]";
7077 const size_t trunc_len = sizeof(trunc_str)-1;
7080 /* ..... field_name: dataaaaaaaaaaaaa
7084 * ..... field_name [truncated]: dataaaaaaaaaaaaa
7086 * name_pos==0 means that we have only data or only a field_name
7089 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
7090 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
7091 memcpy(label_str + name_pos, trunc_str, trunc_len);
7093 /* in general, label_str is UTF-8
7094 we can truncate it only at the beginning of a new character
7095 we go backwards from the byte right after our buffer and
7096 find the next starting byte of a UTF-8 character, this is
7098 there's no need to use g_utf8_find_prev_char(), the search
7099 will always succeed since we copied trunc_str into the
7101 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH]);
7104 } else if (name_pos < ITEM_LABEL_LENGTH)
7105 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
7109 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
7113 /* "%s: %s", hfinfo->name, text */
7114 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
7115 pos = label_concat(label_str, pos, ": ");
7116 pos = label_concat(label_str, pos, text ? text : "(null)");
7118 if (pos >= ITEM_LABEL_LENGTH) {
7119 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7120 label_mark_truncated(label_str, name_pos);
7127 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
7131 /* "%s: %s (%s)", hfinfo->name, text, descr */
7132 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
7133 pos = label_concat(label_str, pos, ": ");
7134 pos = label_concat(label_str, pos, text ? text : "(null)");
7135 pos = label_concat(label_str, pos, " (");
7136 pos = label_concat(label_str, pos, descr ? descr : "(null)");
7137 pos = label_concat(label_str, pos, ")");
7139 if (pos >= ITEM_LABEL_LENGTH) {
7140 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7141 label_mark_truncated(label_str, name_pos);
7148 proto_item_fill_label(field_info *fi, gchar *label_str)
7150 header_field_info *hfinfo;
7154 ipv4_addr_and_mask *ipv4;
7156 guint32 n_addr; /* network-order IPv4 address */
7165 /* XXX: Check validity of hfinfo->type */
7169 hfinfo = fi->hfinfo;
7171 switch (hfinfo->type) {
7174 g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
7178 fill_label_boolean(fi, label_str);
7183 bytes = (guint8 *)fvalue_get(&fi->value);
7186 switch(hfinfo->display)
7189 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
7192 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
7195 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
7198 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7202 if (prefs.display_byte_fields_with_spaces)
7204 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7208 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
7212 label_fill(label_str, 0, hfinfo, str);
7213 wmem_free(NULL, str);
7215 if (hfinfo->display & BASE_ALLOW_ZERO) {
7216 label_fill(label_str, 0, hfinfo, "<none>");
7218 label_fill(label_str, 0, hfinfo, "<MISSING>");
7224 if (hfinfo->bitmask) {
7225 fill_label_bitfield_char(fi, label_str);
7227 fill_label_char(fi, label_str);
7231 /* Four types of integers to take care of:
7232 * Bitfield, with val_string
7233 * Bitfield, w/o val_string
7234 * Non-bitfield, with val_string
7235 * Non-bitfield, w/o val_string
7241 if (hfinfo->bitmask) {
7242 fill_label_bitfield(fi, label_str, FALSE);
7244 fill_label_number(fi, label_str, FALSE);
7249 fill_label_number(fi, label_str, FALSE);
7256 if (hfinfo->bitmask) {
7257 fill_label_bitfield64(fi, label_str, FALSE);
7259 fill_label_number64(fi, label_str, FALSE);
7267 if (hfinfo->bitmask) {
7268 fill_label_bitfield(fi, label_str, TRUE);
7270 fill_label_number(fi, label_str, TRUE);
7278 if (hfinfo->bitmask) {
7279 fill_label_bitfield64(fi, label_str, TRUE);
7281 fill_label_number64(fi, label_str, TRUE);
7286 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7287 "%s: %." G_STRINGIFY(FLT_DIG) "g",
7288 hfinfo->name, fvalue_get_floating(&fi->value));
7292 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7293 "%s: %." G_STRINGIFY(DBL_DIG) "g",
7294 hfinfo->name, fvalue_get_floating(&fi->value));
7297 case FT_ABSOLUTE_TIME:
7298 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
7299 label_fill(label_str, 0, hfinfo, tmp);
7300 wmem_free(NULL, tmp);
7303 case FT_RELATIVE_TIME:
7304 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
7305 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7306 "%s: %s seconds", hfinfo->name, tmp);
7307 wmem_free(NULL, tmp);
7311 integer = fvalue_get_uinteger(&fi->value);
7312 tmp = get_ipxnet_name(NULL, integer);
7313 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7314 "%s: %s (0x%08X)", hfinfo->name,
7316 wmem_free(NULL, tmp);
7320 addr.type = AT_AX25;
7321 addr.len = AX25_ADDR_LEN;
7322 addr.data = (guint8 *)fvalue_get(&fi->value);
7324 addr_str = (char*)address_to_str(NULL, &addr);
7325 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7326 "%s: %s", hfinfo->name, addr_str);
7327 wmem_free(NULL, addr_str);
7331 addr.type = vines_address_type;
7332 addr.len = VINES_ADDR_LEN;
7333 addr.data = (guint8 *)fvalue_get(&fi->value);
7335 addr_str = (char*)address_to_str(NULL, &addr);
7336 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7337 "%s: %s", hfinfo->name, addr_str);
7338 wmem_free(NULL, addr_str);
7342 bytes = (guint8 *)fvalue_get(&fi->value);
7344 addr.type = AT_ETHER;
7348 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7349 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7350 "%s: %s", hfinfo->name, addr_str);
7351 wmem_free(NULL, addr_str);
7355 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&fi->value);
7356 n_addr = ipv4_get_net_order_addr(ipv4);
7358 addr.type = AT_IPv4;
7360 addr.data = &n_addr;
7362 if (hfinfo->display == BASE_NETMASK)
7364 addr_str = (char*)address_to_str(NULL, &addr);
7368 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7370 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7371 "%s: %s", hfinfo->name, addr_str);
7372 wmem_free(NULL, addr_str);
7376 bytes = (guint8 *)fvalue_get(&fi->value);
7378 addr.type = AT_IPv6;
7382 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7383 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7384 "%s: %s", hfinfo->name, addr_str);
7385 wmem_free(NULL, addr_str);
7389 addr.type = AT_FCWWN;
7390 addr.len = FCWWN_ADDR_LEN;
7391 addr.data = (guint8 *)fvalue_get(&fi->value);
7393 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7394 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7395 "%s: %s", hfinfo->name, addr_str);
7396 wmem_free(NULL, addr_str);
7400 guid = (e_guid_t *)fvalue_get(&fi->value);
7401 tmp = guid_to_str(NULL, guid);
7402 label_fill(label_str, 0, hfinfo, tmp);
7403 wmem_free(NULL, tmp);
7407 bytes = (guint8 *)fvalue_get(&fi->value);
7408 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7409 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7411 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7412 wmem_free(NULL, name);
7414 label_fill(label_str, 0, hfinfo, tmp);
7416 wmem_free(NULL, tmp);
7420 bytes = (guint8 *)fvalue_get(&fi->value);
7421 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7422 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7424 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7425 wmem_free(NULL, name);
7427 label_fill(label_str, 0, hfinfo, tmp);
7429 wmem_free(NULL, tmp);
7433 bytes = (guint8 *)fvalue_get(&fi->value);
7434 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
7435 label_fill(label_str, 0, hfinfo, tmp);
7436 wmem_free(NULL, tmp);
7440 integer64 = fvalue_get_uinteger64(&fi->value);
7441 addr_str = eui64_to_str(NULL, integer64);
7442 tmp = (char*)eui64_to_display(NULL, integer64);
7443 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
7444 wmem_free(NULL, tmp);
7445 wmem_free(NULL, addr_str);
7449 case FT_UINT_STRING:
7451 bytes = (guint8 *)fvalue_get(&fi->value);
7452 label_fill(label_str, 0, hfinfo, hfinfo_format_text(hfinfo, bytes));
7455 case FT_IEEE_11073_SFLOAT:
7456 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7457 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7460 wmem_free(NULL, tmp);
7462 case FT_IEEE_11073_FLOAT:
7463 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7464 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7467 wmem_free(NULL, tmp);
7471 g_error("hfinfo->type %d (%s) not handled\n",
7472 hfinfo->type, ftype_name(hfinfo->type));
7473 DISSECTOR_ASSERT_NOT_REACHED();
7479 fill_label_boolean(field_info *fi, gchar *label_str)
7481 char *p = label_str;
7482 int bitfield_byte_length = 0, bitwidth;
7483 guint64 unshifted_value;
7486 header_field_info *hfinfo = fi->hfinfo;
7487 const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
7489 if (hfinfo->strings) {
7490 tfstring = (const struct true_false_string*) hfinfo->strings;
7493 value = fvalue_get_uinteger64(&fi->value);
7494 if (hfinfo->bitmask) {
7495 /* Figure out the bit width */
7496 bitwidth = hfinfo_container_bitwidth(hfinfo);
7499 unshifted_value = value;
7500 unshifted_value <<= hfinfo_bitshift(hfinfo);
7502 /* Create the bitfield first */
7503 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7504 bitfield_byte_length = (int) (p - label_str);
7507 /* Fill in the textual info */
7508 label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
7512 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
7514 if (hfinfo->display & BASE_RANGE_STRING)
7515 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
7517 if (hfinfo->display & BASE_EXT_STRING)
7518 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
7520 if (hfinfo->display & BASE_VAL64_STRING)
7521 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7523 return try_val_to_str(value, (const value_string *) hfinfo->strings);
7527 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
7529 if (hfinfo->display & BASE_VAL64_STRING)
7530 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7532 if (hfinfo->display & BASE_RANGE_STRING)
7533 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
7535 /* If this is reached somebody registered a 64-bit field with a 32-bit
7536 * value-string, which isn't right. */
7537 DISSECTOR_ASSERT_NOT_REACHED();
7539 /* This is necessary to squelch MSVC errors; is there
7540 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
7546 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
7548 const char *str = hf_try_val_to_str(value, hfinfo);
7550 return (str) ? str : unknown_str;
7554 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
7556 const char *str = hf_try_val64_to_str(value, hfinfo);
7558 return (str) ? str : unknown_str;
7561 /* Fills data for bitfield chars with val_strings */
7563 fill_label_bitfield_char(field_info *fi, gchar *label_str)
7566 int bitfield_byte_length, bitwidth;
7567 guint32 unshifted_value;
7573 header_field_info *hfinfo = fi->hfinfo;
7575 /* Figure out the bit width */
7576 bitwidth = hfinfo_container_bitwidth(hfinfo);
7579 value = fvalue_get_uinteger(&fi->value);
7581 unshifted_value = value;
7582 if (hfinfo->bitmask) {
7583 unshifted_value <<= hfinfo_bitshift(hfinfo);
7586 /* Create the bitfield first */
7587 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7588 bitfield_byte_length = (int) (p - label_str);
7590 /* Fill in the textual info using stored (shifted) value */
7591 if (hfinfo->display == BASE_CUSTOM) {
7592 gchar tmp[ITEM_LABEL_LENGTH];
7593 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7595 DISSECTOR_ASSERT(fmtfunc);
7596 fmtfunc(tmp, value);
7597 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7599 else if (hfinfo->strings) {
7600 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7602 out = hfinfo_char_vals_format(hfinfo, buf, value);
7603 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7604 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7606 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7609 out = hfinfo_char_value_format(hfinfo, buf, value);
7611 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7615 /* Fills data for bitfield ints with val_strings */
7617 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
7620 int bitfield_byte_length, bitwidth;
7621 guint32 unshifted_value;
7627 header_field_info *hfinfo = fi->hfinfo;
7629 /* Figure out the bit width */
7630 bitwidth = hfinfo_container_bitwidth(hfinfo);
7634 value = fvalue_get_sinteger(&fi->value);
7636 value = fvalue_get_uinteger(&fi->value);
7638 unshifted_value = value;
7639 if (hfinfo->bitmask) {
7640 unshifted_value <<= hfinfo_bitshift(hfinfo);
7643 /* Create the bitfield first */
7644 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7645 bitfield_byte_length = (int) (p - label_str);
7647 /* Fill in the textual info using stored (shifted) value */
7648 if (hfinfo->display == BASE_CUSTOM) {
7649 gchar tmp[ITEM_LABEL_LENGTH];
7650 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7652 DISSECTOR_ASSERT(fmtfunc);
7653 fmtfunc(tmp, value);
7654 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7656 else if (hfinfo->strings) {
7657 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7659 out = hfinfo_number_vals_format(hfinfo, buf, value);
7660 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7661 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7663 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7666 out = hfinfo_number_value_format(hfinfo, buf, value);
7668 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7673 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
7676 int bitfield_byte_length, bitwidth;
7677 guint64 unshifted_value;
7683 header_field_info *hfinfo = fi->hfinfo;
7685 /* Figure out the bit width */
7686 bitwidth = hfinfo_container_bitwidth(hfinfo);
7690 value = fvalue_get_sinteger64(&fi->value);
7692 value = fvalue_get_uinteger64(&fi->value);
7694 unshifted_value = value;
7695 if (hfinfo->bitmask) {
7696 unshifted_value <<= hfinfo_bitshift(hfinfo);
7699 /* Create the bitfield first */
7700 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7701 bitfield_byte_length = (int) (p - label_str);
7703 /* Fill in the textual info using stored (shifted) value */
7704 if (hfinfo->display == BASE_CUSTOM) {
7705 gchar tmp[ITEM_LABEL_LENGTH];
7706 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7708 DISSECTOR_ASSERT(fmtfunc64);
7709 fmtfunc64(tmp, value);
7710 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7712 else if (hfinfo->strings) {
7713 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7715 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7716 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7717 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7719 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7722 out = hfinfo_number_value_format64(hfinfo, buf, value);
7724 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7729 fill_label_char(field_info *fi, gchar *label_str)
7731 header_field_info *hfinfo = fi->hfinfo;
7737 value = fvalue_get_uinteger(&fi->value);
7739 /* Fill in the textual info */
7740 if (hfinfo->display == BASE_CUSTOM) {
7741 gchar tmp[ITEM_LABEL_LENGTH];
7742 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7744 DISSECTOR_ASSERT(fmtfunc);
7745 fmtfunc(tmp, value);
7746 label_fill(label_str, 0, hfinfo, tmp);
7748 else if (hfinfo->strings) {
7749 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7751 out = hfinfo_char_vals_format(hfinfo, buf, value);
7752 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7755 out = hfinfo_char_value_format(hfinfo, buf, value);
7757 label_fill(label_str, 0, hfinfo, out);
7762 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
7764 header_field_info *hfinfo = fi->hfinfo;
7771 value = fvalue_get_sinteger(&fi->value);
7773 value = fvalue_get_uinteger(&fi->value);
7775 /* Fill in the textual info */
7776 if (hfinfo->display == BASE_CUSTOM) {
7777 gchar tmp[ITEM_LABEL_LENGTH];
7778 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7780 DISSECTOR_ASSERT(fmtfunc);
7781 fmtfunc(tmp, value);
7782 label_fill(label_str, 0, hfinfo, tmp);
7784 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7786 * It makes no sense to have a value-string table for a
7787 * frame-number field - they're just integers giving
7788 * the ordinal frame number.
7790 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7792 out = hfinfo_number_vals_format(hfinfo, buf, value);
7793 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7794 label_fill(label_str, 0, hfinfo, val_str);
7796 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7798 else if (IS_BASE_PORT(hfinfo->display)) {
7799 gchar tmp[ITEM_LABEL_LENGTH];
7801 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
7802 display_to_port_type((field_display_e)hfinfo->display), value);
7803 label_fill(label_str, 0, hfinfo, tmp);
7806 out = hfinfo_number_value_format(hfinfo, buf, value);
7808 label_fill(label_str, 0, hfinfo, out);
7813 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
7815 header_field_info *hfinfo = fi->hfinfo;
7822 value = fvalue_get_sinteger64(&fi->value);
7824 value = fvalue_get_uinteger64(&fi->value);
7826 /* Fill in the textual info */
7827 if (hfinfo->display == BASE_CUSTOM) {
7828 gchar tmp[ITEM_LABEL_LENGTH];
7829 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7831 DISSECTOR_ASSERT(fmtfunc64);
7832 fmtfunc64(tmp, value);
7833 label_fill(label_str, 0, hfinfo, tmp);
7835 else if (hfinfo->strings) {
7836 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7838 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7839 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7840 label_fill(label_str, 0, hfinfo, val_str);
7842 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7845 out = hfinfo_number_value_format64(hfinfo, buf, value);
7847 label_fill(label_str, 0, hfinfo, out);
7852 hfinfo_bitshift(const header_field_info *hfinfo)
7854 return ws_ctz(hfinfo->bitmask);
7858 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
7860 if (!hfinfo->bitmask) {
7864 /* ilog2 = first set bit, ctz = last set bit */
7865 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
7869 hfinfo_type_bitwidth(enum ftenum type)
7908 DISSECTOR_ASSERT_NOT_REACHED();
7916 hfinfo_container_bitwidth(const header_field_info *hfinfo)
7918 if (!hfinfo->bitmask) {
7922 if (hfinfo->type == FT_BOOLEAN) {
7923 return hfinfo->display; /* hacky? :) */
7926 return hfinfo_type_bitwidth(hfinfo->type);
7930 hfinfo_hex_digits(const header_field_info *hfinfo)
7934 /* If we have a bitmask, hfinfo->type is the width of the container, so not
7935 * appropriate to determine the number of hex digits for the field.
7936 * So instead, we compute it from the bitmask.
7938 if (hfinfo->bitmask != 0) {
7939 bitwidth = hfinfo_mask_bitwidth(hfinfo);
7941 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
7944 /* Divide by 4, rounding up, to get number of hex digits. */
7945 return (bitwidth + 3) / 4;
7949 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
7951 char *ptr = &buf[6];
7952 static const gchar hex_digits[16] =
7953 { '0', '1', '2', '3', '4', '5', '6', '7',
7954 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
7958 /* Properly format value */
7959 if (g_ascii_isprint(value)) {
7961 * Printable, so just show the character, and, if it needs
7962 * to be escaped, escape it.
7965 if (value == '\\' || value == '\'')
7969 * Non-printable; show it as an escape sequence.
7975 * Show a NUL with only one digit.
8009 switch (display & FIELD_DISPLAY_E_MASK) {
8012 *(--ptr) = (value & 0x7) + '0';
8014 *(--ptr) = (value & 0x7) + '0';
8016 *(--ptr) = (value & 0x7) + '0';
8020 *(--ptr) = hex_digits[value & 0x0F];
8022 *(--ptr) = hex_digits[value & 0x0F];
8027 g_assert_not_reached();
8037 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
8039 char *ptr = &buf[31];
8040 gboolean isint = IS_FT_INT(hfinfo->type);
8043 /* Properly format value */
8044 switch (display & FIELD_DISPLAY_E_MASK) {
8046 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8050 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8053 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8057 return oct_to_str_back(ptr, value);
8060 return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8064 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8067 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8074 port_with_resolution_to_str_buf(buf, 32,
8075 display_to_port_type((field_display_e)display), value);
8079 g_assert_not_reached();
8085 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
8087 char *ptr = &buf[47];
8088 gboolean isint = IS_FT_INT(hfinfo->type);
8091 /* Properly format value */
8094 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8098 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8101 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8105 return oct64_to_str_back(ptr, value);
8108 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8112 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8115 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8119 g_assert_not_reached();
8125 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8127 int display = hfinfo->display;
8129 if (hfinfo->type == FT_FRAMENUM) {
8131 * Frame numbers are always displayed in decimal.
8136 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8140 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8142 int display = hfinfo->display;
8144 if (hfinfo->type == FT_FRAMENUM) {
8146 * Frame numbers are always displayed in decimal.
8151 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8155 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8157 /* Get the underlying BASE_ value */
8158 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8160 return hfinfo_char_value_format_display(display, buf, value);
8164 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8166 /* Get the underlying BASE_ value */
8167 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8169 if (hfinfo->type == FT_FRAMENUM) {
8171 * Frame numbers are always displayed in decimal.
8176 if (IS_BASE_PORT(display)) {
8182 /* case BASE_DEC: */
8184 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
8189 /* case BASE_HEX: */
8195 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8199 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8201 /* Get the underlying BASE_ value */
8202 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8204 if (hfinfo->type == FT_FRAMENUM) {
8206 * Frame numbers are always displayed in decimal.
8213 /* case BASE_DEC: */
8215 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
8220 /* case BASE_HEX: */
8226 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8230 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8232 /* Get the underlying BASE_ value */
8233 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8235 return hfinfo_char_value_format_display(display, buf, value);
8239 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8241 /* Get the underlying BASE_ value */
8242 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8244 if (display == BASE_NONE)
8247 if (display == BASE_DEC_HEX)
8249 if (display == BASE_HEX_DEC)
8252 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8256 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8258 /* Get the underlying BASE_ value */
8259 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8261 if (display == BASE_NONE)
8264 if (display == BASE_DEC_HEX)
8266 if (display == BASE_HEX_DEC)
8269 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8273 proto_registrar_get_name(const int n)
8275 header_field_info *hfinfo;
8277 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8278 return hfinfo->name;
8282 proto_registrar_get_abbrev(const int n)
8284 header_field_info *hfinfo;
8286 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8287 return hfinfo->abbrev;
8291 proto_registrar_get_ftype(const int n)
8293 header_field_info *hfinfo;
8295 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8296 return hfinfo->type;
8300 proto_registrar_get_parent(const int n)
8302 header_field_info *hfinfo;
8304 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8305 return hfinfo->parent;
8309 proto_registrar_is_protocol(const int n)
8311 header_field_info *hfinfo;
8313 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8314 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
8317 /* Returns length of field in packet (not necessarily the length
8318 * in our internal representation, as in the case of IPv4).
8319 * 0 means undeterminable at time of registration
8320 * -1 means the field is not registered. */
8322 proto_registrar_get_length(const int n)
8324 header_field_info *hfinfo;
8326 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8327 return ftype_length(hfinfo->type);
8330 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
8331 * it exists anywhere, or FALSE if it exists nowhere. */
8333 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
8335 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
8337 if (g_ptr_array_len(ptrs) > 0) {
8345 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
8346 * This only works if the hfindex was "primed" before the dissection
8347 * took place, as we just pass back the already-created GPtrArray*.
8348 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
8351 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
8356 if (PTREE_DATA(tree)->interesting_hfids != NULL)
8357 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
8358 GINT_TO_POINTER(id));
8364 proto_tracking_interesting_fields(const proto_tree *tree)
8366 GHashTable *interesting_hfids;
8371 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
8373 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
8376 /* Helper struct for proto_find_info() and proto_all_finfos() */
8382 /* Helper function for proto_find_info() */
8384 find_finfo(proto_node *node, gpointer data)
8386 field_info *fi = PNODE_FINFO(node);
8387 if (fi && fi->hfinfo) {
8388 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8389 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8393 /* Don't stop traversing. */
8397 /* Helper function for proto_find_first_info() */
8399 find_first_finfo(proto_node *node, gpointer data)
8401 field_info *fi = PNODE_FINFO(node);
8402 if (fi && fi->hfinfo) {
8403 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8404 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8408 /* Stop traversing. */
8412 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
8413 * This works on any proto_tree, primed or unprimed, but actually searches
8414 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8415 * The caller does need to free the returned GPtrArray with
8416 * g_ptr_array_free(<array>, TRUE).
8419 proto_find_finfo(proto_tree *tree, const int id)
8423 ffdata.array = g_ptr_array_new();
8426 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
8428 return ffdata.array;
8431 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
8432 * This works on any proto_tree, primed or unprimed, but actually searches
8433 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8434 * The caller does need to free the returned GPtrArray with
8435 * g_ptr_array_free(<array>, TRUE).
8438 proto_find_first_finfo(proto_tree *tree, const int id)
8442 ffdata.array = g_ptr_array_new();
8445 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
8447 return ffdata.array;
8450 /* Helper function for proto_all_finfos() */
8452 every_finfo(proto_node *node, gpointer data)
8454 field_info *fi = PNODE_FINFO(node);
8455 if (fi && fi->hfinfo) {
8456 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8459 /* Don't stop traversing. */
8463 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
8465 proto_all_finfos(proto_tree *tree)
8469 /* Pre allocate enough space to hold all fields in most cases */
8470 ffdata.array = g_ptr_array_sized_new(512);
8473 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
8475 return ffdata.array;
8486 check_for_offset(proto_node *node, gpointer data)
8488 field_info *fi = PNODE_FINFO(node);
8489 offset_search_t *offsearch = (offset_search_t *)data;
8491 /* !fi == the top most container node which holds nothing */
8492 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
8493 if (offsearch->offset >= (guint) fi->start &&
8494 offsearch->offset < (guint) (fi->start + fi->length)) {
8496 offsearch->finfo = fi;
8497 return FALSE; /* keep traversing */
8500 return FALSE; /* keep traversing */
8503 /* Search a proto_tree backwards (from leaves to root) looking for the field
8504 * whose start/length occupies 'offset' */
8505 /* XXX - I couldn't find an easy way to search backwards, so I search
8506 * forwards, w/o stopping. Therefore, the last finfo I find will the be
8507 * the one I want to return to the user. This algorithm is inefficient
8508 * and could be re-done, but I'd have to handle all the children and
8509 * siblings of each node myself. When I have more time I'll do that.
8512 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
8514 offset_search_t offsearch;
8516 offsearch.offset = offset;
8517 offsearch.finfo = NULL;
8518 offsearch.tvb = tvb;
8520 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
8522 return offsearch.finfo;
8527 check_for_undecoded(proto_node *node, gpointer data)
8529 field_info *fi = PNODE_FINFO(node);
8530 gchar* decoded = (gchar*)data;
8535 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
8536 for (i = fi->start; i < fi->start + fi->length; i++) {
8539 decoded[byte] |= (1 << bit);
8547 proto_find_undecoded_data(proto_tree *tree, guint length)
8549 gchar* decoded = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
8551 proto_tree_traverse_pre_order(tree, check_for_undecoded, decoded);
8555 /* Dumps the protocols in the registration database to stdout. An independent
8556 * program can take this output and format it into nice tables or HTML or
8559 * There is one record per line. The fields are tab-delimited.
8561 * Field 1 = protocol name
8562 * Field 2 = protocol short name
8563 * Field 3 = protocol filter name
8566 proto_registrar_dump_protocols(void)
8568 protocol_t *protocol;
8570 void *cookie = NULL;
8573 i = proto_get_first_protocol(&cookie);
8575 protocol = find_protocol_by_id(i);
8576 ws_debug_printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
8577 protocol->filter_name);
8578 i = proto_get_next_protocol(&cookie);
8582 /* Dumps the value_strings, extended value string headers, range_strings
8583 * or true/false strings for fields that have them.
8584 * There is one record per line. Fields are tab-delimited.
8585 * There are four types of records: Value String, Extended Value String Header,
8586 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
8587 * the type of record.
8589 * Note that a record will be generated only if the value_string,... is referenced
8590 * in a registered hfinfo entry.
8596 * Field 2 = Field abbreviation to which this value string corresponds
8597 * Field 3 = Integer value
8600 * Extended Value String Headers
8601 * -----------------------------
8603 * Field 2 = Field abbreviation to which this extended value string header corresponds
8604 * Field 3 = Extended Value String "Name"
8605 * Field 4 = Number of entries in the associated value_string array
8606 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
8611 * Field 2 = Field abbreviation to which this range string corresponds
8612 * Field 3 = Integer value: lower bound
8613 * Field 4 = Integer value: upper bound
8616 * True/False Strings
8617 * ------------------
8619 * Field 2 = Field abbreviation to which this true/false string corresponds
8620 * Field 3 = True String
8621 * Field 4 = False String
8624 proto_registrar_dump_values(void)
8626 header_field_info *hfinfo;
8628 const value_string *vals;
8629 const val64_string *vals64;
8630 const range_string *range;
8631 const true_false_string *tfs;
8633 len = gpa_hfinfo.len;
8634 for (i = 0; i < len ; i++) {
8635 if (gpa_hfinfo.hfi[i] == NULL)
8636 continue; /* This is a deregistered protocol or field */
8638 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8640 if (hfinfo->id == hf_text_only) {
8644 /* ignore protocols */
8645 if (proto_registrar_is_protocol(i)) {
8648 /* process header fields */
8649 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
8651 * If this field isn't at the head of the list of
8652 * fields with this name, skip this field - all
8653 * fields with the same name are really just versions
8654 * of the same field stored in different bits, and
8655 * should have the same type/radix/value list, and
8656 * just differ in their bit masks. (If a field isn't
8657 * a bitfield, but can be, say, 1 or 2 bytes long,
8658 * it can just be made FT_UINT16, meaning the
8659 * *maximum* length is 2 bytes, and be used
8662 if (hfinfo->same_name_prev_id != -1)
8670 if (hfinfo->strings != NULL) {
8671 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) != BASE_CUSTOM &&
8672 (hfinfo->type == FT_CHAR ||
8673 hfinfo->type == FT_UINT8 ||
8674 hfinfo->type == FT_UINT16 ||
8675 hfinfo->type == FT_UINT24 ||
8676 hfinfo->type == FT_UINT32 ||
8677 hfinfo->type == FT_UINT40 ||
8678 hfinfo->type == FT_UINT48 ||
8679 hfinfo->type == FT_UINT56 ||
8680 hfinfo->type == FT_UINT64 ||
8681 hfinfo->type == FT_INT8 ||
8682 hfinfo->type == FT_INT16 ||
8683 hfinfo->type == FT_INT24 ||
8684 hfinfo->type == FT_INT32 ||
8685 hfinfo->type == FT_INT40 ||
8686 hfinfo->type == FT_INT48 ||
8687 hfinfo->type == FT_INT56 ||
8688 hfinfo->type == FT_INT64)) {
8690 if (hfinfo->display & BASE_RANGE_STRING) {
8691 range = (const range_string *)hfinfo->strings;
8692 } else if (hfinfo->display & BASE_EXT_STRING) {
8693 vals = VALUE_STRING_EXT_VS_P((value_string_ext *)hfinfo->strings);
8694 } else if (hfinfo->display & BASE_VAL64_STRING) {
8695 vals64 = (const val64_string *)hfinfo->strings;
8697 vals = (const value_string *)hfinfo->strings;
8700 else if (hfinfo->type == FT_BOOLEAN) {
8701 tfs = (const struct true_false_string *)hfinfo->strings;
8705 /* Print value strings? */
8707 if (hfinfo->display & BASE_EXT_STRING) {
8708 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
8709 if (!value_string_ext_validate(vse_p)) {
8710 ws_g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
8713 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
8714 ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
8716 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
8717 VALUE_STRING_EXT_VS_NAME(vse_p),
8718 value_string_ext_match_type_str(vse_p));
8721 while (vals[vi].strptr) {
8722 /* Print in the proper base */
8723 if (hfinfo->type == FT_CHAR) {
8724 if (g_ascii_isprint(vals[vi].value)) {
8725 ws_debug_printf("V\t%s\t'%c'\t%s\n",
8730 if (hfinfo->display == BASE_HEX) {
8731 ws_debug_printf("V\t%s\t'\\x%02x'\t%s\n",
8737 ws_debug_printf("V\t%s\t'\\%03o'\t%s\n",
8744 if (hfinfo->display == BASE_HEX) {
8745 ws_debug_printf("V\t%s\t0x%x\t%s\n",
8751 ws_debug_printf("V\t%s\t%u\t%s\n",
8762 while (vals64[vi].strptr) {
8763 ws_debug_printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
8771 /* print range strings? */
8774 while (range[vi].strptr) {
8775 /* Print in the proper base */
8776 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_HEX) {
8777 ws_debug_printf("R\t%s\t0x%x\t0x%x\t%s\n",
8779 range[vi].value_min,
8780 range[vi].value_max,
8784 ws_debug_printf("R\t%s\t%u\t%u\t%s\n",
8786 range[vi].value_min,
8787 range[vi].value_max,
8794 /* Print true/false strings? */
8796 ws_debug_printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
8797 tfs->true_string, tfs->false_string);
8802 /* Prints the number of registered fields.
8803 * Useful for determining an appropriate value for
8804 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
8806 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
8807 * the number of fields, TRUE otherwise.
8810 proto_registrar_dump_fieldcount(void)
8813 header_field_info *hfinfo;
8814 guint32 deregistered_count = 0;
8815 guint32 same_name_count = 0;
8816 guint32 protocol_count = 0;
8818 for (i = 0; i < gpa_hfinfo.len; i++) {
8819 if (gpa_hfinfo.hfi[i] == NULL) {
8820 deregistered_count++;
8821 continue; /* This is a deregistered protocol or header field */
8824 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8826 if (proto_registrar_is_protocol(i))
8829 if (hfinfo->same_name_prev_id != -1)
8833 ws_debug_printf("There are %u header fields registered, of which:\n"
8834 "\t%u are deregistered\n"
8835 "\t%u are protocols\n"
8836 "\t%u have the same name as another field\n\n",
8837 gpa_hfinfo.len, deregistered_count, protocol_count,
8840 ws_debug_printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
8841 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
8842 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
8845 ws_debug_printf("The header field table consumes %u KiB of memory.\n",
8846 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
8847 ws_debug_printf("The fields themselves consume %u KiB of memory.\n",
8848 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
8850 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8854 /* Dumps the contents of the registration database to stdout. An independent
8855 * program can take this output and format it into nice tables or HTML or
8858 * There is one record per line. Each record is either a protocol or a header
8859 * field, differentiated by the first field. The fields are tab-delimited.
8864 * Field 2 = descriptive protocol name
8865 * Field 3 = protocol abbreviation
8870 * Field 2 = descriptive field name
8871 * Field 3 = field abbreviation
8872 * Field 4 = type ( textual representation of the the ftenum type )
8873 * Field 5 = parent protocol abbreviation
8874 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
8875 * Field 7 = bitmask: format: hex: 0x....
8876 * Field 8 = blurb describing field
8879 proto_registrar_dump_fields(void)
8881 header_field_info *hfinfo, *parent_hfinfo;
8883 const char *enum_name;
8884 const char *base_name;
8888 len = gpa_hfinfo.len;
8889 for (i = 0; i < len ; i++) {
8890 if (gpa_hfinfo.hfi[i] == NULL)
8891 continue; /* This is a deregistered protocol or header field */
8893 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8896 * Skip the pseudo-field for "proto_tree_add_text()" since
8897 * we don't want it in the list of filterable fields.
8899 if (hfinfo->id == hf_text_only)
8902 /* format for protocols */
8903 if (proto_registrar_is_protocol(i)) {
8904 ws_debug_printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
8906 /* format for header fields */
8909 * If this field isn't at the head of the list of
8910 * fields with this name, skip this field - all
8911 * fields with the same name are really just versions
8912 * of the same field stored in different bits, and
8913 * should have the same type/radix/value list, and
8914 * just differ in their bit masks. (If a field isn't
8915 * a bitfield, but can be, say, 1 or 2 bytes long,
8916 * it can just be made FT_UINT16, meaning the
8917 * *maximum* length is 2 bytes, and be used
8920 if (hfinfo->same_name_prev_id != -1)
8923 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
8925 enum_name = ftype_name(hfinfo->type);
8928 if (hfinfo->type == FT_CHAR ||
8929 hfinfo->type == FT_UINT8 ||
8930 hfinfo->type == FT_UINT16 ||
8931 hfinfo->type == FT_UINT24 ||
8932 hfinfo->type == FT_UINT32 ||
8933 hfinfo->type == FT_UINT40 ||
8934 hfinfo->type == FT_UINT48 ||
8935 hfinfo->type == FT_UINT56 ||
8936 hfinfo->type == FT_UINT64 ||
8937 hfinfo->type == FT_INT8 ||
8938 hfinfo->type == FT_INT16 ||
8939 hfinfo->type == FT_INT24 ||
8940 hfinfo->type == FT_INT32 ||
8941 hfinfo->type == FT_INT40 ||
8942 hfinfo->type == FT_INT48 ||
8943 hfinfo->type == FT_INT56 ||
8944 hfinfo->type == FT_INT64) {
8946 switch (FIELD_DISPLAY(hfinfo->display)) {
8958 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
8964 } else if (hfinfo->type == FT_BOOLEAN) {
8965 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
8966 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
8970 blurb = hfinfo->blurb;
8973 else if (strlen(blurb) == 0)
8976 ws_debug_printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
8977 hfinfo->name, hfinfo->abbrev, enum_name,
8978 parent_hfinfo->abbrev, base_name,
8979 hfinfo->bitmask, blurb);
8984 /* Dumps field types and descriptive names to stdout. An independent
8985 * program can take this output and format it into nice tables or HTML or
8988 * There is one record per line. The fields are tab-delimited.
8990 * Field 1 = field type name, e.g. FT_UINT8
8991 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
8994 proto_registrar_dump_ftypes(void)
8998 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
8999 ws_debug_printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
9003 /* This function indicates whether it's possible to construct a
9004 * "match selected" display filter string for the specified field,
9005 * returns an indication of whether it's possible, and, if it's
9006 * possible and "filter" is non-null, constructs the filter and
9007 * sets "*filter" to point to it.
9008 * You do not need to [g_]free() this string since it will be automatically
9009 * freed once the next packet is dissected.
9012 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
9015 header_field_info *hfinfo;
9020 gint start, length, length_remaining;
9022 gchar is_signed_num = FALSE;
9027 hfinfo = finfo->hfinfo;
9028 DISSECTOR_ASSERT(hfinfo);
9029 abbrev_len = (int) strlen(hfinfo->abbrev);
9031 if (hfinfo->strings && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
9032 const gchar *str = NULL;
9034 switch (hfinfo->type) {
9040 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
9048 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
9055 if (str != NULL && filter != NULL) {
9056 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
9062 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
9063 * functions for FT_UINT and FT_INT types, as we choose the base in
9064 * the string expression based on the display base of the field.
9066 * Note that the base does matter, as this is also used for
9067 * the protocolinfo tap.
9069 * It might be nice to use them in "proto_item_fill_label()"
9070 * as well, although, there, you'd have to deal with the base
9071 * *and* with resolved values for addresses.
9073 * Perhaps we need two different val_to_string routines, one
9074 * to generate items for display filters and one to generate
9075 * strings for display, and pass to both of them the
9076 * "display" and "strings" values in the header_field_info
9077 * structure for the field, so they can get the base and,
9078 * if the field is Boolean or an enumerated integer type,
9079 * the tables used to generate human-readable values.
9081 switch (hfinfo->type) {
9084 if (filter != NULL) {
9090 number = fvalue_get_uinteger(&finfo->value);
9092 out = hfinfo_char_value_format(hfinfo, buf, number);
9094 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9102 is_signed_num = TRUE;
9109 if (filter != NULL) {
9116 number = fvalue_get_sinteger(&finfo->value);
9118 number = fvalue_get_uinteger(&finfo->value);
9120 out = hfinfo_numeric_value_format(hfinfo, buf, number);
9122 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9130 is_signed_num = TRUE;
9136 if (filter != NULL) {
9143 number = fvalue_get_sinteger64(&finfo->value);
9145 number = fvalue_get_uinteger64(&finfo->value);
9147 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
9149 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9155 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
9160 * If the length is 0, just match the name of the
9163 * (Also check for negative values, just in case,
9164 * as we'll cast it to an unsigned value later.)
9166 length = finfo->length;
9169 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
9176 * This doesn't have a value, so we'd match
9177 * on the raw bytes at this address.
9179 * Should we be allowed to access to the raw bytes?
9180 * If "edt" is NULL, the answer is "no".
9186 * Is this field part of the raw frame tvbuff?
9187 * If not, we can't use "frame[N:M]" to match
9190 * XXX - should this be frame-relative, or
9191 * protocol-relative?
9193 * XXX - does this fallback for non-registered
9194 * fields even make sense?
9196 if (finfo->ds_tvb != edt->tvb)
9197 return FALSE; /* you lose */
9200 * Don't go past the end of that tvbuff.
9202 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
9203 if (length > length_remaining)
9204 length = length_remaining;
9208 if (filter != NULL) {
9209 start = finfo->start;
9210 buf_len = 32 + length * 3;
9211 *filter = (char *)wmem_alloc0(NULL, buf_len);
9214 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
9215 "frame[%d:%d] == ", finfo->start, length);
9216 for (i=0; i<length; i++) {
9217 c = tvb_get_guint8(finfo->ds_tvb, start);
9220 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
9223 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
9230 /* FT_PCRE never appears as a type for a registered field. It is
9231 * only used internally. */
9232 DISSECTOR_ASSERT_NOT_REACHED();
9235 /* By default, use the fvalue's "to_string_repr" method. */
9237 /* Figure out the string length needed.
9238 * The ft_repr length.
9239 * 4 bytes for " == ".
9240 * 1 byte for trailing NUL.
9242 if (filter != NULL) {
9244 dfilter_len = fvalue_string_repr_len(&finfo->value,
9245 FTREPR_DFILTER, finfo->hfinfo->display);
9246 dfilter_len += abbrev_len + 4 + 1;
9247 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
9249 /* Create the string */
9250 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
9251 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
9252 wmem_free(NULL, str);
9261 * Returns TRUE if we can do a "match selected" on the field, FALSE
9265 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
9267 return construct_match_selected_string(finfo, edt, NULL);
9270 /* This function attempts to construct a "match selected" display filter
9271 * string for the specified field; if it can do so, it returns a pointer
9272 * to the string, otherwise it returns NULL.
9274 * The string is allocated with packet lifetime scope.
9275 * You do not need to [g_]free() this string since it will be automatically
9276 * freed once the next packet is dissected.
9279 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
9281 char *filter = NULL;
9283 if (!construct_match_selected_string(finfo, edt, &filter))
9285 wmem_free(NULL, filter);
9291 /* This function is common code for all proto_tree_add_bitmask... functions.
9295 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
9296 const int len, const gint ett, const int **fields,
9297 const int flags, gboolean first,
9298 gboolean use_parent_tree,
9299 proto_tree* tree, guint64 value)
9302 guint64 available_bits = 0;
9304 header_field_info *hf;
9306 if (len < 0 || len > 8)
9307 g_assert_not_reached();
9308 bitshift = (8 - (guint)len)*8;
9309 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
9311 if (use_parent_tree == FALSE)
9312 tree = proto_item_add_subtree(item, ett);
9315 guint64 present_bits;
9316 PROTO_REGISTRAR_GET_NTH(**fields,hf);
9317 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
9319 /* Skip fields that aren't fully present */
9320 present_bits = available_bits & hf->bitmask;
9321 if (present_bits != hf->bitmask) {
9336 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
9347 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
9351 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
9355 DISSECTOR_ASSERT_NOT_REACHED();
9358 if (flags & BMT_NO_APPEND) {
9362 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
9366 if (hf->display == BASE_CUSTOM) {
9367 gchar lbl[ITEM_LABEL_LENGTH];
9368 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9370 DISSECTOR_ASSERT(fmtfunc);
9371 fmtfunc(lbl, (guint32) tmpval);
9372 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9376 else if (hf->strings) {
9377 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9378 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
9381 else if (!(flags & BMT_NO_INT)) {
9386 proto_item_append_text(item, ", ");
9389 out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
9390 proto_item_append_text(item, "%s: %s", hf->name, out);
9412 if (hf->display == BASE_CUSTOM) {
9413 gchar lbl[ITEM_LABEL_LENGTH];
9414 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9416 DISSECTOR_ASSERT(fmtfunc);
9417 fmtfunc(lbl, (guint32) tmpval);
9418 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9422 else if (hf->strings) {
9423 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9424 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
9427 else if (!(flags & BMT_NO_INT)) {
9432 proto_item_append_text(item, ", ");
9435 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
9436 proto_item_append_text(item, "%s: %s", hf->name, out);
9442 if (hf->strings && !(flags & BMT_NO_TFS)) {
9443 /* If we have true/false strings, emit full - otherwise messages
9445 const struct true_false_string *tfs =
9446 (const struct true_false_string *)hf->strings;
9449 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9450 hf->name, tfs->true_string);
9452 } else if (!(flags & BMT_NO_FALSE)) {
9453 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9454 hf->name, tfs->false_string);
9457 } else if (hf->bitmask & value) {
9458 /* If the flag is set, show the name */
9459 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
9464 DISSECTOR_ASSERT_NOT_REACHED();
9474 /* This function will dissect a sequence of bytes that describe a
9475 * bitmask and supply the value of that sequence through a pointer.
9476 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9478 * This field will form an expansion under which the individual fields of the
9479 * bitmask is dissected and displayed.
9480 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9482 * fields is an array of pointers to int that lists all the fields of the
9483 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9484 * or another integer of the same type/size as hf_hdr with a mask specified.
9485 * This array is terminated by a NULL entry.
9487 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9488 * FT_integer fields that have a value_string attached will have the
9489 * matched string displayed on the expansion line.
9492 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
9493 const guint offset, const int hf_hdr,
9494 const gint ett, const int **fields,
9495 const guint encoding, guint64 *retval)
9497 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);
9500 /* This function will dissect a sequence of bytes that describe a
9502 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9504 * This field will form an expansion under which the individual fields of the
9505 * bitmask is dissected and displayed.
9506 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9508 * fields is an array of pointers to int that lists all the fields of the
9509 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9510 * or another integer of the same type/size as hf_hdr with a mask specified.
9511 * This array is terminated by a NULL entry.
9513 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9514 * FT_integer fields that have a value_string attached will have the
9515 * matched string displayed on the expansion line.
9518 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
9519 const guint offset, const int hf_hdr,
9520 const gint ett, const int **fields,
9521 const guint encoding)
9523 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
9526 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9527 * what data is appended to the header.
9530 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9531 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
9534 proto_item *item = NULL;
9535 header_field_info *hf;
9539 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9540 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9541 len = ftype_length(hf->type);
9542 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9545 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9546 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9547 flags, FALSE, FALSE, NULL, value);
9552 /* Mask out irrelevant portions */
9553 *retval &= hf->bitmask;
9555 *retval >>= hfinfo_bitshift(hf);
9561 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9562 * what data is appended to the header.
9565 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9566 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
9568 proto_item *item = NULL;
9569 header_field_info *hf;
9573 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9574 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9577 len = ftype_length(hf->type);
9578 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9579 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9580 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9581 flags, FALSE, FALSE, NULL, value);
9587 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
9588 can't be retrieved directly from tvb) */
9590 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9591 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
9593 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
9594 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
9597 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
9598 WS_DLL_PUBLIC proto_item *
9599 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9600 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
9602 proto_item *item = NULL;
9603 header_field_info *hf;
9606 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9607 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9608 len = ftype_length(hf->type);
9612 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
9614 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
9616 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9617 flags, FALSE, FALSE, NULL, value);
9623 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
9625 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9626 const int len, const int **fields, const guint encoding)
9631 value = get_uint64_value(tree, tvb, offset, len, encoding);
9632 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9633 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9638 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9639 const int len, const int **fields, const guint64 value)
9642 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9643 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9648 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
9649 * This is intended to support bitmask fields whose lengths can vary, perhaps
9650 * as the underlying standard evolves over time.
9651 * With this API there is the possibility of being called to display more or
9652 * less data than the dissector was coded to support.
9653 * In such cases, it is assumed that bitmasks are extended on the MSb end.
9654 * Thus when presented with "too much" or "too little" data, MSbits will be
9655 * ignored or MSfields sacrificed.
9657 * Only fields for which all defined bits are available are displayed.
9660 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
9661 const guint offset, const guint len, const int hf_hdr,
9662 const gint ett, const int **fields, struct expert_field* exp,
9663 const guint encoding)
9665 proto_item *item = NULL;
9666 header_field_info *hf;
9667 guint decodable_len;
9668 guint decodable_offset;
9669 guint32 decodable_value;
9672 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
9673 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9675 decodable_offset = offset;
9676 decodable_len = MIN(len, (guint) ftype_length(hf->type));
9678 /* If we are ftype_length-limited,
9679 * make sure we decode as many LSBs as possible.
9681 if (encoding == ENC_BIG_ENDIAN) {
9682 decodable_offset += (len - decodable_len);
9686 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
9687 decodable_len, encoding);
9689 /* The root item covers all the bytes even if we can't decode them all */
9690 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
9694 if (decodable_len < len) {
9695 /* Dissector likely requires updating for new protocol revision */
9696 expert_add_info_format(NULL, item, exp,
9697 "Only least-significant %d of %d bytes decoded",
9698 decodable_len, len);
9702 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
9703 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
9704 ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
9710 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
9712 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
9713 const guint offset, const guint len,
9714 const char *name, const char *fallback,
9715 const gint ett, const int **fields,
9716 const guint encoding, const int flags)
9718 proto_item *item = NULL;
9722 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
9723 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9724 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9725 flags, TRUE, FALSE, NULL, value) && fallback) {
9726 /* Still at first item - append 'fallback' text if any */
9727 proto_item_append_text(item, "%s", fallback);
9735 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9736 const guint bit_offset, const gint no_of_bits,
9737 const guint encoding)
9739 header_field_info *hfinfo;
9743 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9745 octet_length = (no_of_bits + 7) >> 3;
9746 octet_offset = bit_offset >> 3;
9747 test_length(hfinfo, tvb, octet_offset, octet_length);
9749 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
9750 * but only after doing a bunch more work (which we can, in the common
9751 * case, shortcut here).
9753 CHECK_FOR_NULL_TREE(tree);
9754 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9756 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
9760 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
9761 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
9762 * Offset should be given in bits from the start of the tvb.
9766 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9767 const guint bit_offset, const gint no_of_bits,
9768 guint64 *return_value, const guint encoding)
9774 char lbl_str[ITEM_LABEL_LENGTH];
9778 header_field_info *hf_field;
9780 const true_false_string *tfstring;
9782 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
9783 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
9785 if (hf_field->bitmask != 0) {
9786 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9787 "Incompatible use of proto_tree_add_bits_ret_val"
9788 " with field '%s' (%s) with bitmask != 0",
9789 hf_field->abbrev, hf_field->name));
9792 DISSECTOR_ASSERT(no_of_bits > 0);
9794 /* Byte align offset */
9795 offset = bit_offset>>3;
9798 * Calculate the number of octets used to hold the bits
9800 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
9801 length = (tot_no_bits + 7) >> 3;
9803 if (no_of_bits < 65) {
9804 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
9806 DISSECTOR_ASSERT_NOT_REACHED();
9810 /* Sign extend for signed types */
9811 switch (hf_field->type) {
9820 value = ws_sign_ext64(value, no_of_bits);
9828 *return_value = value;
9831 /* Coast clear. Try and fake it */
9832 CHECK_FOR_NULL_TREE(tree);
9833 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9835 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
9837 switch (hf_field->type) {
9840 tfstring = (const true_false_string *) &tfs_true_false;
9841 if (hf_field->strings)
9842 tfstring = (const true_false_string *)hf_field->strings;
9843 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
9845 bf_str, hf_field->name,
9846 (guint64)value ? tfstring->true_string : tfstring->false_string);
9850 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
9851 fill_label_char(PITEM_FINFO(pi), lbl_str);
9858 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
9859 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
9866 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
9867 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
9874 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
9875 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
9882 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
9883 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
9887 DISSECTOR_ASSERT_NOT_REACHED();
9892 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
9897 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9898 const guint bit_offset, const crumb_spec_t *crumb_spec,
9899 guint64 *return_value)
9904 guint mask_initial_bit_offset;
9905 guint mask_greatest_bit_offset;
9909 char lbl_str[ITEM_LABEL_LENGTH];
9911 guint64 composite_bitmask;
9912 guint64 composite_bitmap;
9914 header_field_info *hf_field;
9915 const true_false_string *tfstring;
9917 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
9918 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
9920 if (hf_field->bitmask != 0) {
9921 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9922 "Incompatible use of proto_tree_add_split_bits_item_ret_val"
9923 " with field '%s' (%s) with bitmask != 0",
9924 hf_field->abbrev, hf_field->name));
9927 mask_initial_bit_offset = bit_offset % 8;
9932 mask_greatest_bit_offset = 0;
9933 composite_bitmask = 0;
9934 composite_bitmap = 0;
9936 while (crumb_spec[i].crumb_bit_length != 0) {
9937 guint64 crumb_mask, crumb_value;
9938 guint8 crumb_end_bit_offset;
9940 DISSECTOR_ASSERT(i < 64);
9941 crumb_value = tvb_get_bits64(tvb,
9942 bit_offset + crumb_spec[i].crumb_bit_offset,
9943 crumb_spec[i].crumb_bit_length,
9945 value += crumb_value;
9946 no_of_bits += crumb_spec[i].crumb_bit_length;
9948 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
9949 octet containing the initial offset.
9950 If the mask is beyond 32 bits, then give up on bit map display.
9951 This could be improved in future, probably showing a table
9952 of 32 or 64 bits per row */
9953 if (mask_greatest_bit_offset < 32) {
9954 crumb_end_bit_offset = mask_initial_bit_offset
9955 + crumb_spec[i].crumb_bit_offset
9956 + crumb_spec[i].crumb_bit_length;
9957 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
9959 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
9960 mask_greatest_bit_offset = crumb_end_bit_offset;
9962 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
9963 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
9965 /* Shift left for the next segment */
9966 value <<= crumb_spec[++i].crumb_bit_length;
9969 /* Sign extend for signed types */
9970 switch (hf_field->type) {
9979 value = ws_sign_ext64(value, no_of_bits);
9986 *return_value = value;
9989 /* Coast clear. Try and fake it */
9990 CHECK_FOR_NULL_TREE(tree);
9991 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9993 /* initialise the format string */
9996 octet_offset = bit_offset >> 3;
9998 /* Round up mask length to nearest octet */
9999 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
10000 mask_greatest_bit_offset = octet_length << 3;
10002 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
10003 It would be a useful enhancement to eliminate this restriction. */
10004 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
10005 other_decode_bitfield_value(bf_str,
10006 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
10007 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
10008 mask_greatest_bit_offset);
10011 switch (hf_field->type) {
10012 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
10013 /* Boolean field */
10014 tfstring = (const true_false_string *) &tfs_true_false;
10015 if (hf_field->strings)
10016 tfstring = (const true_false_string *) hf_field->strings;
10017 return proto_tree_add_boolean_format(tree, hfindex,
10018 tvb, octet_offset, octet_length, (guint32)value,
10020 bf_str, hf_field->name,
10021 (guint64)value ? tfstring->true_string : tfstring->false_string);
10025 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
10026 fill_label_char(PITEM_FINFO(pi), lbl_str);
10033 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
10034 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
10041 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
10042 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
10049 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
10050 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
10057 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
10058 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
10062 DISSECTOR_ASSERT_NOT_REACHED();
10066 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
10071 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
10072 const crumb_spec_t *crumb_spec, guint16 crumb_index)
10074 header_field_info *hfinfo;
10076 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
10077 proto_tree_add_text_internal(tree, tvb,
10079 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
10080 "%s crumb %d of %s (decoded above)",
10081 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
10084 crumb_spec[crumb_index].crumb_bit_length,
10091 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10092 const guint bit_offset, const gint no_of_bits,
10093 guint64 *return_value, const guint encoding)
10097 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
10098 bit_offset, no_of_bits,
10099 return_value, encoding))) {
10100 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
10101 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
10106 static proto_item *
10107 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
10108 tvbuff_t *tvb, const guint bit_offset,
10109 const gint no_of_bits, void *value_ptr,
10114 guint8 tot_no_bits;
10117 header_field_info *hf_field;
10119 /* We do not have to return a value, try to fake it as soon as possible */
10120 CHECK_FOR_NULL_TREE(tree);
10121 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10123 if (hf_field->bitmask != 0) {
10124 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10125 "Incompatible use of proto_tree_add_bits_format_value"
10126 " with field '%s' (%s) with bitmask != 0",
10127 hf_field->abbrev, hf_field->name));
10130 DISSECTOR_ASSERT(no_of_bits > 0);
10132 /* Byte align offset */
10133 offset = bit_offset>>3;
10136 * Calculate the number of octets used to hold the bits
10138 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
10139 length = tot_no_bits>>3;
10140 /* If we are using part of the next octet, increase length by 1 */
10141 if (tot_no_bits & 0x07)
10144 if (no_of_bits < 65) {
10145 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
10147 DISSECTOR_ASSERT_NOT_REACHED();
10151 str = decode_bits_in_field(bit_offset, no_of_bits, value);
10153 g_strlcat(str, " = ", 256+64);
10154 g_strlcat(str, hf_field->name, 256+64);
10157 * This function does not receive an actual value but a dimensionless pointer to that value.
10158 * For this reason, the type of the header field is examined in order to determine
10159 * what kind of value we should read from this address.
10160 * The caller of this function must make sure that for the specific header field type the address of
10161 * a compatible value is provided.
10163 switch (hf_field->type) {
10165 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
10166 "%s: %s", str, value_str);
10174 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
10175 "%s: %s", str, value_str);
10182 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
10183 "%s: %s", str, value_str);
10190 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
10191 "%s: %s", str, value_str);
10198 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
10199 "%s: %s", str, value_str);
10203 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
10204 "%s: %s", str, value_str);
10208 DISSECTOR_ASSERT_NOT_REACHED();
10214 static proto_item *
10215 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
10216 tvbuff_t *tvb, const guint bit_offset,
10217 const gint no_of_bits, void *value_ptr,
10222 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
10223 tvb, bit_offset, no_of_bits,
10224 value_ptr, value_str))) {
10225 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
10226 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
10231 #define CREATE_VALUE_STRING(dst,format,ap) \
10232 va_start(ap, format); \
10233 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
10237 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
10238 tvbuff_t *tvb, const guint bit_offset,
10239 const gint no_of_bits, guint32 value,
10240 const char *format, ...)
10244 header_field_info *hf_field;
10246 CHECK_FOR_NULL_TREE(tree);
10248 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10250 switch (hf_field->type) {
10258 DISSECTOR_ASSERT_NOT_REACHED();
10263 CREATE_VALUE_STRING(dst, format, ap);
10265 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10269 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
10270 tvbuff_t *tvb, const guint bit_offset,
10271 const gint no_of_bits, guint64 value,
10272 const char *format, ...)
10276 header_field_info *hf_field;
10278 CHECK_FOR_NULL_TREE(tree);
10280 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10282 switch (hf_field->type) {
10290 DISSECTOR_ASSERT_NOT_REACHED();
10295 CREATE_VALUE_STRING(dst, format, ap);
10297 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10301 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
10302 tvbuff_t *tvb, const guint bit_offset,
10303 const gint no_of_bits, float value,
10304 const char *format, ...)
10308 header_field_info *hf_field;
10310 CHECK_FOR_NULL_TREE(tree);
10312 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10314 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
10316 CREATE_VALUE_STRING(dst, format, ap);
10318 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10322 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
10323 tvbuff_t *tvb, const guint bit_offset,
10324 const gint no_of_bits, gint32 value,
10325 const char *format, ...)
10329 header_field_info *hf_field;
10331 CHECK_FOR_NULL_TREE(tree);
10333 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10335 switch (hf_field->type) {
10343 DISSECTOR_ASSERT_NOT_REACHED();
10348 CREATE_VALUE_STRING(dst, format, ap);
10350 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10354 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
10355 tvbuff_t *tvb, const guint bit_offset,
10356 const gint no_of_bits, gint64 value,
10357 const char *format, ...)
10361 header_field_info *hf_field;
10363 CHECK_FOR_NULL_TREE(tree);
10365 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10367 switch (hf_field->type) {
10375 DISSECTOR_ASSERT_NOT_REACHED();
10380 CREATE_VALUE_STRING(dst, format, ap);
10382 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10386 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
10387 tvbuff_t *tvb, const guint bit_offset,
10388 const gint no_of_bits, guint32 value,
10389 const char *format, ...)
10393 header_field_info *hf_field;
10395 CHECK_FOR_NULL_TREE(tree);
10397 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10399 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
10401 CREATE_VALUE_STRING(dst, format, ap);
10403 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10407 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
10408 tvbuff_t *tvb, const guint bit_offset,
10409 const gint no_of_bits, guint64 value,
10410 const char *format, ...)
10414 header_field_info *hf_field;
10416 CHECK_FOR_NULL_TREE(tree);
10418 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10420 DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
10422 CREATE_VALUE_STRING(dst, format, ap);
10424 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10428 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10429 const guint bit_offset, const gint no_of_chars)
10432 header_field_info *hfinfo;
10437 CHECK_FOR_NULL_TREE(tree);
10439 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10441 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
10443 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
10444 byte_offset = bit_offset >> 3;
10446 string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
10448 if (hfinfo->display == STR_UNICODE) {
10449 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
10452 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
10453 DISSECTOR_ASSERT(byte_length >= 0);
10454 proto_tree_set_string(PNODE_FINFO(pi), string);
10460 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10461 const guint bit_offset, const gint no_of_chars)
10464 header_field_info *hfinfo;
10469 CHECK_FOR_NULL_TREE(tree);
10471 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10473 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
10475 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
10476 byte_offset = bit_offset >> 3;
10478 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
10480 if (hfinfo->display == STR_UNICODE) {
10481 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
10484 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
10485 DISSECTOR_ASSERT(byte_length >= 0);
10486 proto_tree_set_string(PNODE_FINFO(pi), string);
10491 const value_string proto_checksum_vals[] = {
10492 { PROTO_CHECKSUM_E_BAD, "Bad" },
10493 { PROTO_CHECKSUM_E_GOOD, "Good" },
10494 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
10495 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
10501 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
10502 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
10503 packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
10505 header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
10508 proto_item* ti = NULL;
10510 gboolean incorrect_checksum = TRUE;
10512 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
10514 if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
10515 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, 0, 0, "[missing]");
10516 PROTO_ITEM_SET_GENERATED(ti);
10517 if (hf_checksum_status != -1) {
10518 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_NOT_PRESENT);
10519 PROTO_ITEM_SET_GENERATED(ti2);
10524 switch (hfinfo->type){
10538 DISSECTOR_ASSERT_NOT_REACHED();
10541 if (flags & PROTO_CHECKSUM_GENERATED) {
10542 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, 0, computed_checksum);
10543 PROTO_ITEM_SET_GENERATED(ti);
10545 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
10546 if (flags & PROTO_CHECKSUM_VERIFY) {
10547 if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
10548 if (computed_checksum == 0) {
10549 proto_item_append_text(ti, " [correct]");
10550 if (hf_checksum_status != -1) {
10551 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
10552 PROTO_ITEM_SET_GENERATED(ti2);
10554 incorrect_checksum = FALSE;
10555 } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
10556 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
10559 if (checksum == computed_checksum) {
10560 proto_item_append_text(ti, " [correct]");
10561 if (hf_checksum_status != -1) {
10562 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
10563 PROTO_ITEM_SET_GENERATED(ti2);
10565 incorrect_checksum = FALSE;
10569 if (incorrect_checksum) {
10570 if (hf_checksum_status != -1) {
10571 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
10572 PROTO_ITEM_SET_GENERATED(ti2);
10574 if (flags & PROTO_CHECKSUM_ZERO) {
10575 proto_item_append_text(ti, " [incorrect]");
10576 if (bad_checksum_expert != NULL)
10577 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum");
10579 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
10580 if (bad_checksum_expert != NULL)
10581 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum [should be 0x%0*x]", len*2, computed_checksum);
10585 if (hf_checksum_status != -1) {
10586 proto_item_append_text(ti, " [unverified]");
10587 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
10588 PROTO_ITEM_SET_GENERATED(ti2);
10597 proto_check_field_name(const gchar *field_name)
10599 return wrs_check_charset(fld_abbrev_chars, field_name);
10603 tree_expanded(int tree_type)
10605 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10606 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
10610 tree_expanded_set(int tree_type, gboolean value)
10612 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10615 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
10617 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
10621 * Editor modelines - http://www.wireshark.org/tools/modelines.html
10624 * c-basic-offset: 8
10626 * indent-tabs-mode: t
10629 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
10630 * :indentSize=8:tabSize=8:noTabs=false: