2 * Routines for protocol tree
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include <wsutil/bits_ctz.h>
32 #include <wsutil/bits_count_ones.h>
33 #include <wsutil/sign_ext.h>
35 #include <ftypes/ftypes-int.h>
38 #include "exceptions.h"
39 #include "ptvcursor.h"
41 #include "addr_resolv.h"
42 #include "address_types.h"
45 #include "epan_dissect.h"
47 #include "wmem/wmem.h"
49 #include "asm_utils.h"
50 #include "column-utils.h"
51 #include "to_str-int.h"
53 #include "osi-utils.h"
55 #include "show_exception.h"
57 #include <wsutil/plugins.h>
59 /* Ptvcursor limits */
60 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
61 #define SUBTREE_MAX_LEVELS 256
63 /* Throw an exception if our tree exceeds these. */
64 /* XXX - These should probably be preferences */
65 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
66 #define MAX_TREE_LEVELS (5 * 100)
68 typedef struct __subtree_lvl {
75 subtree_lvl *pushed_tree;
76 guint8 pushed_tree_index;
77 guint8 pushed_tree_max;
83 #define cVALS(x) (const value_string*)(x)
85 /** See inlined comments.
86 @param tree the tree to append this item to
87 @param free_block a code block to call to free resources if this returns
88 @return NULL if 'tree' is null */
89 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block) \
95 /** See inlined comments.
96 @param tree the tree to append this item to
97 @param free_block a code block to call to free resources if this returns
98 @return NULL if 'tree' is null */
99 #define CHECK_FOR_NULL_TREE(tree) \
100 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
102 /** See inlined comments.
103 @param tree the tree to append this item to
104 @param hfindex field index
105 @param hfinfo header_field
106 @param free_block a code block to call to free resources if this returns
107 @return the header field matching 'hfinfo' */
108 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
109 /* If this item is not referenced we don't have to do much work \
110 at all but we should still return a node so that field items \
111 below this node (think proto_item_add_subtree()) will still \
112 have somewhere to attach to or else filtering will not work \
113 (they would be ignored since tree would be NULL). \
114 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
115 since dissectors that want to do proto_item_set_len() or \
116 other operations that dereference this would crash. \
117 We fake FT_PROTOCOL unless some clients have requested us \
120 PTREE_DATA(tree)->count++; \
121 if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
123 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
124 g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
125 /* Let the exception handler add items to the tree */ \
126 PTREE_DATA(tree)->count = 0; \
127 THROW_MESSAGE(DissectorError, \
128 wmem_strdup_printf(wmem_packet_scope(), "More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
130 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
131 if (!(PTREE_DATA(tree)->visible)) { \
132 if (PTREE_FINFO(tree)) { \
133 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
134 && (hfinfo->type != FT_PROTOCOL || \
135 PTREE_DATA(tree)->fake_protocols)) { \
137 /* just return tree back to the caller */\
143 /** See inlined comments.
144 @param tree the tree to append this item to
145 @param hfindex field index
146 @param hfinfo header_field
147 @return the header field matching 'hfinfo' */
148 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
149 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
152 /** See inlined comments.
153 @param pi the created protocol item we're about to return */
154 #define TRY_TO_FAKE_THIS_REPR(pi) \
156 if (!(PTREE_DATA(pi)->visible)) { \
157 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
158 * items string representation */ \
161 /* Same as above but returning void */
162 #define TRY_TO_FAKE_THIS_REPR_VOID(pi) \
165 if (!(PTREE_DATA(pi)->visible)) { \
166 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
167 * items string representation */ \
171 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
172 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
173 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
175 static void label_mark_truncated(char *label_str, gsize name_pos);
176 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
178 static void fill_label_boolean(field_info *fi, gchar *label_str);
179 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
180 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
181 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
182 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
184 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
185 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
186 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
187 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
188 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
189 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
190 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
191 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
194 proto_tree_add_node(proto_tree *tree, field_info *fi);
197 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
201 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
202 gint length, guint item_length, const gint encoding);
205 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
206 const gint start, const gint item_length);
209 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
210 gint start, gint *length);
213 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
215 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
218 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
220 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
222 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
224 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
226 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
228 proto_tree_set_string(field_info *fi, const char* value);
230 proto_tree_set_ax25(field_info *fi, const guint8* value);
232 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
234 proto_tree_set_vines(field_info *fi, const guint8* value);
236 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
238 proto_tree_set_ether(field_info *fi, const guint8* value);
240 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
242 proto_tree_set_ipxnet(field_info *fi, guint32 value);
244 proto_tree_set_ipv4(field_info *fi, guint32 value);
246 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
248 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
250 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
252 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
254 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
256 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
258 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
260 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
262 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
264 proto_tree_set_boolean(field_info *fi, guint64 value);
266 proto_tree_set_float(field_info *fi, float value);
268 proto_tree_set_double(field_info *fi, double value);
270 proto_tree_set_uint(field_info *fi, guint32 value);
272 proto_tree_set_int(field_info *fi, gint32 value);
274 proto_tree_set_uint64(field_info *fi, guint64 value);
276 proto_tree_set_int64(field_info *fi, gint64 value);
278 proto_tree_set_eui64(field_info *fi, const guint64 value);
280 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
282 /* Handle type length mismatch (now filterable) expert info */
283 static int proto_type_length_mismatch = -1;
284 static expert_field ei_type_length_mismatch_error = EI_INIT;
285 static expert_field ei_type_length_mismatch_warn = EI_INIT;
286 static void register_type_length_mismatch(void);
288 /* Handle number string decoding errors with expert info */
289 static int proto_number_string_decoding_error = -1;
290 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
291 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
292 static void register_number_string_decoding_error(void);
294 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
296 /* special-case header field used within proto.c */
297 static header_field_info hfi_text_only =
298 { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
299 int hf_text_only = -1;
301 /* Structure for information about a protocol */
303 const char *name; /* long description */
304 const char *short_name; /* short description */
305 const char *filter_name; /* name of this protocol in filters */
306 GPtrArray *fields; /* fields for this protocol */
307 int proto_id; /* field ID for this protocol */
308 gboolean is_enabled; /* TRUE if protocol is enabled */
309 gboolean enabled_by_default; /* TRUE if protocol is enabled by default */
310 gboolean can_toggle; /* TRUE if is_enabled can be changed */
311 GList *heur_list; /* Heuristic dissectors associated with this protocol */
314 /* List of all protocols */
315 static GList *protocols = NULL;
317 /* Deregistered fields */
318 static GPtrArray *deregistered_fields = NULL;
319 static GPtrArray *deregistered_data = NULL;
321 /* Contains information about a field when a dissector calls
322 * proto_tree_add_item. */
323 #define FIELD_INFO_NEW(pool, fi) fi = wmem_new(pool, field_info)
324 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
326 /* Contains the space for proto_nodes. */
327 #define PROTO_NODE_INIT(node) \
328 node->first_child = NULL; \
329 node->last_child = NULL; \
332 #define PROTO_NODE_FREE(pool, node) \
333 wmem_free(pool, node)
335 /* String space for protocol and field items for the GUI */
336 #define ITEM_LABEL_NEW(pool, il) \
337 il = wmem_new(pool, item_label_t);
338 #define ITEM_LABEL_FREE(pool, il) \
341 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
342 if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
343 g_error("Unregistered hf! index=%d", hfindex); \
344 DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
345 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
346 hfinfo = gpa_hfinfo.hfi[hfindex];
348 /* List which stores protocols and fields that have been registered */
349 typedef struct _gpa_hfinfo_t {
351 guint32 allocated_len;
352 header_field_info **hfi;
355 static gpa_hfinfo_t gpa_hfinfo;
357 /* Hash table of abbreviations and IDs */
358 static GHashTable *gpa_name_map = NULL;
359 static header_field_info *same_name_hfinfo;
361 * We're called repeatedly with the same field name when sorting a column.
362 * Cache our last gpa_name_map hit for faster lookups.
364 static char *last_field_name = NULL;
365 static header_field_info *last_hfinfo;
367 static void save_same_name_hfinfo(gpointer data)
369 same_name_hfinfo = (header_field_info*)data;
372 /* Cached value for VINES address type (used for FT_VINES) */
373 static int vines_address_type = -1;
375 /* Points to the first element of an array of bits, indexed by
376 a subtree item type; that array element is TRUE if subtrees of
377 an item of that type are to be expanded. */
378 static guint32 *tree_is_expanded;
380 /* Number of elements in that array. */
383 /* Name hashtables for fast detection of duplicate names */
384 static GHashTable* proto_names = NULL;
385 static GHashTable* proto_short_names = NULL;
386 static GHashTable* proto_filter_names = NULL;
389 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
391 const protocol_t *p1 = (const protocol_t *)p1_arg;
392 const protocol_t *p2 = (const protocol_t *)p2_arg;
394 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
399 * List of dissector plugins.
402 void (*register_protoinfo)(void); /* routine to call to register protocol information */
403 void (*reg_handoff)(void); /* routine to call to register dissector handoff */
406 static GSList *dissector_plugins = NULL;
409 * Callback for each plugin found.
412 check_for_dissector_plugin(GModule *handle)
415 void (*register_protoinfo)(void);
416 void (*reg_handoff)(void);
417 dissector_plugin *plugin;
420 * Do we have a register routine?
422 if (g_module_symbol(handle, "plugin_register", &gp)) {
424 register_protoinfo = (void (*)(void))gp;
428 register_protoinfo = NULL;
432 * Do we have a reg_handoff routine?
434 if (g_module_symbol(handle, "plugin_reg_handoff", &gp)) {
436 reg_handoff = (void (*)(void))gp;
444 * If we have neither, we're not a dissector plugin.
446 if (register_protoinfo == NULL && reg_handoff == NULL)
450 * Add this one to the list of dissector plugins.
452 plugin = (dissector_plugin *)g_malloc(sizeof (dissector_plugin));
453 plugin->register_protoinfo = register_protoinfo;
454 plugin->reg_handoff = reg_handoff;
455 dissector_plugins = g_slist_append(dissector_plugins, plugin);
460 register_dissector_plugin(gpointer data, gpointer user_data _U_)
462 dissector_plugin *plugin = (dissector_plugin *)data;
464 if (plugin->register_protoinfo)
465 (plugin->register_protoinfo)();
469 reg_handoff_dissector_plugin(gpointer data, gpointer user_data _U_)
471 dissector_plugin *plugin = (dissector_plugin *)data;
473 if (plugin->reg_handoff)
474 (plugin->reg_handoff)();
478 * Register dissector plugin type.
481 register_dissector_plugin_type(void)
483 add_plugin_type("dissector", check_for_dissector_plugin);
485 #endif /* HAVE_PLUGINS */
487 /* initialize data structures and register protocols and fields */
489 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
490 void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
492 gpointer client_data)
496 proto_names = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
497 proto_short_names = g_hash_table_new(wrs_str_hash, g_str_equal);
498 proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
501 gpa_hfinfo.allocated_len = 0;
502 gpa_hfinfo.hfi = NULL;
503 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
504 deregistered_fields = g_ptr_array_new();
505 deregistered_data = g_ptr_array_new();
507 /* Initialize the ftype subsystem */
510 /* Initialize the addres type subsystem */
511 address_types_initialize();
513 /* Register one special-case FT_TEXT_ONLY field for use when
514 converting wireshark to new-style proto_tree. These fields
515 are merely strings on the GUI tree; they are not filterable */
516 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
518 /* Register the pseudo-protocols used for exceptions. */
519 register_show_exception();
520 register_type_length_mismatch();
521 register_number_string_decoding_error();
523 /* Have each built-in dissector register its protocols, fields,
524 dissector tables, and dissectors to be called through a
525 handle, and do whatever one-time initialization it needs to
527 register_all_protocols_func(cb, client_data);
529 /* Now that the VINES dissector has registered it's address
530 type, grab the value for the field type */
531 vines_address_type = address_type_get_by_name("AT_VINES");
533 /* Now call the registration routines for all disssector
536 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
537 g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL);
540 /* Now call the "handoff registration" routines of all built-in
541 dissectors; those routines register the dissector in other
542 dissectors' handoff tables, and fetch any dissector handles
544 register_all_handoffs_func(cb, client_data);
547 /* Now do the same with plugins. */
549 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
550 g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL);
553 /* sort the protocols by protocol name */
554 protocols = g_list_sort(protocols, proto_compare_name);
556 /* We've assigned all the subtree type values; allocate the array
557 for them, and zero it out. */
558 tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
564 /* Free the abbrev/ID hash table */
566 g_hash_table_destroy(gpa_name_map);
569 g_free(last_field_name);
570 last_field_name = NULL;
573 protocol_t *protocol = (protocol_t *)protocols->data;
574 header_field_info *hfinfo;
575 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
576 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
578 g_slice_free(header_field_info, hfinfo);
579 g_ptr_array_free(protocol->fields, TRUE);
580 g_list_free(protocol->heur_list);
581 protocols = g_list_remove(protocols, protocol);
586 g_hash_table_destroy(proto_names);
590 if (proto_short_names) {
591 g_hash_table_destroy(proto_short_names);
592 proto_short_names = NULL;
595 if (proto_filter_names) {
596 g_hash_table_destroy(proto_filter_names);
597 proto_filter_names = NULL;
600 if (gpa_hfinfo.allocated_len) {
602 gpa_hfinfo.allocated_len = 0;
603 g_free(gpa_hfinfo.hfi);
604 gpa_hfinfo.hfi = NULL;
607 if (deregistered_fields) {
608 g_ptr_array_free(deregistered_fields, FALSE);
609 deregistered_fields = NULL;
612 if (deregistered_data) {
613 g_ptr_array_free(deregistered_data, FALSE);
614 deregistered_data = NULL;
617 g_free(tree_is_expanded);
618 tree_is_expanded = NULL;
622 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
625 proto_node *pnode = tree;
629 if (func(pnode, data))
632 child = pnode->first_child;
633 while (child != NULL) {
635 * The routine we call might modify the child, e.g. by
636 * freeing it, so we get the child's successor before
637 * calling that routine.
640 child = current->next;
641 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
649 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
652 proto_node *pnode = tree;
656 child = pnode->first_child;
657 while (child != NULL) {
659 * The routine we call might modify the child, e.g. by
660 * freeing it, so we get the child's successor before
661 * calling that routine.
664 child = current->next;
665 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
668 if (func(pnode, data))
675 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
678 proto_node *node = tree;
684 node = node->first_child;
685 while (node != NULL) {
687 node = current->next;
688 func((proto_tree *)current, data);
693 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
695 GPtrArray *ptrs = (GPtrArray *)value;
696 gint hfid = GPOINTER_TO_UINT(key);
697 header_field_info *hfinfo;
699 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
700 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
701 /* when a field is referenced by a filter this also
702 affects the refcount for the parent protocol so we need
703 to adjust the refcount for the parent as well
705 if (hfinfo->parent != -1) {
706 header_field_info *parent_hfinfo;
707 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
708 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
710 hfinfo->ref_type = HF_REF_TYPE_NONE;
713 g_ptr_array_free(ptrs, TRUE);
717 proto_tree_free_node(proto_node *node, gpointer data _U_)
719 field_info *finfo = PNODE_FINFO(node);
721 proto_tree_children_foreach(node, proto_tree_free_node, NULL);
723 FVALUE_CLEANUP(&finfo->value);
727 proto_tree_reset(proto_tree *tree)
729 tree_data_t *tree_data = PTREE_DATA(tree);
731 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
734 if (tree_data->interesting_hfids) {
735 /* Free all the GPtrArray's in the interesting_hfids hash. */
736 g_hash_table_foreach(tree_data->interesting_hfids,
737 free_GPtrArray_value, NULL);
739 /* And then remove all values. */
740 g_hash_table_remove_all(tree_data->interesting_hfids);
743 /* Reset track of the number of children */
744 tree_data->count = 0;
746 PROTO_NODE_INIT(tree);
749 /* frees the resources that the dissection a proto_tree uses */
751 proto_tree_free(proto_tree *tree)
753 tree_data_t *tree_data = PTREE_DATA(tree);
755 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
758 if (tree_data->interesting_hfids) {
759 /* Free all the GPtrArray's in the interesting_hfids hash. */
760 g_hash_table_foreach(tree_data->interesting_hfids,
761 free_GPtrArray_value, NULL);
763 /* And then destroy the hash. */
764 g_hash_table_destroy(tree_data->interesting_hfids);
767 g_slice_free(tree_data_t, tree_data);
769 g_slice_free(proto_tree, tree);
772 /* Is the parsing being done for a visible proto_tree or an invisible one?
773 * By setting this correctly, the proto_tree creation is sped up by not
774 * having to call g_vsnprintf and copy strings around.
777 proto_tree_set_visible(proto_tree *tree, gboolean visible)
779 gboolean old_visible = PTREE_DATA(tree)->visible;
781 PTREE_DATA(tree)->visible = visible;
787 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
789 PTREE_DATA(tree)->fake_protocols = fake_protocols;
792 /* Assume dissector set only its protocol fields.
793 This function is called by dissectors and allows the speeding up of filtering
794 in wireshark; if this function returns FALSE it is safe to reset tree to NULL
795 and thus skip calling most of the expensive proto_tree_add_...()
797 If the tree is visible we implicitly assume the field is referenced.
800 proto_field_is_referenced(proto_tree *tree, int proto_id)
802 register header_field_info *hfinfo;
808 if (PTREE_DATA(tree)->visible)
811 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
812 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
815 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
822 /* Finds a record in the hfinfo array by id. */
824 proto_registrar_get_nth(guint hfindex)
826 register header_field_info *hfinfo;
828 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
833 /* Prefix initialization
834 * this allows for a dissector to register a display filter name prefix
835 * so that it can delay the initialization of the hf array as long as
839 /* compute a hash for the part before the dot of a display filter */
841 prefix_hash (gconstpointer key) {
842 /* end the string at the dot and compute its hash */
843 gchar* copy = g_strdup((const gchar *)key);
854 tmp = g_str_hash(copy);
859 /* are both strings equal up to the end or the dot? */
861 prefix_equal (gconstpointer ap, gconstpointer bp) {
862 const gchar* a = (const gchar *)ap;
863 const gchar* b = (const gchar *)bp;
869 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
871 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
872 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
874 if (ac != bc) return FALSE;
881 /* indexed by prefix, contains initializers */
882 static GHashTable* prefixes = NULL;
885 /* Register a new prefix for "delayed" initialization of field arrays */
887 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
889 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
892 g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
895 /* helper to call all prefix initializers */
897 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
898 ((prefix_initializer_t)v)((const char *)k);
902 /** Initialize every remaining uninitialized prefix. */
904 proto_initialize_all_prefixes(void) {
905 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
908 /* Finds a record in the hfinfo array by name.
909 * If it fails to find it in the already registered fields,
910 * it tries to find and call an initializer in the prefixes
911 * table and if so it looks again.
915 proto_registrar_get_byname(const char *field_name)
917 header_field_info *hfinfo;
918 prefix_initializer_t pi;
923 if (g_strcmp0(field_name, last_field_name) == 0) {
927 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
930 g_free(last_field_name);
931 last_field_name = g_strdup(field_name);
932 last_hfinfo = hfinfo;
939 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
941 g_hash_table_remove(prefixes, field_name);
946 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
949 g_free(last_field_name);
950 last_field_name = g_strdup(field_name);
951 last_hfinfo = hfinfo;
957 proto_registrar_get_id_byname(const char *field_name)
959 header_field_info *hfinfo;
961 hfinfo = proto_registrar_get_byname(field_name);
971 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
973 subtree_lvl *pushed_tree;
975 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
976 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
978 pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
979 DISSECTOR_ASSERT(pushed_tree != NULL);
980 if (ptvc->pushed_tree)
981 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
982 ptvc->pushed_tree = pushed_tree;
986 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
988 ptvc->pushed_tree = NULL;
989 ptvc->pushed_tree_max = 0;
990 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
991 ptvc->pushed_tree_index = 0;
994 /* Allocates an initializes a ptvcursor_t with 3 variables:
995 * proto_tree, tvbuff, and offset. */
997 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
1001 ptvc = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
1004 ptvc->offset = offset;
1005 ptvc->pushed_tree = NULL;
1006 ptvc->pushed_tree_max = 0;
1007 ptvc->pushed_tree_index = 0;
1012 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1014 ptvcursor_free(ptvcursor_t *ptvc)
1016 ptvcursor_free_subtree_levels(ptvc);
1020 /* Returns tvbuff. */
1022 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1027 /* Returns current offset. */
1029 ptvcursor_current_offset(ptvcursor_t *ptvc)
1031 return ptvc->offset;
1035 ptvcursor_tree(ptvcursor_t *ptvc)
1044 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1049 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1051 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1053 subtree_lvl *subtree;
1054 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1055 ptvcursor_new_subtree_levels(ptvc);
1057 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1058 subtree->tree = ptvc->tree;
1060 ptvc->pushed_tree_index++;
1061 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1064 /* pops a subtree */
1066 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1068 subtree_lvl *subtree;
1070 if (ptvc->pushed_tree_index <= 0)
1073 ptvc->pushed_tree_index--;
1074 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1075 if (subtree->it != NULL)
1076 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1078 ptvc->tree = subtree->tree;
1081 /* saves the current tvb offset and the item in the current subtree level */
1083 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1085 subtree_lvl *subtree;
1087 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1089 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1091 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1094 /* Creates a subtree and adds it to the cursor as the working tree but does not
1095 * save the old working tree */
1097 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1099 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1104 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1106 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1107 if (length == SUBTREE_UNDEFINED_LENGTH)
1108 ptvcursor_subtree_set_item(ptvc, it);
1109 return ptvcursor_tree(ptvc);
1112 /* Add an item to the tree and create a subtree
1113 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1114 * In this case, when the subtree will be closed, the parent item length will
1115 * be equal to the advancement of the cursor since the creation of the subtree.
1118 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1119 const guint encoding, gint ett_subtree)
1123 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1124 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1128 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1130 /* Add a text node to the tree and create a subtree
1131 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1132 * In this case, when the subtree will be closed, the item length will be equal
1133 * to the advancement of the cursor since the creation of the subtree.
1136 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1137 gint ett_subtree, const char *format, ...)
1141 header_field_info *hfinfo;
1144 tree = ptvcursor_tree(ptvc);
1146 CHECK_FOR_NULL_TREE(tree);
1148 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1150 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1151 ptvcursor_current_offset(ptvc), length);
1153 TRY_TO_FAKE_THIS_REPR(pi);
1155 va_start(ap, format);
1156 proto_tree_set_representation(pi, format, ap);
1159 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1162 /* Add a text-only node, leaving it to our caller to fill the text in */
1164 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1171 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1176 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1178 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1179 const char *format, ...)
1183 header_field_info *hfinfo;
1185 CHECK_FOR_NULL_TREE(tree);
1187 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1189 pi = proto_tree_add_text_node(tree, tvb, start, length);
1191 TRY_TO_FAKE_THIS_REPR(pi);
1193 va_start(ap, format);
1194 proto_tree_set_representation(pi, format, ap);
1200 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1202 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1203 gint length, const char *format, va_list ap)
1206 header_field_info *hfinfo;
1208 CHECK_FOR_NULL_TREE(tree);
1210 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1212 pi = proto_tree_add_text_node(tree, tvb, start, length);
1214 TRY_TO_FAKE_THIS_REPR(pi);
1216 proto_tree_set_representation(pi, format, ap);
1221 /* Add a text-only node that creates a subtree underneath.
1224 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1226 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1229 /* Add a text-only node that creates a subtree underneath.
1232 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1238 va_start(ap, format);
1239 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1242 if (tree_item != NULL)
1245 pt = proto_item_add_subtree(pi, idx);
1250 /* Add a text-only node for debugging purposes. The caller doesn't need
1251 * to worry about tvbuff, start, or length. Debug message gets sent to
1254 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1259 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1262 va_start(ap, format);
1263 proto_tree_set_representation(pi, format, ap);
1266 va_start(ap, format);
1267 vprintf(format, ap);
1275 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1278 header_field_info *hfinfo;
1280 CHECK_FOR_NULL_TREE(tree);
1282 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1284 pi = proto_tree_add_text_node(tree, tvb, start, length);
1286 TRY_TO_FAKE_THIS_REPR(pi);
1288 proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1294 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1297 header_field_info *hfinfo;
1299 CHECK_FOR_NULL_TREE(tree);
1301 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1303 pi = proto_tree_add_text_node(tree, tvb, start, length);
1305 TRY_TO_FAKE_THIS_REPR(pi);
1307 proto_item_set_text(pi, "%s", tvb_format_text_wsp(tvb, start, length));
1312 void proto_report_dissector_bug(const char *message)
1314 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1317 THROW_MESSAGE(DissectorError, message);
1320 /* We could probably get away with changing is_error to a minimum length value. */
1322 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1325 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1327 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1331 THROW(ReportedBoundsError);
1336 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1339 gboolean length_error;
1344 value = tvb_get_guint8(tvb, offset);
1348 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1349 : tvb_get_ntohs(tvb, offset);
1353 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1354 : tvb_get_ntoh24(tvb, offset);
1358 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1359 : tvb_get_ntohl(tvb, offset);
1364 length_error = TRUE;
1367 length_error = FALSE;
1368 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1369 : tvb_get_ntohl(tvb, offset);
1371 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1377 static inline guint64
1378 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1381 gboolean length_error;
1386 value = tvb_get_guint8(tvb, offset);
1390 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1391 : tvb_get_ntohs(tvb, offset);
1395 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1396 : tvb_get_ntoh24(tvb, offset);
1400 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1401 : tvb_get_ntohl(tvb, offset);
1405 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1406 : tvb_get_ntoh40(tvb, offset);
1410 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1411 : tvb_get_ntoh48(tvb, offset);
1415 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1416 : tvb_get_ntoh56(tvb, offset);
1420 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1421 : tvb_get_ntoh64(tvb, offset);
1426 length_error = TRUE;
1429 length_error = FALSE;
1430 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1431 : tvb_get_ntoh64(tvb, offset);
1433 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1440 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1443 gboolean length_error;
1448 value = (gint8)tvb_get_guint8(tvb, offset);
1452 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1453 : tvb_get_ntohs(tvb, offset));
1457 value = encoding ? tvb_get_letoh24(tvb, offset)
1458 : tvb_get_ntoh24(tvb, offset);
1459 if (value & 0x00800000) {
1460 /* Sign bit is set; sign-extend it. */
1461 value |= 0xFF000000;
1466 value = encoding ? tvb_get_letohl(tvb, offset)
1467 : tvb_get_ntohl(tvb, offset);
1472 length_error = TRUE;
1475 length_error = FALSE;
1476 value = encoding ? tvb_get_letohl(tvb, offset)
1477 : tvb_get_ntohl(tvb, offset);
1479 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1485 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1486 * be cast-able as a gint64. This is weird, but what the code has always done.
1488 static inline guint64
1489 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1491 guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1496 value = ws_sign_ext64(value, 56);
1499 value = ws_sign_ext64(value, 48);
1502 value = ws_sign_ext64(value, 40);
1505 value = ws_sign_ext64(value, 32);
1508 value = ws_sign_ext64(value, 24);
1511 value = ws_sign_ext64(value, 16);
1514 value = ws_sign_ext64(value, 8);
1522 static inline const guint8 *
1523 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1524 gint length, gint *ret_length, const guint encoding)
1527 length = tvb_ensure_captured_length_remaining(tvb, start);
1529 *ret_length = length;
1530 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1533 /* For FT_STRINGZ */
1534 static inline const guint8 *
1535 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1536 gint start, gint length, gint *ret_length, const guint encoding)
1538 const guint8 *value;
1541 report_type_length_mismatch(tree, "a string", length, TRUE);
1544 /* This can throw an exception */
1545 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1546 } else if (length == 0) {
1549 /* In this case, length signifies the length of the string.
1551 * This could either be a null-padded string, which doesn't
1552 * necessarily have a '\0' at the end, or a null-terminated
1553 * string, with a trailing '\0'. (Yes, there are cases
1554 * where you have a string that's both counted and null-
1557 * In the first case, we must allocate a buffer of length
1558 * "length+1", to make room for a trailing '\0'.
1560 * In the second case, we don't assume that there is a
1561 * trailing '\0' there, as the packet might be malformed.
1562 * (XXX - should we throw an exception if there's no
1563 * trailing '\0'?) Therefore, we allocate a buffer of
1564 * length "length+1", and put in a trailing '\0', just to
1567 * (XXX - this would change if we made string values counted
1568 * rather than null-terminated.)
1570 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1572 *ret_length = length;
1576 /* For FT_UINT_STRING */
1577 static inline const guint8 *
1578 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1579 tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1580 const guint encoding)
1583 const guint8 *value;
1585 /* I believe it's ok if this is called with a NULL tree */
1586 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1587 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1589 *ret_length = length;
1593 /* For FT_STRINGZPAD */
1594 static inline const guint8 *
1595 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1596 gint length, gint *ret_length, const guint encoding)
1599 * XXX - currently, string values are null-
1600 * terminated, so a "zero-padded" string
1601 * isn't special. If we represent string
1602 * values as something that includes a counted
1603 * array of bytes, we'll need to strip
1607 length = tvb_ensure_captured_length_remaining(tvb, start);
1609 *ret_length = length;
1610 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1613 /* this can be called when there is no tree, so don't add that as a param */
1615 get_time_value(tvbuff_t *tvb, const gint start, const gint length, const guint encoding,
1616 nstime_t *time_stamp, const gboolean is_relative)
1621 /* relative timestamps don't do TOD/NTP */
1623 (encoding != (ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN)) &&
1624 (encoding != (ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN)) )
1626 /* XXX: I think this should call REPORT_DISSECTOR_BUG(), but
1627 the existing code didn't do that, so I'm not either */
1633 case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1635 * 4-byte UNIX epoch, possibly followed by
1636 * 4-byte fractional time in nanoseconds,
1639 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1641 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1643 time_stamp->nsecs = 0;
1646 case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1648 * 4-byte UNIX epoch, possibly followed by
1649 * 4-byte fractional time in nanoseconds,
1650 * both little-endian.
1652 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1654 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1656 time_stamp->nsecs = 0;
1659 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1661 * TOD time stamp, big-endian.
1663 /* XXX - where should this go? */
1664 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800)
1666 todsecs = tvb_get_ntoh64(tvb, start) >> 12;
1667 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1668 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1671 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1673 * TOD time stamp, big-endian.
1675 todsecs = tvb_get_letoh64(tvb, start) >> 12 ;
1676 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1677 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1680 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1682 * NTP time stamp, big-endian.
1685 /* XXX - where should this go? */
1686 #define NTP_BASETIME G_GUINT64_CONSTANT(2208988800)
1688 /* We need a temporary variable here so the unsigned math
1689 * works correctly (for years > 2036 according to RFC 2030
1692 tmpsecs = tvb_get_ntohl(tvb, start);
1694 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1696 time_stamp->secs = tmpsecs; /* 0 */
1700 * We're using nanoseconds here (and we will
1701 * display nanoseconds), but NTP's timestamps
1702 * have a precision in microseconds or greater.
1703 * Round to 1 microsecond.
1705 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1706 time_stamp->nsecs *= 1000;
1708 time_stamp->nsecs = 0;
1712 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1714 * NTP time stamp, big-endian.
1716 tmpsecs = tvb_get_letohl(tvb, start);
1718 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1720 time_stamp->secs = tmpsecs; /* 0 */
1724 * We're using nanoseconds here (and we will
1725 * display nanoseconds), but NTP's timestamps
1726 * have a precision in microseconds or greater.
1727 * Round to 1 microsecond.
1729 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1730 time_stamp->nsecs *= 1000;
1732 time_stamp->nsecs = 0;
1735 case ENC_TIME_NTP_BASE_ZERO|ENC_BIG_ENDIAN:
1737 * DDS NTP time stamp, big-endian.
1740 #define NTP_BASETIME_ZERO G_GUINT64_CONSTANT(0)
1742 tmpsecs = tvb_get_ntohl(tvb, start);
1744 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1746 time_stamp->secs = tmpsecs; /* 0 */
1750 * We're using nanoseconds here (and we will
1751 * display nanoseconds), but NTP's timestamps
1752 * have a precision in microseconds or greater.
1753 * Round to 1 microsecond.
1755 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1756 time_stamp->nsecs *= 1000;
1758 time_stamp->nsecs = 0;
1762 case ENC_TIME_NTP_BASE_ZERO|ENC_LITTLE_ENDIAN:
1764 * NTP time stamp, big-endian.
1766 tmpsecs = tvb_get_letohl(tvb, start);
1768 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1770 time_stamp->secs = tmpsecs; /* 0 */
1771 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1774 * We're using nanoseconds here (and we will
1775 * display nanoseconds), but NTP's timestamps
1776 * have a precision in microseconds or greater.
1777 * Round to 1 microsecond.
1779 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1780 time_stamp->nsecs *= 1000;
1782 time_stamp->nsecs = 0;
1787 DISSECTOR_ASSERT_NOT_REACHED();
1793 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
1795 const header_field_info *hfinfo = fi->hfinfo;
1797 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
1798 GPtrArray *ptrs = NULL;
1800 if (tree_data->interesting_hfids == NULL) {
1801 /* Initialize the hash because we now know that it is needed */
1802 tree_data->interesting_hfids =
1803 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
1804 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
1805 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
1806 GINT_TO_POINTER(hfinfo->id));
1810 /* First element triggers the creation of pointer array */
1811 ptrs = g_ptr_array_new();
1812 g_hash_table_insert(tree_data->interesting_hfids,
1813 GINT_TO_POINTER(hfinfo->id), ptrs);
1816 g_ptr_array_add(ptrs, fi);
1820 /* Add an item to a proto_tree, using the text label registered to that item;
1821 the item is extracted from the tvbuff handed to it. */
1823 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
1824 tvbuff_t *tvb, gint start, gint length,
1831 const char *stringval;
1832 nstime_t time_stamp;
1833 gboolean length_error;
1835 switch (new_fi->hfinfo->type) {
1837 /* no value to set for FT_NONE */
1841 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
1845 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
1850 * Map all non-zero values to little-endian for
1851 * backwards compatibility.
1854 encoding = ENC_LITTLE_ENDIAN;
1855 n = get_uint_value(tree, tvb, start, length, encoding);
1856 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
1858 /* Instead of calling proto_item_set_len(), since we don't yet
1859 * have a proto_item, we set the field_info's length ourselves. */
1860 new_fi->length = n + length;
1865 * Map all non-zero values to little-endian for
1866 * backwards compatibility.
1869 encoding = ENC_LITTLE_ENDIAN;
1870 proto_tree_set_boolean(new_fi,
1871 get_uint64_value(tree, tvb, start, length, encoding));
1874 /* XXX - make these just FT_UINT? */
1880 * Map all non-zero values to little-endian for
1881 * backwards compatibility.
1884 encoding = ENC_LITTLE_ENDIAN;
1885 proto_tree_set_uint(new_fi,
1886 get_uint_value(tree, tvb, start, length, encoding));
1894 * Map all non-zero values to little-endian for
1895 * backwards compatibility.
1898 encoding = ENC_LITTLE_ENDIAN;
1899 proto_tree_set_uint64(new_fi,
1900 get_uint64_value(tree, tvb, start, length, encoding));
1903 /* XXX - make these just FT_INT? */
1909 * Map all non-zero values to little-endian for
1910 * backwards compatibility.
1913 encoding = ENC_LITTLE_ENDIAN;
1914 proto_tree_set_int(new_fi,
1915 get_int_value(tree, tvb, start, length, encoding));
1923 * Map all non-zero values to little-endian for
1924 * backwards compatibility.
1927 encoding = ENC_LITTLE_ENDIAN;
1928 proto_tree_set_int64(new_fi,
1929 get_int64_value(tree, tvb, start, length, encoding));
1934 * Map all non-zero values to little-endian for
1935 * backwards compatibility.
1938 encoding = ENC_LITTLE_ENDIAN;
1939 if (length != FT_IPv4_LEN) {
1940 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
1941 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
1943 value = tvb_get_ipv4(tvb, start);
1945 * NOTE: to support code written when
1946 * proto_tree_add_item() took a gboolean as its
1947 * last argument, with FALSE meaning "big-endian"
1948 * and TRUE meaning "little-endian", we treat any
1949 * non-zero value of "encoding" as meaning
1952 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
1956 if (length != FT_IPXNET_LEN) {
1957 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
1958 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
1960 proto_tree_set_ipxnet(new_fi,
1961 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
1965 if (length != FT_IPv6_LEN) {
1966 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
1967 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
1969 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
1973 if (length != FT_FCWWN_LEN) {
1974 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
1975 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
1977 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
1982 length_error = length < 7 ? TRUE : FALSE;
1983 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
1985 proto_tree_set_ax25_tvb(new_fi, tvb, start);
1989 if (length != VINES_ADDR_LEN) {
1990 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
1991 report_type_length_mismatch(tree, "a Vines address", length, length_error);
1993 proto_tree_set_vines_tvb(new_fi, tvb, start);
1997 if (length != FT_ETHER_LEN) {
1998 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
1999 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2001 proto_tree_set_ether_tvb(new_fi, tvb, start);
2006 * Map all non-zero values to little-endian for
2007 * backwards compatibility.
2010 encoding = ENC_LITTLE_ENDIAN;
2011 if (length != FT_EUI64_LEN) {
2012 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2013 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2015 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2019 * Map all non-zero values to little-endian for
2020 * backwards compatibility.
2023 encoding = ENC_LITTLE_ENDIAN;
2024 if (length != FT_GUID_LEN) {
2025 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2026 report_type_length_mismatch(tree, "a GUID", length, length_error);
2028 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2033 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2037 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2042 * NOTE: to support code written when
2043 * proto_tree_add_item() took a gboolean as its
2044 * last argument, with FALSE meaning "big-endian"
2045 * and TRUE meaning "little-endian", we treat any
2046 * non-zero value of "encoding" as meaning
2049 * At some point in the future, we might
2050 * support non-IEEE-binary floating-point
2051 * formats in the encoding as well
2052 * (IEEE decimal, System/3x0, VAX).
2055 encoding = ENC_LITTLE_ENDIAN;
2057 length_error = length < 4 ? TRUE : FALSE;
2058 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2061 floatval = tvb_get_letohieee_float(tvb, start);
2063 floatval = tvb_get_ntohieee_float(tvb, start);
2064 proto_tree_set_float(new_fi, floatval);
2069 * NOTE: to support code written when
2070 * proto_tree_add_item() took a gboolean as its
2071 * last argument, with FALSE meaning "big-endian"
2072 * and TRUE meaning "little-endian", we treat any
2073 * non-zero value of "encoding" as meaning
2076 * At some point in the future, we might
2077 * support non-IEEE-binary floating-point
2078 * formats in the encoding as well
2079 * (IEEE decimal, System/3x0, VAX).
2081 if (encoding == TRUE)
2082 encoding = ENC_LITTLE_ENDIAN;
2084 length_error = length < 8 ? TRUE : FALSE;
2085 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2088 doubleval = tvb_get_letohieee_double(tvb, start);
2090 doubleval = tvb_get_ntohieee_double(tvb, start);
2091 proto_tree_set_double(new_fi, doubleval);
2095 stringval = get_string_value(wmem_packet_scope(),
2096 tvb, start, length, &length, encoding);
2097 proto_tree_set_string(new_fi, stringval);
2099 /* Instead of calling proto_item_set_len(), since we
2100 * don't yet have a proto_item, we set the
2101 * field_info's length ourselves.
2103 * XXX - our caller can't use that length to
2104 * advance an offset unless they arrange that
2105 * there always be a protocol tree into which
2106 * we're putting this item.
2108 new_fi->length = length;
2112 stringval = get_stringz_value(wmem_packet_scope(),
2113 tree, tvb, start, length, &length, encoding);
2114 proto_tree_set_string(new_fi, stringval);
2116 /* Instead of calling proto_item_set_len(),
2117 * since we don't yet have a proto_item, we
2118 * set the field_info's length ourselves.
2120 * XXX - our caller can't use that length to
2121 * advance an offset unless they arrange that
2122 * there always be a protocol tree into which
2123 * we're putting this item.
2125 new_fi->length = length;
2128 case FT_UINT_STRING:
2130 * NOTE: to support code written when
2131 * proto_tree_add_item() took a gboolean as its
2132 * last argument, with FALSE meaning "big-endian"
2133 * and TRUE meaning "little-endian", if the
2134 * encoding value is TRUE, treat that as
2135 * ASCII with a little-endian length.
2137 * This won't work for code that passes
2138 * arbitrary non-zero values; that code
2139 * will need to be fixed.
2141 if (encoding == TRUE)
2142 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2143 stringval = get_uint_string_value(wmem_packet_scope(),
2144 tree, tvb, start, length, &length, encoding);
2145 proto_tree_set_string(new_fi, stringval);
2147 /* Instead of calling proto_item_set_len(), since we
2148 * don't yet have a proto_item, we set the
2149 * field_info's length ourselves.
2151 * XXX - our caller can't use that length to
2152 * advance an offset unless they arrange that
2153 * there always be a protocol tree into which
2154 * we're putting this item.
2156 new_fi->length = length;
2160 stringval = get_stringzpad_value(wmem_packet_scope(),
2161 tvb, start, length, &length, encoding);
2162 proto_tree_set_string(new_fi, stringval);
2164 /* Instead of calling proto_item_set_len(), since we
2165 * don't yet have a proto_item, we set the
2166 * field_info's length ourselves.
2168 * XXX - our caller can't use that length to
2169 * advance an offset unless they arrange that
2170 * there always be a protocol tree into which
2171 * we're putting this item.
2173 new_fi->length = length;
2176 case FT_ABSOLUTE_TIME:
2178 * Absolute times can be in any of a number of
2179 * formats, and they can be big-endian or
2182 * Historically FT_TIMEs were only timespecs;
2183 * the only question was whether they were stored
2184 * in big- or little-endian format.
2186 * For backwards compatibility, we interpret an
2187 * encoding of 1 as meaning "little-endian timespec",
2188 * so that passing TRUE is interpreted as that.
2190 if (encoding == TRUE)
2191 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2193 if (length != 8 && length != 4) {
2194 length_error = length < 4 ? TRUE : FALSE;
2195 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2198 get_time_value(tvb, start, length, encoding, &time_stamp, FALSE);
2200 proto_tree_set_time(new_fi, &time_stamp);
2203 case FT_RELATIVE_TIME:
2205 * Relative times can be in any of a number of
2206 * formats, and they can be big-endian or
2209 * Historically FT_TIMEs were only timespecs;
2210 * the only question was whether they were stored
2211 * in big- or little-endian format.
2213 * For backwards compatibility, we interpret an
2214 * encoding of 1 as meaning "little-endian timespec",
2215 * so that passing TRUE is interpreted as that.
2217 if (encoding == TRUE)
2218 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2220 if (length != 8 && length != 4) {
2221 length_error = length < 4 ? TRUE : FALSE;
2222 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2225 get_time_value(tvb, start, length, encoding, &time_stamp, TRUE);
2227 proto_tree_set_time(new_fi, &time_stamp);
2229 case FT_IEEE_11073_SFLOAT:
2231 encoding = ENC_LITTLE_ENDIAN;
2233 length_error = length < 2 ? TRUE : FALSE;
2234 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2237 fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2240 case FT_IEEE_11073_FLOAT:
2242 encoding = ENC_LITTLE_ENDIAN;
2244 length_error = length < 4 ? TRUE : FALSE;
2245 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2250 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2251 new_fi->hfinfo->type,
2252 ftype_name(new_fi->hfinfo->type));
2253 DISSECTOR_ASSERT_NOT_REACHED();
2256 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2258 /* Don't add new node to proto_tree until now so that any exceptions
2259 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2260 /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2261 * to know which item caused exception? */
2262 pi = proto_tree_add_node(tree, new_fi);
2268 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2269 const gint start, gint length,
2270 const guint encoding, gint32 *retval)
2272 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2276 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2278 switch (hfinfo->type){
2285 DISSECTOR_ASSERT_NOT_REACHED();
2288 /* length validation for native number encoding caught by get_uint_value() */
2289 /* length has to be -1 or > 0 regardless of encoding */
2290 if (length < -1 || length == 0)
2291 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2292 "Invalid length %d passed to proto_tree_add_item_ret_int",
2295 if (encoding & ENC_STRING) {
2296 REPORT_DISSECTOR_BUG("wrong encoding");
2298 /* I believe it's ok if this is called with a NULL tree */
2299 value = get_int_value(tree, tvb, start, length, encoding);
2304 CHECK_FOR_NULL_TREE(tree);
2306 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2308 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2310 proto_tree_set_int(new_fi, value);
2312 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2314 return proto_tree_add_node(tree, new_fi);
2318 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2319 const gint start, gint length,
2320 const guint encoding, guint32 *retval)
2322 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2326 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2328 switch (hfinfo->type){
2335 DISSECTOR_ASSERT_NOT_REACHED();
2338 /* length validation for native number encoding caught by get_uint_value() */
2339 /* length has to be -1 or > 0 regardless of encoding */
2340 if (length < -1 || length == 0)
2341 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2342 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2345 if (encoding & ENC_STRING) {
2346 REPORT_DISSECTOR_BUG("wrong encoding");
2348 /* I believe it's ok if this is called with a NULL tree */
2349 value = get_uint_value(tree, tvb, start, length, encoding);
2354 CHECK_FOR_NULL_TREE(tree);
2356 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2358 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2360 proto_tree_set_uint(new_fi, value);
2362 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2364 return proto_tree_add_node(tree, new_fi);
2368 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
2370 const gint start, gint length,
2371 const guint encoding,
2372 wmem_allocator_t *scope,
2373 const guint8 **retval,
2376 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2378 const guint8 *value;
2380 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2382 switch (hfinfo->type){
2384 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
2387 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
2389 case FT_UINT_STRING:
2390 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
2393 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
2396 DISSECTOR_ASSERT_NOT_REACHED();
2402 CHECK_FOR_NULL_TREE(tree);
2404 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2406 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2408 proto_tree_set_string(new_fi, value);
2410 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2412 return proto_tree_add_node(tree, new_fi);
2416 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2417 const gint start, gint length,
2418 const guint encoding, wmem_allocator_t *scope,
2419 const guint8 **retval)
2421 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
2422 tvb, start, length, encoding, scope, retval, &length);
2426 * Validates that field length bytes are available starting from
2427 * start (pos/neg). Throws an exception if they aren't.
2430 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2431 gint start, gint length)
2438 if (hfinfo->type == FT_STRINGZ) {
2439 /* If we're fetching until the end of the TVB, only validate
2440 * that the offset is within range.
2446 tvb_ensure_bytes_exist(tvb, start, size);
2449 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2450 and returns proto_item* */
2452 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
2453 const guint encoding)
2456 header_field_info *hfinfo;
2460 offset = ptvc->offset;
2461 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2462 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
2463 test_length(hfinfo, ptvc->tvb, offset, item_length);
2465 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2466 item_length, encoding);
2468 CHECK_FOR_NULL_TREE(ptvc->tree);
2470 /* Coast clear. Try and fake it */
2471 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2473 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2475 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2476 offset, length, encoding);
2479 /* Add an item to a proto_tree, using the text label registered to that item;
2480 the item is extracted from the tvbuff handed to it. */
2482 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
2483 const gint start, gint length, const guint encoding)
2488 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2490 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2491 test_length(hfinfo, tvb, start, item_length);
2493 CHECK_FOR_NULL_TREE(tree);
2495 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2497 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2499 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2503 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2504 const gint start, gint length, const guint encoding)
2506 register header_field_info *hfinfo;
2508 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2509 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
2512 /* Add an item to a proto_tree, using the text label registered to that item;
2513 the item is extracted from the tvbuff handed to it.
2515 Return the length of the item through the pointer. */
2517 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
2518 tvbuff_t *tvb, const gint start,
2519 gint length, const guint encoding,
2526 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2528 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2529 test_length(hfinfo, tvb, start, item_length);
2533 * We need to get the correct item length here.
2534 * That's normally done by proto_tree_new_item(),
2535 * but we won't be calling it.
2537 *lenretval = get_full_length(hfinfo, tvb, start, length,
2538 item_length, encoding);
2542 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2544 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2546 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2547 *lenretval = new_fi->length;
2552 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2553 const gint start, gint length,
2554 const guint encoding, gint *lenretval)
2556 register header_field_info *hfinfo;
2558 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2559 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
2562 /* which FT_ types can use proto_tree_add_bytes_item() */
2563 static inline gboolean
2564 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
2566 return (type == FT_BYTES ||
2567 type == FT_UINT_BYTES ||
2569 type == FT_REL_OID ||
2570 type == FT_SYSTEM_ID );
2573 /* Note: this does no validation that the byte array of an FT_OID or
2574 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
2575 so I think it's ok to continue not validating it?
2578 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2579 const gint start, gint length, const guint encoding,
2580 GByteArray *retval, gint *endoff, gint *err)
2583 GByteArray *bytes = retval;
2584 GByteArray *created_bytes = NULL;
2587 header_field_info *hfinfo;
2588 gboolean generate = (bytes || tree) ? TRUE : FALSE;
2590 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2592 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2594 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
2595 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
2597 /* length has to be -1 or > 0 regardless of encoding */
2598 /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
2599 if (length < -1 || length == 0) {
2600 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2601 "Invalid length %d passed to proto_tree_add_bytes_item for %s",
2602 length, ftype_name(hfinfo->type)));
2605 if (encoding & ENC_STR_NUM) {
2606 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
2609 if (generate && (encoding & ENC_STR_HEX)) {
2610 if (hfinfo->type == FT_UINT_BYTES) {
2611 /* can't decode FT_UINT_BYTES from strings */
2612 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
2613 "FT_UINT_BYTES type, but as ENC_STR_HEX");
2617 /* caller doesn't care about return value, but we need it to
2618 call tvb_get_string_bytes() and set the tree later */
2619 bytes = created_bytes = g_byte_array_new();
2622 /* bytes might be NULL after this, but can't add expert error until later */
2623 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
2625 /* grab the errno now before it gets overwritten */
2628 else if (generate) {
2629 tvb_ensure_bytes_exist(tvb, start, length);
2632 /* caller doesn't care about return value, but we need it to
2633 call tvb_get_string_bytes() and set the tree later */
2634 bytes = created_bytes = g_byte_array_new();
2637 if (hfinfo->type == FT_UINT_BYTES) {
2638 n = length; /* n is now the "header" length */
2639 length = get_uint_value(tree, tvb, start, n, encoding);
2640 /* length is now the value's length; only store the value in the array */
2641 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
2643 else if (length > 0) {
2644 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
2648 *endoff = start + n + length;
2651 if (err) *err = saved_err;
2653 CHECK_FOR_NULL_TREE_AND_FREE(tree,
2656 g_byte_array_free(created_bytes, TRUE);
2657 created_bytes = NULL;
2661 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
2664 g_byte_array_free(created_bytes, TRUE);
2665 created_bytes = NULL;
2669 /* n will be zero except when it's a FT_UINT_BYTES */
2670 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
2672 if (encoding & ENC_STRING) {
2673 if (saved_err == ERANGE)
2674 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2675 else if (!bytes || saved_err != 0)
2676 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2679 proto_tree_set_bytes_gbytearray(new_fi, bytes);
2681 proto_tree_set_bytes(new_fi, NULL, 0);
2684 g_byte_array_free(created_bytes, TRUE);
2687 /* n will be zero except when it's a FT_UINT_BYTES */
2688 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
2691 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2694 return proto_tree_add_node(tree, new_fi);
2699 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2700 const gint start, gint length, const guint encoding,
2701 nstime_t *retval, gint *endoff, gint *err)
2704 nstime_t time_stamp;
2706 header_field_info *hfinfo;
2708 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2710 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2712 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
2714 /* length has to be -1 or > 0 regardless of encoding */
2715 if (length < -1 || length == 0) {
2716 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2717 "Invalid length %d passed to proto_tree_add_time_item", length));
2720 time_stamp.secs = 0;
2721 time_stamp.nsecs = 0;
2723 if (encoding & ENC_STR_TIME_MASK) {
2724 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
2725 /* grab the errno now before it gets overwritten */
2729 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
2731 if (length != 8 && length != 4) {
2732 const gboolean length_error = length < 4 ? TRUE : FALSE;
2734 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2736 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2739 tvb_ensure_bytes_exist(tvb, start, length);
2740 get_time_value(tvb, start, length, encoding, &time_stamp, is_relative);
2741 if (endoff) *endoff = length;
2744 if (err) *err = saved_err;
2747 retval->secs = time_stamp.secs;
2748 retval->nsecs = time_stamp.nsecs;
2751 CHECK_FOR_NULL_TREE(tree);
2753 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2755 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2757 proto_tree_set_time(new_fi, &time_stamp);
2759 if (encoding & ENC_STRING) {
2760 if (saved_err == ERANGE)
2761 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2762 else if (saved_err == EDOM)
2763 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2767 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2770 return proto_tree_add_node(tree, new_fi);
2773 /* Add a FT_NONE to a proto_tree */
2775 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
2776 const gint start, gint length, const char *format,
2781 header_field_info *hfinfo;
2783 CHECK_FOR_NULL_TREE(tree);
2785 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2787 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
2789 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2791 TRY_TO_FAKE_THIS_REPR(pi);
2793 va_start(ap, format);
2794 proto_tree_set_representation(pi, format, ap);
2797 /* no value to set for FT_NONE */
2801 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
2802 * offset, and returns proto_item* */
2804 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
2805 const guint encoding)
2809 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
2815 /* Advance the ptvcursor's offset within its tvbuff without
2816 * adding anything to the proto_tree. */
2818 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
2820 ptvc->offset += length;
2825 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
2827 fvalue_set_protocol(&fi->value, tvb, field_data);
2830 /* Add a FT_PROTOCOL to a proto_tree */
2832 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2833 gint start, gint length, const char *format, ...)
2837 header_field_info *hfinfo;
2838 gchar* protocol_rep;
2840 CHECK_FOR_NULL_TREE(tree);
2842 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2844 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
2846 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2848 va_start(ap, format);
2849 protocol_rep = g_strdup_vprintf(format, ap);
2850 proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length)), protocol_rep);
2851 g_free(protocol_rep);
2854 TRY_TO_FAKE_THIS_REPR(pi);
2856 va_start(ap, format);
2857 proto_tree_set_representation(pi, format, ap);
2863 /* Add a FT_BYTES to a proto_tree */
2865 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2866 gint length, const guint8 *start_ptr)
2869 header_field_info *hfinfo;
2872 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2873 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2874 test_length(hfinfo, tvb, start, item_length);
2876 CHECK_FOR_NULL_TREE(tree);
2878 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2880 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2882 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2883 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
2888 /* Add a FT_BYTES to a proto_tree */
2890 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2891 gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
2894 header_field_info *hfinfo;
2897 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2898 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length);
2899 test_length(hfinfo, tvb, start, item_length);
2901 CHECK_FOR_NULL_TREE(tree);
2903 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2905 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2907 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
2908 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
2914 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2915 gint start, gint length,
2916 const guint8 *start_ptr,
2917 const char *format, ...)
2921 header_field_info *hfinfo;
2924 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2925 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2926 test_length(hfinfo, tvb, start, item_length);
2928 CHECK_FOR_NULL_TREE(tree);
2930 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2933 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2936 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2937 tvb_get_ptr(tvb, start, length));
2939 va_start(ap, format);
2940 proto_tree_set_representation_value(pi, format, ap);
2947 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2948 gint start, gint length, const guint8 *start_ptr,
2949 const char *format, ...)
2953 header_field_info *hfinfo;
2956 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2957 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2958 test_length(hfinfo, tvb, start, item_length);
2960 CHECK_FOR_NULL_TREE(tree);
2962 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2965 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2968 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2969 tvb_get_ptr(tvb, start, length));
2971 TRY_TO_FAKE_THIS_REPR(pi);
2973 va_start(ap, format);
2974 proto_tree_set_representation(pi, format, ap);
2981 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
2985 DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
2987 bytes = g_byte_array_new();
2989 g_byte_array_append(bytes, start_ptr, length);
2991 fvalue_set_byte_array(&fi->value, bytes);
2996 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
2998 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
3002 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
3006 DISSECTOR_ASSERT(value != NULL);
3008 bytes = byte_array_dup(value);
3010 fvalue_set_byte_array(&fi->value, bytes);
3013 /* Add a FT_*TIME to a proto_tree */
3015 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3016 gint length, const nstime_t *value_ptr)
3019 header_field_info *hfinfo;
3021 CHECK_FOR_NULL_TREE(tree);
3023 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3025 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3027 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3028 proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
3034 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3035 gint start, gint length, nstime_t *value_ptr,
3036 const char *format, ...)
3041 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3043 va_start(ap, format);
3044 proto_tree_set_representation_value(pi, format, ap);
3052 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3053 gint start, gint length, nstime_t *value_ptr,
3054 const char *format, ...)
3059 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3061 TRY_TO_FAKE_THIS_REPR(pi);
3063 va_start(ap, format);
3064 proto_tree_set_representation(pi, format, ap);
3071 /* Set the FT_*TIME value */
3073 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
3075 DISSECTOR_ASSERT(value_ptr != NULL);
3077 fvalue_set_time(&fi->value, value_ptr);
3080 /* Add a FT_IPXNET to a proto_tree */
3082 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3083 gint length, guint32 value)
3086 header_field_info *hfinfo;
3088 CHECK_FOR_NULL_TREE(tree);
3090 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3092 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
3094 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3095 proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
3101 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3102 gint start, gint length, guint32 value,
3103 const char *format, ...)
3108 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3110 va_start(ap, format);
3111 proto_tree_set_representation_value(pi, format, ap);
3119 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3120 gint start, gint length, guint32 value,
3121 const char *format, ...)
3126 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3128 TRY_TO_FAKE_THIS_REPR(pi);
3130 va_start(ap, format);
3131 proto_tree_set_representation(pi, format, ap);
3138 /* Set the FT_IPXNET value */
3140 proto_tree_set_ipxnet(field_info *fi, guint32 value)
3142 fvalue_set_uinteger(&fi->value, value);
3145 /* Add a FT_IPv4 to a proto_tree */
3147 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3148 gint length, guint32 value)
3151 header_field_info *hfinfo;
3153 CHECK_FOR_NULL_TREE(tree);
3155 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3157 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
3159 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3160 proto_tree_set_ipv4(PNODE_FINFO(pi), value);
3166 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3167 gint start, gint length, guint32 value,
3168 const char *format, ...)
3173 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3175 va_start(ap, format);
3176 proto_tree_set_representation_value(pi, format, ap);
3184 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3185 gint start, gint length, guint32 value,
3186 const char *format, ...)
3191 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3193 TRY_TO_FAKE_THIS_REPR(pi);
3195 va_start(ap, format);
3196 proto_tree_set_representation(pi, format, ap);
3203 /* Set the FT_IPv4 value */
3205 proto_tree_set_ipv4(field_info *fi, guint32 value)
3207 fvalue_set_uinteger(&fi->value, value);
3210 /* Add a FT_IPv6 to a proto_tree */
3212 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3213 gint length, const struct e_in6_addr *value_ptr)
3216 header_field_info *hfinfo;
3218 CHECK_FOR_NULL_TREE(tree);
3220 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3222 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
3224 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3225 proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
3231 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3232 gint start, gint length,
3233 const struct e_in6_addr *value_ptr,
3234 const char *format, ...)
3239 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3241 va_start(ap, format);
3242 proto_tree_set_representation_value(pi, format, ap);
3250 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3251 gint start, gint length,
3252 const struct e_in6_addr *value_ptr,
3253 const char *format, ...)
3258 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3260 TRY_TO_FAKE_THIS_REPR(pi);
3262 va_start(ap, format);
3263 proto_tree_set_representation(pi, format, ap);
3270 /* Set the FT_IPv6 value */
3272 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
3274 DISSECTOR_ASSERT(value_ptr != NULL);
3275 fvalue_set_bytes(&fi->value, value_ptr);
3279 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3281 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
3284 /* Set the FT_FCWWN value */
3286 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
3288 DISSECTOR_ASSERT(value_ptr != NULL);
3289 fvalue_set_bytes(&fi->value, value_ptr);
3293 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3295 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
3298 /* Add a FT_GUID to a proto_tree */
3300 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3301 gint length, const e_guid_t *value_ptr)
3304 header_field_info *hfinfo;
3306 CHECK_FOR_NULL_TREE(tree);
3308 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3310 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
3312 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3313 proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
3319 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3320 gint start, gint length,
3321 const e_guid_t *value_ptr,
3322 const char *format, ...)
3327 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3329 va_start(ap, format);
3330 proto_tree_set_representation_value(pi, format, ap);
3338 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3339 gint start, gint length, const e_guid_t *value_ptr,
3340 const char *format, ...)
3345 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3347 TRY_TO_FAKE_THIS_REPR(pi);
3349 va_start(ap, format);
3350 proto_tree_set_representation(pi, format, ap);
3357 /* Set the FT_GUID value */
3359 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
3361 DISSECTOR_ASSERT(value_ptr != NULL);
3362 fvalue_set_guid(&fi->value, value_ptr);
3366 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
3367 const guint encoding)
3371 tvb_get_guid(tvb, start, &guid, encoding);
3372 proto_tree_set_guid(fi, &guid);
3375 /* Add a FT_OID to a proto_tree */
3377 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3378 gint length, const guint8* value_ptr)
3381 header_field_info *hfinfo;
3383 CHECK_FOR_NULL_TREE(tree);
3385 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3387 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
3389 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3390 proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
3396 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3397 gint start, gint length,
3398 const guint8* value_ptr,
3399 const char *format, ...)
3404 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3406 va_start(ap, format);
3407 proto_tree_set_representation_value(pi, format, ap);
3415 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3416 gint start, gint length, const guint8* value_ptr,
3417 const char *format, ...)
3422 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3424 TRY_TO_FAKE_THIS_REPR(pi);
3426 va_start(ap, format);
3427 proto_tree_set_representation(pi, format, ap);
3434 /* Set the FT_OID value */
3436 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
3440 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3442 bytes = g_byte_array_new();
3444 g_byte_array_append(bytes, value_ptr, length);
3446 fvalue_set_byte_array(&fi->value, bytes);
3450 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3452 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
3455 /* Set the FT_SYSTEM_ID value */
3457 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
3461 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3463 bytes = g_byte_array_new();
3465 g_byte_array_append(bytes, value_ptr, length);
3467 fvalue_set_byte_array(&fi->value, bytes);
3471 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3473 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
3476 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
3477 * own copy of string, and frees it when the proto_tree is destroyed. */
3479 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3480 gint length, const char* value)
3483 header_field_info *hfinfo;
3485 CHECK_FOR_NULL_TREE(tree);
3487 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3489 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
3491 if (hfinfo->display == STR_UNICODE) {
3492 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
3495 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3496 DISSECTOR_ASSERT(length >= 0);
3497 proto_tree_set_string(PNODE_FINFO(pi), value);
3503 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3504 gint start, gint length, const char* value,
3511 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3513 va_start(ap, format);
3514 proto_tree_set_representation_value(pi, format, ap);
3522 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3523 gint start, gint length, const char* value,
3524 const char *format, ...)
3529 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3531 TRY_TO_FAKE_THIS_REPR(pi);
3533 va_start(ap, format);
3534 proto_tree_set_representation(pi, format, ap);
3541 /* Set the FT_STRING value */
3543 proto_tree_set_string(field_info *fi, const char* value)
3546 fvalue_set_string(&fi->value, value);
3548 fvalue_set_string(&fi->value, "[ Null ]");
3552 /* Set the FT_AX25 value */
3554 proto_tree_set_ax25(field_info *fi, const guint8* value)
3556 fvalue_set_bytes(&fi->value, value);
3560 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3562 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
3565 /* Set the FT_VINES value */
3567 proto_tree_set_vines(field_info *fi, const guint8* value)
3569 fvalue_set_bytes(&fi->value, value);
3573 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3575 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
3578 /* Add a FT_ETHER to a proto_tree */
3580 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3581 gint length, const guint8* value)
3584 header_field_info *hfinfo;
3586 CHECK_FOR_NULL_TREE(tree);
3588 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3590 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
3592 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3593 proto_tree_set_ether(PNODE_FINFO(pi), value);
3599 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3600 gint start, gint length, const guint8* value,
3601 const char *format, ...)
3606 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3608 va_start(ap, format);
3609 proto_tree_set_representation_value(pi, format, ap);
3617 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3618 gint start, gint length, const guint8* value,
3619 const char *format, ...)
3624 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3626 TRY_TO_FAKE_THIS_REPR(pi);
3628 va_start(ap, format);
3629 proto_tree_set_representation(pi, format, ap);
3636 /* Set the FT_ETHER value */
3638 proto_tree_set_ether(field_info *fi, const guint8* value)
3640 fvalue_set_bytes(&fi->value, value);
3644 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3646 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
3649 /* Add a FT_BOOLEAN to a proto_tree */
3651 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3652 gint length, guint32 value)
3655 header_field_info *hfinfo;
3657 CHECK_FOR_NULL_TREE(tree);
3659 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3661 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3663 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3664 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3670 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
3671 tvbuff_t *tvb, gint start, gint length,
3672 guint32 value, const char *format, ...)
3677 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3679 va_start(ap, format);
3680 proto_tree_set_representation_value(pi, format, ap);
3688 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3689 gint start, gint length, guint32 value,
3690 const char *format, ...)
3695 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3697 TRY_TO_FAKE_THIS_REPR(pi);
3699 va_start(ap, format);
3700 proto_tree_set_representation(pi, format, ap);
3708 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3709 gint length, guint64 value)
3712 header_field_info *hfinfo;
3714 CHECK_FOR_NULL_TREE(tree);
3716 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3718 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3720 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3721 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3726 /* Set the FT_BOOLEAN value */
3728 proto_tree_set_boolean(field_info *fi, guint64 value)
3730 proto_tree_set_uint64(fi, value);
3733 /* Generate, into "buf", a string showing the bits of a bitfield.
3734 Return a pointer to the character after that string. */
3735 /*XXX this needs a buf_len check */
3737 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3745 bit = G_GUINT64_CONSTANT(1) << (width - 1);
3748 /* This bit is part of the field. Show its value. */
3754 /* This bit is not part of the field. */
3769 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3773 p = other_decode_bitfield_value(buf, val, mask, width);
3774 p = g_stpcpy(p, " = ");
3779 /* Add a FT_FLOAT to a proto_tree */
3781 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3782 gint length, float value)
3785 header_field_info *hfinfo;
3787 CHECK_FOR_NULL_TREE(tree);
3789 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3791 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
3793 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3794 proto_tree_set_float(PNODE_FINFO(pi), value);
3800 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3801 gint start, gint length, float value,
3802 const char *format, ...)
3807 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3809 va_start(ap, format);
3810 proto_tree_set_representation_value(pi, format, ap);
3818 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3819 gint start, gint length, float value,
3820 const char *format, ...)
3825 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3827 TRY_TO_FAKE_THIS_REPR(pi);
3829 va_start(ap, format);
3830 proto_tree_set_representation(pi, format, ap);
3837 /* Set the FT_FLOAT value */
3839 proto_tree_set_float(field_info *fi, float value)
3841 fvalue_set_floating(&fi->value, value);
3844 /* Add a FT_DOUBLE to a proto_tree */
3846 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3847 gint length, double value)
3850 header_field_info *hfinfo;
3852 CHECK_FOR_NULL_TREE(tree);
3854 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3856 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
3858 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3859 proto_tree_set_double(PNODE_FINFO(pi), value);
3865 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3866 gint start, gint length, double value,
3867 const char *format, ...)
3872 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3874 va_start(ap, format);
3875 proto_tree_set_representation_value(pi, format, ap);
3883 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3884 gint start, gint length, double value,
3885 const char *format, ...)
3890 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3892 TRY_TO_FAKE_THIS_REPR(pi);
3894 va_start(ap, format);
3895 proto_tree_set_representation(pi, format, ap);
3902 /* Set the FT_DOUBLE value */
3904 proto_tree_set_double(field_info *fi, double value)
3906 fvalue_set_floating(&fi->value, value);
3909 /* Add FT_UINT{8,16,24,32} to a proto_tree */
3911 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3912 gint length, guint32 value)
3914 proto_item *pi = NULL;
3915 header_field_info *hfinfo;
3917 CHECK_FOR_NULL_TREE(tree);
3919 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3921 switch (hfinfo->type) {
3927 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3928 proto_tree_set_uint(PNODE_FINFO(pi), value);
3932 DISSECTOR_ASSERT_NOT_REACHED();
3939 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3940 gint start, gint length, guint32 value,
3941 const char *format, ...)
3946 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3948 va_start(ap, format);
3949 proto_tree_set_representation_value(pi, format, ap);
3957 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3958 gint start, gint length, guint32 value,
3959 const char *format, ...)
3964 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3966 TRY_TO_FAKE_THIS_REPR(pi);
3968 va_start(ap, format);
3969 proto_tree_set_representation(pi, format, ap);
3976 /* Set the FT_UINT{8,16,24,32} value */
3978 proto_tree_set_uint(field_info *fi, guint32 value)
3980 header_field_info *hfinfo;
3983 hfinfo = fi->hfinfo;
3986 if (hfinfo->bitmask) {
3987 /* Mask out irrelevant portions */
3988 integer &= (guint32)(hfinfo->bitmask);
3991 integer >>= hfinfo_bitshift(hfinfo);
3994 fvalue_set_uinteger(&fi->value, integer);
3997 /* Add FT_UINT{40,48,56,64} to a proto_tree */
3999 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4000 gint length, guint64 value)
4002 proto_item *pi = NULL;
4003 header_field_info *hfinfo;
4005 CHECK_FOR_NULL_TREE(tree);
4007 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4009 switch (hfinfo->type) {
4015 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4016 proto_tree_set_uint64(PNODE_FINFO(pi), value);
4020 DISSECTOR_ASSERT_NOT_REACHED();
4027 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4028 gint start, gint length, guint64 value,
4029 const char *format, ...)
4034 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4036 va_start(ap, format);
4037 proto_tree_set_representation_value(pi, format, ap);
4045 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4046 gint start, gint length, guint64 value,
4047 const char *format, ...)
4052 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4054 TRY_TO_FAKE_THIS_REPR(pi);
4056 va_start(ap, format);
4057 proto_tree_set_representation(pi, format, ap);
4064 /* Set the FT_UINT{40,48,56,64} value */
4066 proto_tree_set_uint64(field_info *fi, guint64 value)
4068 header_field_info *hfinfo;
4071 hfinfo = fi->hfinfo;
4074 if (hfinfo->bitmask) {
4075 /* Mask out irrelevant portions */
4076 integer &= hfinfo->bitmask;
4079 integer >>= hfinfo_bitshift(hfinfo);
4082 fvalue_set_uinteger64(&fi->value, integer);
4085 /* Add FT_INT{8,16,24,32} to a proto_tree */
4087 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4088 gint length, gint32 value)
4090 proto_item *pi = NULL;
4091 header_field_info *hfinfo;
4093 CHECK_FOR_NULL_TREE(tree);
4095 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4097 switch (hfinfo->type) {
4102 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4103 proto_tree_set_int(PNODE_FINFO(pi), value);
4107 DISSECTOR_ASSERT_NOT_REACHED();
4114 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4115 gint start, gint length, gint32 value,
4116 const char *format, ...)
4121 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4123 va_start(ap, format);
4124 proto_tree_set_representation_value(pi, format, ap);
4132 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4133 gint start, gint length, gint32 value,
4134 const char *format, ...)
4139 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4141 TRY_TO_FAKE_THIS_REPR(pi);
4143 va_start(ap, format);
4144 proto_tree_set_representation(pi, format, ap);
4151 /* Set the FT_INT{8,16,24,32} value */
4153 proto_tree_set_int(field_info *fi, gint32 value)
4155 header_field_info *hfinfo;
4159 hfinfo = fi->hfinfo;
4160 integer = (guint32) value;
4162 if (hfinfo->bitmask) {
4163 /* Mask out irrelevant portions */
4164 integer &= (guint32)(hfinfo->bitmask);
4167 integer >>= hfinfo_bitshift(hfinfo);
4169 no_of_bits = ws_count_ones(hfinfo->bitmask);
4170 integer = ws_sign_ext32(integer, no_of_bits);
4173 fvalue_set_sinteger(&fi->value, integer);
4176 /* Add FT_INT{40,48,56,64} to a proto_tree */
4178 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4179 gint length, gint64 value)
4181 proto_item *pi = NULL;
4182 header_field_info *hfinfo;
4184 CHECK_FOR_NULL_TREE(tree);
4186 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4188 switch (hfinfo->type) {
4193 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4194 proto_tree_set_int64(PNODE_FINFO(pi), value);
4198 DISSECTOR_ASSERT_NOT_REACHED();
4205 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4206 gint start, gint length, gint64 value,
4207 const char *format, ...)
4212 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4214 va_start(ap, format);
4215 proto_tree_set_representation_value(pi, format, ap);
4222 /* Set the FT_INT{40,48,56,64} value */
4224 proto_tree_set_int64(field_info *fi, gint64 value)
4226 header_field_info *hfinfo;
4230 hfinfo = fi->hfinfo;
4233 if (hfinfo->bitmask) {
4234 /* Mask out irrelevant portions */
4235 integer &= hfinfo->bitmask;
4238 integer >>= hfinfo_bitshift(hfinfo);
4240 no_of_bits = ws_count_ones(hfinfo->bitmask);
4241 integer = ws_sign_ext64(integer, no_of_bits);
4244 fvalue_set_sinteger64(&fi->value, integer);
4248 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4249 gint start, gint length, gint64 value,
4250 const char *format, ...)
4255 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4257 TRY_TO_FAKE_THIS_REPR(pi);
4259 va_start(ap, format);
4260 proto_tree_set_representation(pi, format, ap);
4267 /* Add a FT_EUI64 to a proto_tree */
4269 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4270 gint length, const guint64 value)
4273 header_field_info *hfinfo;
4275 CHECK_FOR_NULL_TREE(tree);
4277 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4279 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
4281 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4282 proto_tree_set_eui64(PNODE_FINFO(pi), value);
4288 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4289 gint start, gint length, const guint64 value,
4290 const char *format, ...)
4295 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4297 va_start(ap, format);
4298 proto_tree_set_representation_value(pi, format, ap);
4306 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4307 gint start, gint length, const guint64 value,
4308 const char *format, ...)
4313 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4315 TRY_TO_FAKE_THIS_REPR(pi);
4317 va_start(ap, format);
4318 proto_tree_set_representation(pi, format, ap);
4325 /* Set the FT_EUI64 value */
4327 proto_tree_set_eui64(field_info *fi, const guint64 value)
4329 fvalue_set_uinteger64(&fi->value, value);
4332 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
4336 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
4338 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
4342 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
4344 proto_tree_add_node(proto_tree *tree, field_info *fi)
4346 proto_node *pnode, *tnode, *sibling;
4351 * Restrict our depth. proto_tree_traverse_pre_order and
4352 * proto_tree_traverse_post_order (and possibly others) are recursive
4353 * so we need to be mindful of our stack size.
4355 if (tree->first_child == NULL) {
4356 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
4358 if (G_UNLIKELY(depth > MAX_TREE_LEVELS)) {
4359 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
4360 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u)",
4362 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
4368 * Make sure "tree" is ready to have subtrees under it, by
4369 * checking whether it's been given an ett_ value.
4371 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
4372 * node of the protocol tree. That node is not displayed,
4373 * so it doesn't need an ett_ value to remember whether it
4377 tfi = PNODE_FINFO(tnode);
4378 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
4379 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4380 "\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
4381 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
4382 /* XXX - is it safe to continue here? */
4385 pnode = wmem_new(PNODE_POOL(tree), proto_node);
4386 PROTO_NODE_INIT(pnode);
4387 pnode->parent = tnode;
4388 PNODE_FINFO(pnode) = fi;
4389 pnode->tree_data = PTREE_DATA(tree);
4391 if (tnode->last_child != NULL) {
4392 sibling = tnode->last_child;
4393 DISSECTOR_ASSERT(sibling->next == NULL);
4394 sibling->next = pnode;
4396 tnode->first_child = pnode;
4397 tnode->last_child = pnode;
4399 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
4401 return (proto_item *)pnode;
4405 /* Generic way to allocate field_info and add to proto_tree.
4406 * Sets *pfi to address of newly-allocated field_info struct */
4408 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
4415 get_hfi_length(hfinfo, tvb, start, length, &item_length);
4416 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4417 pi = proto_tree_add_node(tree, fi);
4424 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
4427 gint length_remaining;
4430 * We only allow a null tvbuff if the item has a zero length,
4431 * i.e. if there's no data backing it.
4433 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
4436 * XXX - in some protocols, there are 32-bit unsigned length
4437 * fields, so lengths in protocol tree and tvbuff routines
4438 * should really be unsigned. We should have, for those
4439 * field types for which "to the end of the tvbuff" makes sense,
4440 * additional routines that take no length argument and
4441 * add fields that run to the end of the tvbuff.
4443 if (*length == -1) {
4445 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
4446 * FT_STRINGZPAD fields, a length of -1 means "set the
4447 * length to what remains in the tvbuff".
4449 * The assumption is either that
4451 * 1) the length of the item can only be determined
4452 * by dissection (typically true of items with
4453 * subitems, which are probably FT_NONE or
4458 * 2) if the tvbuff is "short" (either due to a short
4459 * snapshot length or due to lack of reassembly of
4460 * fragments/segments/whatever), we want to display
4461 * what's available in the field (probably FT_BYTES
4462 * or FT_STRING) and then throw an exception later
4466 * 3) the field is defined to be "what's left in the
4469 * so we set the length to what remains in the tvbuff so
4470 * that, if we throw an exception while dissecting, it
4471 * has what is probably the right value.
4473 * For FT_STRINGZ, it means "the string is null-terminated,
4474 * not null-padded; set the length to the actual length
4475 * of the string", and if the tvbuff if short, we just
4476 * throw an exception.
4478 * It's not valid for any other type of field. For those
4479 * fields, we treat -1 the same way we treat other
4480 * negative values - we assume the length is a Really
4481 * Big Positive Number, and throw a ReportedBoundsError
4482 * exception, under the assumption that the Really Big
4483 * Length would run past the end of the packet.
4485 switch (hfinfo->type) {
4493 * We allow FT_PROTOCOLs to be zero-length -
4494 * for example, an ONC RPC NULL procedure has
4495 * neither arguments nor reply, so the
4496 * payload for that protocol is empty.
4498 * We also allow the others to be zero-length -
4499 * because that's the way the code has been for a
4502 * However, we want to ensure that the start
4503 * offset is not *past* the byte past the end
4504 * of the tvbuff: we throw an exception in that
4507 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
4508 DISSECTOR_ASSERT(*length >= 0);
4513 * Leave the length as -1, so our caller knows
4519 THROW(ReportedBoundsError);
4520 DISSECTOR_ASSERT_NOT_REACHED();
4522 *item_length = *length;
4524 *item_length = *length;
4525 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
4527 * These types are for interior nodes of the
4528 * tree, and don't have data associated with
4529 * them; if the length is negative (XXX - see
4530 * above) or goes past the end of the tvbuff,
4531 * cut it short at the end of the tvbuff.
4532 * That way, if this field is selected in
4533 * Wireshark, we don't highlight stuff past
4534 * the end of the data.
4536 /* XXX - what to do, if we don't have a tvb? */
4538 length_remaining = tvb_captured_length_remaining(tvb, start);
4539 if (*item_length < 0 ||
4540 (*item_length > 0 &&
4541 (length_remaining < *item_length)))
4542 *item_length = length_remaining;
4545 if (*item_length < 0) {
4546 THROW(ReportedBoundsError);
4552 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
4553 gint length, guint item_length, const gint encoding)
4558 * We need to get the correct item length here.
4559 * That's normally done by proto_tree_new_item(),
4560 * but we won't be calling it.
4562 switch (hfinfo->type) {
4568 * The length is the specified length.
4574 * Map all non-zero values to little-endian for
4575 * backwards compatibility.
4577 n = get_uint_value(NULL, tvb, start, length,
4578 encoding ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
4583 /* XXX - make these just FT_UINT? */
4592 /* XXX - make these just FT_INT? */
4617 * The length is the specified length.
4623 report_type_length_mismatch(NULL, "a string", length, TRUE);
4626 /* This can throw an exception */
4627 /* XXX - do this without fetching the string? */
4628 tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
4630 item_length = length;
4633 case FT_UINT_STRING:
4634 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
4639 case FT_ABSOLUTE_TIME:
4640 case FT_RELATIVE_TIME:
4641 case FT_IEEE_11073_SFLOAT:
4642 case FT_IEEE_11073_FLOAT:
4644 * The length is the specified length.
4649 g_error("hfinfo->type %d (%s) not handled\n",
4651 ftype_name(hfinfo->type));
4652 DISSECTOR_ASSERT_NOT_REACHED();
4659 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4660 const gint start, const gint item_length)
4664 FIELD_INFO_NEW(PNODE_POOL(tree), fi);
4666 fi->hfinfo = hfinfo;
4668 fi->start += (tvb)?tvb_raw_offset(tvb):0;
4669 fi->length = item_length;
4672 if (!PTREE_DATA(tree)->visible)
4673 FI_SET_FLAG(fi, FI_HIDDEN);
4674 fvalue_init(&fi->value, fi->hfinfo->type);
4677 /* add the data source tvbuff */
4678 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
4680 fi->appendix_start = 0;
4681 fi->appendix_length = 0;
4686 /* If the protocol tree is to be visible, set the representation of a
4687 proto_tree entry with the name of the field for the item and with
4688 the value formatted with the supplied printf-style format and
4691 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
4695 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
4696 * items string representation */
4697 if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
4699 field_info *fi = PITEM_FINFO(pi);
4700 header_field_info *hf;
4702 DISSECTOR_ASSERT(fi);
4706 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4707 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
4711 if (IS_FT_UINT(hf->type))
4712 val = fvalue_get_uinteger(&fi->value);
4714 val = fvalue_get_uinteger64(&fi->value);
4716 val <<= hfinfo_bitshift(hf);
4718 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
4719 ret = (int) (p - fi->rep->representation);
4722 /* put in the hf name */
4723 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
4725 /* If possible, Put in the value of the string */
4726 if (ret < ITEM_LABEL_LENGTH) {
4727 ret += g_vsnprintf(fi->rep->representation + ret,
4728 ITEM_LABEL_LENGTH - ret, format, ap);
4730 if (ret >= ITEM_LABEL_LENGTH) {
4731 /* Uh oh, we don't have enough room. Tell the user
4732 * that the field is truncated.
4734 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4739 /* If the protocol tree is to be visible, set the representation of a
4740 proto_tree entry with the representation formatted with the supplied
4741 printf-style format and argument list. */
4743 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
4745 int ret; /*tmp return value */
4746 field_info *fi = PITEM_FINFO(pi);
4748 DISSECTOR_ASSERT(fi);
4750 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4751 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4752 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
4754 if (ret >= ITEM_LABEL_LENGTH) {
4755 /* Uh oh, we don't have enough room. Tell the user
4756 * that the field is truncated.
4758 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4764 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
4766 switch (hfinfo->display) {
4768 return format_text(string, strlen(string));
4771 return format_text_wsp(string, strlen(string));
4774 /* XXX, format_unicode_text() */
4778 return format_text(string, strlen(string));
4782 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
4784 gsize res = g_strlcpy(dest, src, dest_size);
4786 if (res > dest_size)
4791 static header_field_info *
4792 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
4794 header_field_info *dup_hfinfo;
4796 if (hfinfo->same_name_prev_id == -1)
4798 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
4803 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
4805 g_free(last_field_name);
4806 last_field_name = NULL;
4808 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
4809 /* No hfinfo with the same name */
4810 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
4814 if (hfinfo->same_name_next) {
4815 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
4818 if (hfinfo->same_name_prev_id != -1) {
4819 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
4820 same_name_prev->same_name_next = hfinfo->same_name_next;
4821 if (!hfinfo->same_name_next) {
4822 /* It's always the latest added hfinfo which is stored in gpa_name_map */
4823 g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
4828 /* -------------------------- */
4830 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
4831 gchar *result, gchar *expr, const int size)
4836 ipv4_addr_and_mask *ipv4;
4837 struct e_in6_addr *ipv6;
4839 guint32 n_addr; /* network-order IPv4 address */
4841 const true_false_string *tfstring;
4843 int len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
4845 field_info *finfo = NULL;
4846 header_field_info* hfinfo;
4847 const gchar *abbrev = NULL;
4849 const char *hf_str_val;
4850 char number_buf[48];
4851 const char *number_out;
4857 g_assert(field_ids != NULL);
4858 while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
4859 field_id = *field_idx;
4860 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
4862 /* do we need to rewind ? */
4866 if (occurrence < 0) {
4867 /* Search other direction */
4868 while (hfinfo->same_name_prev_id != -1) {
4869 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
4874 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
4876 if (!finfos || !(len = g_ptr_array_len(finfos))) {
4877 if (occurrence < 0) {
4878 hfinfo = hfinfo->same_name_next;
4880 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4885 /* Are there enough occurrences of the field? */
4886 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
4887 if (occurrence < 0) {
4888 hfinfo = hfinfo->same_name_next;
4890 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4896 /* Calculate single index or set outer bounderies */
4897 if (occurrence < 0) {
4898 i = occurrence + len + prev_len;
4900 } else if (occurrence > 0) {
4901 i = occurrence - 1 - prev_len;
4908 prev_len += len; /* Count handled occurrences */
4911 finfo = (field_info *)g_ptr_array_index(finfos, i);
4913 if (offset_r && (offset_r < (size - 2)))
4914 result[offset_r++] = ',';
4916 if (offset_e && (offset_e < (size - 2)))
4917 expr[offset_e++] = ',';
4919 switch (hfinfo->type) {
4921 case FT_NONE: /* Nothing to add */
4922 if (offset_r == 0) {
4924 } else if (result[offset_r-1] == ',') {
4925 result[offset_r-1] = '\0';
4930 /* prevent multiple "yes" entries by setting result directly */
4931 g_strlcpy(result, "Yes", size);
4936 bytes = (guint8 *)fvalue_get(&finfo->value);
4938 switch(hfinfo->display)
4941 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
4944 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
4947 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
4950 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
4954 if (prefs.display_byte_fields_with_spaces)
4956 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
4960 str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
4964 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
4965 wmem_free(NULL, str);
4968 if (hfinfo->display & BASE_ALLOW_ZERO) {
4969 offset_r += protoo_strlcpy(result+offset_r, "<none>", size-offset_r);
4971 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
4976 case FT_ABSOLUTE_TIME:
4977 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
4978 offset_r += protoo_strlcpy(result+offset_r,
4981 wmem_free(NULL, tmpbuf);
4984 case FT_RELATIVE_TIME:
4985 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
4986 offset_r += protoo_strlcpy(result+offset_r,
4989 wmem_free(NULL, tmpbuf);
4993 number64 = fvalue_get_uinteger64(&finfo->value);
4994 tfstring = (const true_false_string *)&tfs_true_false;
4995 if (hfinfo->strings) {
4996 tfstring = (const struct true_false_string*) hfinfo->strings;
4998 offset_r += protoo_strlcpy(result+offset_r,
5000 tfstring->true_string :
5001 tfstring->false_string, size-offset_r);
5003 offset_e += protoo_strlcpy(expr+offset_e,
5004 number64 ? "1" : "0", size-offset_e);
5007 /* XXX - make these just FT_NUMBER? */
5018 number = IS_FT_INT(hfinfo->type) ?
5019 (guint32) fvalue_get_sinteger(&finfo->value) :
5020 fvalue_get_uinteger(&finfo->value);
5022 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5023 gchar tmp[ITEM_LABEL_LENGTH];
5024 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5026 DISSECTOR_ASSERT(fmtfunc);
5027 fmtfunc(tmp, number);
5029 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5031 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
5032 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5035 number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
5037 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5040 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
5042 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5045 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5046 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5048 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5050 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5053 offset_e = (int)strlen(expr);
5065 number64 = IS_FT_INT(hfinfo->type) ?
5066 (guint64) fvalue_get_sinteger64(&finfo->value) :
5067 fvalue_get_uinteger64(&finfo->value);
5069 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5070 gchar tmp[ITEM_LABEL_LENGTH];
5071 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
5073 DISSECTOR_ASSERT(fmtfunc64);
5074 fmtfunc64(tmp, number64);
5075 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5076 } else if (hfinfo->strings) {
5077 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
5080 number_out = hfinfo_number_value_format_display64(hfinfo, BASE_DEC, number_buf, number64);
5082 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5085 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
5087 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5090 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5091 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5093 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
5095 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5098 offset_e = (int)strlen(expr);
5102 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
5103 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5104 wmem_free(NULL, str);
5108 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&finfo->value);
5109 n_addr = ipv4_get_net_order_addr(ipv4);
5110 set_address (&addr, AT_IPv4, 4, &n_addr);
5111 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5112 offset_r = (int)strlen(result);
5116 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
5117 set_address (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
5118 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5119 offset_r = (int)strlen(result);
5123 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
5124 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5125 offset_r = (int)strlen(result);
5129 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
5130 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5131 offset_r = (int)strlen(result);
5135 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
5136 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5137 wmem_free(NULL, str);
5141 bytes = (guint8 *)fvalue_get(&finfo->value);
5142 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5143 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5144 wmem_free(NULL, str);
5146 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5147 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5148 wmem_free(NULL, str);
5152 bytes = (guint8 *)fvalue_get(&finfo->value);
5153 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5154 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5155 wmem_free(NULL, str);
5157 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5158 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5159 wmem_free(NULL, str);
5163 bytes = (guint8 *)fvalue_get(&finfo->value);
5164 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
5165 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5166 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5167 wmem_free(NULL, str);
5171 g_snprintf(result+offset_r, size-offset_r,
5172 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
5173 offset_r = (int)strlen(result);
5177 g_snprintf(result+offset_r, size-offset_r,
5178 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
5179 offset_r = (int)strlen(result);
5184 case FT_UINT_STRING:
5186 bytes = (guint8 *)fvalue_get(&finfo->value);
5187 offset_r += protoo_strlcpy(result+offset_r,
5188 hfinfo_format_text(hfinfo, bytes),
5192 case FT_IEEE_11073_SFLOAT:
5193 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5194 g_snprintf(result+offset_r, size-offset_r,
5197 wmem_free(NULL, str);
5198 offset_r = (int)strlen(result);
5201 case FT_IEEE_11073_FLOAT:
5202 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5203 g_snprintf(result+offset_r, size-offset_r,
5206 offset_r = (int)strlen(result);
5207 wmem_free(NULL, str);
5210 case FT_IPXNET: /*XXX really No column custom ?*/
5213 g_error("hfinfo->type %d (%s) not handled\n",
5215 ftype_name(hfinfo->type));
5216 DISSECTOR_ASSERT_NOT_REACHED();
5222 switch (hfinfo->type) {
5245 /* for these types, "expr" is filled in the loop above */
5249 /* for all others, just copy "result" to "expr" */
5250 g_strlcpy(expr, result, size);
5255 /* Store abbrev for return value */
5256 abbrev = hfinfo->abbrev;
5259 if (occurrence == 0) {
5260 /* Fetch next hfinfo with same name (abbrev) */
5261 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5268 return abbrev ? abbrev : "";
5272 /* Set text of proto_item after having already been created. */
5274 proto_item_set_text(proto_item *pi, const char *format, ...)
5276 field_info *fi = NULL;
5279 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5281 fi = PITEM_FINFO(pi);
5286 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
5290 va_start(ap, format);
5291 proto_tree_set_representation(pi, format, ap);
5295 /* Append to text of proto_item after having already been created. */
5297 proto_item_append_text(proto_item *pi, const char *format, ...)
5299 field_info *fi = NULL;
5303 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5305 fi = PITEM_FINFO(pi);
5310 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5312 * If we don't already have a representation,
5313 * generate the default representation.
5315 if (fi->rep == NULL) {
5316 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5317 proto_item_fill_label(fi, fi->rep->representation);
5320 curlen = strlen(fi->rep->representation);
5321 if (ITEM_LABEL_LENGTH > curlen) {
5322 va_start(ap, format);
5323 g_vsnprintf(fi->rep->representation + curlen,
5324 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
5330 /* Prepend to text of proto_item after having already been created. */
5332 proto_item_prepend_text(proto_item *pi, const char *format, ...)
5334 field_info *fi = NULL;
5335 char representation[ITEM_LABEL_LENGTH];
5338 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5340 fi = PITEM_FINFO(pi);
5345 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5347 * If we don't already have a representation,
5348 * generate the default representation.
5350 if (fi->rep == NULL) {
5351 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5352 proto_item_fill_label(fi, representation);
5354 g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
5356 va_start(ap, format);
5357 g_vsnprintf(fi->rep->representation,
5358 ITEM_LABEL_LENGTH, format, ap);
5360 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
5365 proto_item_set_len(proto_item *pi, const gint length)
5369 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5371 fi = PITEM_FINFO(pi);
5375 DISSECTOR_ASSERT(length >= 0);
5376 fi->length = length;
5379 * You cannot just make the "len" field of a GByteArray
5380 * larger, if there's no data to back that length;
5381 * you can only make it smaller.
5383 if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
5384 fi->value.value.bytes->len = length;
5388 * Sets the length of the item based on its start and on the specified
5389 * offset, which is the offset past the end of the item; as the start
5390 * in the item is relative to the beginning of the data source tvbuff,
5391 * we need to pass in a tvbuff - the end offset is relative to the beginning
5395 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
5399 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5401 fi = PITEM_FINFO(pi);
5405 end += tvb_raw_offset(tvb);
5406 DISSECTOR_ASSERT(end >= fi->start);
5407 fi->length = end - fi->start;
5411 proto_item_get_len(const proto_item *pi)
5413 field_info *fi = PITEM_FINFO(pi);
5414 return fi ? fi->length : -1;
5418 proto_tree_create_root(packet_info *pinfo)
5422 /* Initialize the proto_node */
5423 pnode = g_slice_new(proto_tree);
5424 PROTO_NODE_INIT(pnode);
5425 pnode->parent = NULL;
5426 PNODE_FINFO(pnode) = NULL;
5427 pnode->tree_data = g_slice_new(tree_data_t);
5429 /* Make sure we can access pinfo everywhere */
5430 pnode->tree_data->pinfo = pinfo;
5432 /* Don't initialize the tree_data_t. Wait until we know we need it */
5433 pnode->tree_data->interesting_hfids = NULL;
5435 /* Set the default to FALSE so it's easier to
5436 * find errors; if we expect to see the protocol tree
5437 * but for some reason the default 'visible' is not
5438 * changed, then we'll find out very quickly. */
5439 pnode->tree_data->visible = FALSE;
5441 /* Make sure that we fake protocols (if possible) */
5442 pnode->tree_data->fake_protocols = TRUE;
5444 /* Keep track of the number of children */
5445 pnode->tree_data->count = 0;
5447 return (proto_tree *)pnode;
5451 /* "prime" a proto_tree with a single hfid that a dfilter
5452 * is interested in. */
5454 proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
5456 header_field_info *hfinfo;
5458 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
5459 /* this field is referenced by a filter so increase the refcount.
5460 also increase the refcount for the parent, i.e the protocol.
5462 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
5463 /* only increase the refcount if there is a parent.
5464 if this is a protocol and not a field then parent will be -1
5465 and there is no parent to add any refcounting for.
5467 if (hfinfo->parent != -1) {
5468 header_field_info *parent_hfinfo;
5469 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
5471 /* Mark parent as indirectly referenced unless it is already directly
5472 * referenced, i.e. the user has specified the parent in a filter.
5474 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
5475 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
5480 proto_item_add_subtree(proto_item *pi, const gint idx) {
5486 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
5488 fi = PITEM_FINFO(pi);
5490 return (proto_tree *)pi;
5492 fi->tree_type = idx;
5494 return (proto_tree *)pi;
5498 proto_item_get_subtree(proto_item *pi) {
5503 fi = PITEM_FINFO(pi);
5504 if ( (!fi) || (fi->tree_type == -1) )
5506 return (proto_tree *)pi;
5510 proto_item_get_parent(const proto_item *ti) {
5517 proto_item_get_parent_nth(proto_item *ti, int gen) {
5530 proto_tree_get_parent(proto_tree *tree) {
5533 return (proto_item *)tree;
5537 proto_tree_get_parent_tree(proto_tree *tree) {
5541 /* we're the root tree, there's no parent
5542 return ourselves so the caller has at least a tree to attach to */
5546 return (proto_tree *)tree->parent;
5550 proto_tree_get_root(proto_tree *tree) {
5553 while (tree->parent) {
5554 tree = tree->parent;
5560 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
5561 proto_item *item_to_move)
5564 /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
5565 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
5567 /* This function doesn't generate any values. It only reorganizes the prococol tree
5568 * so we can bail out immediately if it isn't visible. */
5569 if (!tree || !PTREE_DATA(tree)->visible)
5572 DISSECTOR_ASSERT(item_to_move->parent == tree);
5573 DISSECTOR_ASSERT(fixed_item->parent == tree);
5575 /*** cut item_to_move out ***/
5577 /* is item_to_move the first? */
5578 if (tree->first_child == item_to_move) {
5579 /* simply change first child to next */
5580 tree->first_child = item_to_move->next;
5582 DISSECTOR_ASSERT(tree->last_child != item_to_move);
5584 proto_item *curr_item;
5585 /* find previous and change it's next */
5586 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
5587 if (curr_item->next == item_to_move) {
5592 DISSECTOR_ASSERT(curr_item);
5594 curr_item->next = item_to_move->next;
5596 /* fix last_child if required */
5597 if (tree->last_child == item_to_move) {
5598 tree->last_child = curr_item;
5602 /*** insert to_move after fixed ***/
5603 item_to_move->next = fixed_item->next;
5604 fixed_item->next = item_to_move;
5605 if (tree->last_child == fixed_item) {
5606 tree->last_child = item_to_move;
5611 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
5619 fi = PTREE_FINFO(tree);
5623 start += tvb_raw_offset(tvb);
5624 DISSECTOR_ASSERT(start >= 0);
5625 DISSECTOR_ASSERT(length >= 0);
5627 fi->appendix_start = start;
5628 fi->appendix_length = length;
5632 proto_register_protocol(const char *name, const char *short_name,
5633 const char *filter_name)
5635 protocol_t *protocol;
5636 const protocol_t *existing_protocol = NULL;
5637 header_field_info *hfinfo;
5639 const char *existing_name;
5643 gboolean found_invalid;
5646 * Make sure there's not already a protocol with any of those
5647 * names. Crash if there is, as that's an error in the code
5648 * or an inappropriate plugin.
5649 * This situation has to be fixed to not register more than one
5650 * protocol with the same name.
5652 * This is done by reducing the number of strcmp (and alike) calls
5653 * as much as possible, as this significally slows down startup time.
5655 * Drawback: As a hash value is used to reduce insert time,
5656 * this might lead to a hash collision.
5657 * However, although we have somewhat over 1000 protocols, we're using
5658 * a 32 bit int so this is very, very unlikely.
5661 key = (gint *)g_malloc (sizeof(gint));
5662 *key = wrs_str_hash(name);
5664 existing_name = (const char *)g_hash_table_lookup(proto_names, key);
5665 if (existing_name != NULL) {
5666 /* g_error will terminate the program */
5667 g_error("Duplicate protocol name \"%s\"!"
5668 " This might be caused by an inappropriate plugin or a development error.", name);
5670 g_hash_table_insert(proto_names, key, (gpointer)name);
5672 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5673 if (existing_protocol != NULL) {
5674 g_error("Duplicate protocol short_name \"%s\"!"
5675 " This might be caused by an inappropriate plugin or a development error.", short_name);
5678 found_invalid = FALSE;
5679 for (i = 0; filter_name[i]; i++) {
5681 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
5682 found_invalid = TRUE;
5685 if (found_invalid) {
5686 g_error("Protocol filter name \"%s\" has one or more invalid characters."
5687 " Allowed are lower characters, digits, '-', '_' and '.'."
5688 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5690 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5691 if (existing_protocol != NULL) {
5692 g_error("Duplicate protocol filter_name \"%s\"!"
5693 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5696 /* Add this protocol to the list of known protocols; the list
5697 is sorted by protocol short name. */
5698 protocol = g_new(protocol_t, 1);
5699 protocol->name = name;
5700 protocol->short_name = short_name;
5701 protocol->filter_name = filter_name;
5702 protocol->fields = g_ptr_array_new();
5703 protocol->is_enabled = TRUE; /* protocol is enabled by default */
5704 protocol->enabled_by_default = TRUE; /* see previous comment */
5705 protocol->can_toggle = TRUE;
5706 protocol->heur_list = NULL;
5707 /* list will be sorted later by name, when all protocols completed registering */
5708 protocols = g_list_prepend(protocols, protocol);
5709 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
5710 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
5712 /* Here we allocate a new header_field_info struct */
5713 hfinfo = g_slice_new(header_field_info);
5714 hfinfo->name = name;
5715 hfinfo->abbrev = filter_name;
5716 hfinfo->type = FT_PROTOCOL;
5717 hfinfo->display = BASE_NONE;
5718 hfinfo->strings = protocol;
5719 hfinfo->bitmask = 0;
5720 hfinfo->ref_type = HF_REF_TYPE_NONE;
5721 hfinfo->blurb = NULL;
5722 hfinfo->parent = -1; /* this field differentiates protos and fields */
5724 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
5725 protocol->proto_id = proto_id;
5730 proto_deregister_protocol(const char *short_name)
5732 protocol_t *protocol;
5733 header_field_info *hfinfo;
5738 proto_id = proto_get_id_by_short_name(short_name);
5739 protocol = find_protocol_by_id(proto_id);
5740 if (protocol == NULL)
5743 key = wrs_str_hash(protocol->name);
5744 g_hash_table_remove(proto_names, &key);
5746 g_hash_table_remove(proto_short_names, (gpointer)short_name);
5747 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
5749 for (i = 0; i < protocol->fields->len; i++) {
5750 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
5751 hfinfo_remove_from_gpa_name_map(hfinfo);
5752 expert_deregister_expertinfo(hfinfo->abbrev);
5753 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
5755 g_ptr_array_free(protocol->fields, TRUE);
5756 protocol->fields = NULL;
5758 /* Remove this protocol from the list of known protocols */
5759 protocols = g_list_remove(protocols, protocol);
5761 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
5762 g_hash_table_steal(gpa_name_map, protocol->filter_name);
5764 g_free(last_field_name);
5765 last_field_name = NULL;
5771 * Routines to use to iterate over the protocols.
5772 * The argument passed to the iterator routines is an opaque cookie to
5773 * their callers; it's the GList pointer for the current element in
5775 * The ID of the protocol is returned, or -1 if there is no protocol.
5778 proto_get_first_protocol(void **cookie)
5780 protocol_t *protocol;
5782 if (protocols == NULL)
5784 *cookie = protocols;
5785 protocol = (protocol_t *)protocols->data;
5786 return protocol->proto_id;
5790 proto_get_data_protocol(void *cookie)
5792 GList *list_item = (GList *)cookie;
5794 protocol_t *protocol = (protocol_t *)list_item->data;
5795 return protocol->proto_id;
5799 proto_get_next_protocol(void **cookie)
5801 GList *list_item = (GList *)*cookie;
5802 protocol_t *protocol;
5804 list_item = g_list_next(list_item);
5805 if (list_item == NULL)
5807 *cookie = list_item;
5808 protocol = (protocol_t *)list_item->data;
5809 return protocol->proto_id;
5812 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
5813 assume that the cookie stored by
5814 proto_get_(first|next)_protocol_field() will never have a
5815 value of NULL. So, to preserve this semantic, the cookie value
5816 below is adjusted so that the cookie value stored is 1 + the
5817 current (zero-based) array index.
5820 proto_get_first_protocol_field(const int proto_id, void **cookie)
5822 protocol_t *protocol = find_protocol_by_id(proto_id);
5824 if ((protocol == NULL) || (protocol->fields->len == 0))
5827 *cookie = GUINT_TO_POINTER(0 + 1);
5828 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
5832 proto_get_next_protocol_field(const int proto_id, void **cookie)
5834 protocol_t *protocol = find_protocol_by_id(proto_id);
5835 guint i = GPOINTER_TO_UINT(*cookie) - 1;
5839 if (i >= protocol->fields->len)
5842 *cookie = GUINT_TO_POINTER(i + 1);
5843 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
5847 find_protocol_by_id(const int proto_id)
5849 header_field_info *hfinfo;
5854 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
5855 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
5856 return (protocol_t *)hfinfo->strings;
5860 proto_get_id(const protocol_t *protocol)
5862 return protocol->proto_id;
5866 proto_name_already_registered(const gchar *name)
5870 DISSECTOR_ASSERT_HINT(name, "No name present");
5872 key = wrs_str_hash(name);
5873 if (g_hash_table_lookup(proto_names, &key) != NULL)
5879 proto_get_id_by_filter_name(const gchar *filter_name)
5881 const protocol_t *protocol = NULL;
5883 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
5885 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5887 if (protocol == NULL)
5889 return protocol->proto_id;
5893 proto_get_id_by_short_name(const gchar *short_name)
5895 const protocol_t *protocol = NULL;
5897 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
5899 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5901 if (protocol == NULL)
5903 return protocol->proto_id;
5907 proto_get_protocol_name(const int proto_id)
5909 protocol_t *protocol;
5911 protocol = find_protocol_by_id(proto_id);
5913 if (protocol == NULL)
5915 return protocol->name;
5919 proto_get_protocol_short_name(const protocol_t *protocol)
5921 if (protocol == NULL)
5923 return protocol->short_name;
5927 proto_get_protocol_long_name(const protocol_t *protocol)
5929 if (protocol == NULL)
5931 return protocol->name;
5935 proto_get_protocol_filter_name(const int proto_id)
5937 protocol_t *protocol;
5939 protocol = find_protocol_by_id(proto_id);
5940 if (protocol == NULL)
5942 return protocol->filter_name;
5945 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
5947 heur_dtbl_entry_t* heuristic_dissector;
5949 if (protocol == NULL)
5952 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
5953 if (heuristic_dissector != NULL)
5955 protocol->heur_list = g_list_append (protocol->heur_list, heuristic_dissector);
5959 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
5961 if (protocol == NULL)
5964 g_list_foreach(protocol->heur_list, func, user_data);
5968 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
5969 gboolean *is_tcp, gboolean *is_udp,
5970 gboolean *is_sctp, gboolean *is_ssl,
5972 gboolean *is_lte_rlc)
5974 wmem_list_frame_t *protos = wmem_list_head(layers);
5976 const char *proto_name;
5978 /* Walk the list of a available protocols in the packet and
5979 find "major" ones. */
5980 /* It might make more sense to assemble and return a bitfield. */
5981 while (protos != NULL)
5983 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
5984 proto_name = proto_get_protocol_filter_name(proto_id);
5986 if (is_ip && ((!strcmp(proto_name, "ip")) ||
5987 (!strcmp(proto_name, "ipv6")))) {
5989 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
5991 } else if (is_udp && !strcmp(proto_name, "udp")) {
5993 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
5995 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
5997 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
5999 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
6003 protos = wmem_list_frame_next(protos);
6008 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
6010 wmem_list_frame_t *protos = wmem_list_head(layers);
6014 /* Walk the list of a available protocols in the packet and
6015 find "major" ones. */
6016 /* It might make more sense to assemble and return a bitfield. */
6017 while (protos != NULL)
6019 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6020 name = proto_get_protocol_filter_name(proto_id);
6022 if (!strcmp(name, proto_name))
6027 protos = wmem_list_frame_next(protos);
6035 proto_is_protocol_enabled(const protocol_t *protocol)
6037 return protocol->is_enabled;
6041 proto_can_toggle_protocol(const int proto_id)
6043 protocol_t *protocol;
6045 protocol = find_protocol_by_id(proto_id);
6046 return protocol->can_toggle;
6050 proto_disable_by_default(const int proto_id)
6052 protocol_t *protocol;
6054 protocol = find_protocol_by_id(proto_id);
6055 DISSECTOR_ASSERT(protocol->can_toggle);
6056 protocol->is_enabled = FALSE;
6057 protocol->enabled_by_default = FALSE;
6061 proto_set_decoding(const int proto_id, const gboolean enabled)
6063 protocol_t *protocol;
6065 protocol = find_protocol_by_id(proto_id);
6066 DISSECTOR_ASSERT(protocol->can_toggle);
6067 protocol->is_enabled = enabled;
6071 proto_enable_all(void)
6073 protocol_t *protocol;
6074 GList *list_item = protocols;
6076 if (protocols == NULL)
6080 protocol = (protocol_t *)list_item->data;
6081 if (protocol->can_toggle && protocol->enabled_by_default)
6082 protocol->is_enabled = TRUE;
6083 list_item = g_list_next(list_item);
6088 proto_set_cant_toggle(const int proto_id)
6090 protocol_t *protocol;
6092 protocol = find_protocol_by_id(proto_id);
6093 protocol->can_toggle = FALSE;
6097 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
6099 if (proto != NULL) {
6100 g_ptr_array_add(proto->fields, hfi);
6103 return proto_register_field_init(hfi, parent);
6106 /* for use with static arrays only, since we don't allocate our own copies
6107 of the header_field_info struct contained within the hf_register_info struct */
6109 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
6111 hf_register_info *ptr = hf;
6115 proto = find_protocol_by_id(parent);
6116 for (i = 0; i < num_records; i++, ptr++) {
6118 * Make sure we haven't registered this yet.
6119 * Most fields have variables associated with them
6120 * that are initialized to -1; some have array elements,
6121 * or possibly uninitialized variables, so we also allow
6122 * 0 (which is unlikely to be the field ID we get back
6123 * from "proto_register_field_init()").
6125 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
6127 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
6128 ptr->hfinfo.abbrev);
6132 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
6137 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
6142 proto = find_protocol_by_id(parent);
6143 for (i = 0; i < num_records; i++) {
6145 * Make sure we haven't registered this yet.
6147 if (hfi[i].id != -1) {
6149 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6154 proto_register_field_common(proto, &hfi[i], parent);
6159 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
6164 proto = find_protocol_by_id(parent);
6165 for (i = 0; i < num_records; i++) {
6167 * Make sure we haven't registered this yet.
6169 if (hfi[i]->id != -1) {
6171 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6176 proto_register_field_common(proto, hfi[i], parent);
6180 /* deregister already registered fields */
6182 proto_deregister_field (const int parent, gint hf_id)
6184 header_field_info *hfi;
6188 g_free(last_field_name);
6189 last_field_name = NULL;
6191 if (hf_id == -1 || hf_id == 0)
6194 proto = find_protocol_by_id (parent);
6195 if (!proto || proto->fields->len == 0) {
6199 for (i = 0; i < proto->fields->len; i++) {
6200 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
6201 if (hfi->id == hf_id) {
6202 /* Found the hf_id in this protocol */
6203 g_hash_table_steal(gpa_name_map, hfi->abbrev);
6204 g_ptr_array_remove_index_fast(proto->fields, i);
6205 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
6212 proto_add_deregistered_data (void *data)
6214 g_ptr_array_add(deregistered_data, data);
6218 free_deregistered_field (gpointer data, gpointer user_data _U_)
6220 header_field_info *hfi = (header_field_info *) data;
6221 gint hf_id = hfi->id;
6223 g_free((char *)hfi->name);
6224 g_free((char *)hfi->abbrev);
6225 g_free((char *)hfi->blurb);
6228 switch (hfi->type) {
6230 /* This is just an integer represented as a pointer */
6233 protocol_t *protocol = (protocol_t *)hfi->strings;
6234 g_free((gchar *)protocol->short_name);
6238 true_false_string *tf = (true_false_string *)hfi->strings;
6239 g_free ((gchar *)tf->true_string);
6240 g_free ((gchar *)tf->false_string);
6245 val64_string *vs64 = (val64_string *)hfi->strings;
6246 while (vs64->strptr) {
6247 g_free((gchar *)vs64->strptr);
6253 /* Other Integer types */
6254 value_string *vs = (value_string *)hfi->strings;
6255 while (vs->strptr) {
6256 g_free((gchar *)vs->strptr);
6262 if (hfi->type != FT_FRAMENUM) {
6263 g_free((void *)hfi->strings);
6267 if (hfi->parent == -1)
6268 g_slice_free(header_field_info, hfi);
6270 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
6274 free_deregistered_data (gpointer data, gpointer user_data _U_)
6279 /* free deregistered fields and data */
6281 proto_free_deregistered_fields (void)
6283 expert_free_deregistered_expertinfos();
6285 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
6286 g_ptr_array_free(deregistered_fields, TRUE);
6287 deregistered_fields = g_ptr_array_new();
6289 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
6290 g_ptr_array_free(deregistered_data, TRUE);
6291 deregistered_data = g_ptr_array_new();
6294 /* chars allowed in field abbrev */
6296 const guint8 fld_abbrev_chars[256] = {
6297 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
6298 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
6299 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
6300 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
6301 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
6302 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
6303 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
6304 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
6305 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
6306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
6307 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
6308 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
6309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
6310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
6311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
6312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
6315 static const value_string hf_display[] = {
6316 { BASE_NONE, "BASE_NONE" },
6317 { BASE_DEC, "BASE_DEC" },
6318 { BASE_HEX, "BASE_HEX" },
6319 { BASE_OCT, "BASE_OCT" },
6320 { BASE_DEC_HEX, "BASE_DEC_HEX" },
6321 { BASE_HEX_DEC, "BASE_HEX_DEC" },
6322 { BASE_CUSTOM, "BASE_CUSTOM" },
6323 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
6324 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
6325 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
6326 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
6327 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
6328 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
6329 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
6330 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
6331 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
6332 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
6333 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
6334 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
6335 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
6336 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
6337 /* Alias: BASE_NONE { BASE_FLOAT, "BASE_FLOAT" }, */
6338 /* Alias: BASE_NONE { STR_ASCII, "STR_ASCII" }, */
6339 { STR_UNICODE, "STR_UNICODE" },
6340 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
6341 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
6342 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
6343 { BASE_PT_UDP, "BASE_PT_UDP" },
6344 { BASE_PT_TCP, "BASE_PT_TCP" },
6345 { BASE_PT_DCCP, "BASE_PT_DCCP" },
6346 { BASE_PT_SCTP, "BASE_PT_SCTP" },
6349 const char* proto_field_display_to_string(int field_display)
6351 return val_to_str_const(field_display, hf_display, "Unknown");
6354 static inline port_type
6355 display_to_port_type(field_display_e e)
6372 /* temporary function containing assert part for easier profiling */
6374 tmp_fld_check_assert(header_field_info *hfinfo)
6378 /* The field must have a name (with length > 0) */
6379 if (!hfinfo->name || !hfinfo->name[0]) {
6381 /* Try to identify the field */
6382 g_error("Field (abbrev='%s') does not have a name\n",
6386 g_error("Field does not have a name (nor an abbreviation)\n");
6389 /* fields with an empty string for an abbreviation aren't filterable */
6390 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
6391 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
6393 /* These types of fields are allowed to have value_strings,
6394 * true_false_strings or a protocol_t struct
6396 if (hfinfo->strings != NULL && !(
6397 (hfinfo->type == FT_UINT8) ||
6398 (hfinfo->type == FT_UINT16) ||
6399 (hfinfo->type == FT_UINT24) ||
6400 (hfinfo->type == FT_UINT32) ||
6401 (hfinfo->type == FT_UINT40) ||
6402 (hfinfo->type == FT_UINT48) ||
6403 (hfinfo->type == FT_UINT56) ||
6404 (hfinfo->type == FT_UINT64) ||
6405 (hfinfo->type == FT_INT8) ||
6406 (hfinfo->type == FT_INT16) ||
6407 (hfinfo->type == FT_INT24) ||
6408 (hfinfo->type == FT_INT32) ||
6409 (hfinfo->type == FT_INT40) ||
6410 (hfinfo->type == FT_INT48) ||
6411 (hfinfo->type == FT_INT56) ||
6412 (hfinfo->type == FT_INT64) ||
6413 (hfinfo->type == FT_BOOLEAN) ||
6414 (hfinfo->type == FT_PROTOCOL) ||
6415 (hfinfo->type == FT_FRAMENUM) ))
6416 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
6417 " (which is not allowed to have strings)\n",
6418 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
6420 /* TODO: This check may slow down startup, and output quite a few warnings.
6421 It would be good to be able to enable this (and possibly other checks?)
6422 in non-release builds. */
6424 /* Check for duplicate value_string values.
6425 There are lots that have the same value *and* string, so for now only
6426 report those that have same value but different string. */
6427 if ((hfinfo->strings != NULL) &&
6428 !(hfinfo->display & BASE_RANGE_STRING) &&
6429 !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
6431 (hfinfo->type == FT_UINT8) ||
6432 (hfinfo->type == FT_UINT16) ||
6433 (hfinfo->type == FT_UINT24) ||
6434 (hfinfo->type == FT_UINT32) ||
6435 (hfinfo->type == FT_INT8) ||
6436 (hfinfo->type == FT_INT16) ||
6437 (hfinfo->type == FT_INT24) ||
6438 (hfinfo->type == FT_INT32) ||
6439 (hfinfo->type == FT_FRAMENUM) )) {
6442 const value_string *start_values;
6443 const value_string *current;
6445 if (hfinfo->display & BASE_EXT_STRING)
6446 start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
6448 start_values = (const value_string*)hfinfo->strings;
6449 current = start_values;
6451 for (n=0; current; n++, current++) {
6452 /* Drop out if we reached the end. */
6453 if ((current->value == 0) && (current->strptr == NULL)) {
6457 /* Check value against all previous */
6458 for (m=0; m < n; m++) {
6459 /* There are lots of duplicates with the same string,
6460 so only report if different... */
6461 if ((start_values[m].value == current->value) &&
6462 (strcmp(start_values[m].strptr, current->strptr) != 0)) {
6463 g_warning("Field '%s' (%s) has a conflicting entry in its"
6464 " value_string: %u is at indices %u (%s) and %u (%s))\n",
6465 hfinfo->name, hfinfo->abbrev,
6466 current->value, m, start_values[m].strptr, n, current->strptr);
6474 switch (hfinfo->type) {
6484 /* Hexadecimal and octal are, in printf() and everywhere
6485 * else, unsigned so don't allow dissectors to register a
6486 * signed field to be displayed unsigned. (Else how would
6487 * we display negative values?)
6489 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6494 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6495 g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
6496 hfinfo->name, hfinfo->abbrev,
6497 ftype_name(hfinfo->type), tmp_str);
6498 wmem_free(NULL, tmp_str);
6509 if (IS_BASE_PORT(hfinfo->display)) {
6510 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6511 if (hfinfo->type != FT_UINT16) {
6512 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
6513 hfinfo->name, hfinfo->abbrev,
6514 tmp_str, ftype_name(hfinfo->type));
6516 if (hfinfo->strings != NULL) {
6517 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
6518 hfinfo->name, hfinfo->abbrev,
6519 ftype_name(hfinfo->type), tmp_str);
6521 if (hfinfo->bitmask != 0) {
6522 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
6523 hfinfo->name, hfinfo->abbrev,
6524 ftype_name(hfinfo->type), tmp_str);
6526 wmem_free(NULL, tmp_str);
6530 /* Require integral types (other than frame number,
6531 * which is always displayed in decimal) to have a
6534 * If the display value is BASE_NONE and there is a
6535 * strings conversion then the dissector writer is
6536 * telling us that the field's numerical value is
6537 * meaningless; we'll avoid showing the value to the
6540 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6546 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6549 if (hfinfo->strings == NULL)
6550 g_error("Field '%s' (%s) is an integral value (%s)"
6551 " but is being displayed as BASE_NONE but"
6552 " without a strings conversion",
6553 hfinfo->name, hfinfo->abbrev,
6554 ftype_name(hfinfo->type));
6557 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6558 g_error("Field '%s' (%s) is an integral value (%s)"
6559 " but is being displayed as %s\n",
6560 hfinfo->name, hfinfo->abbrev,
6561 ftype_name(hfinfo->type), tmp_str);
6562 wmem_free(NULL, tmp_str);
6566 /* Require bytes to have a "display type" that could
6567 * add a character between displayed bytes.
6569 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6577 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6578 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",
6579 hfinfo->name, hfinfo->abbrev, tmp_str);
6580 wmem_free(NULL, tmp_str);
6582 if (hfinfo->bitmask != 0)
6583 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6584 hfinfo->name, hfinfo->abbrev,
6585 ftype_name(hfinfo->type));
6586 if (hfinfo->strings != NULL)
6587 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6588 hfinfo->name, hfinfo->abbrev,
6589 ftype_name(hfinfo->type));
6594 if (hfinfo->display != BASE_NONE) {
6595 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6596 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6597 hfinfo->name, hfinfo->abbrev,
6598 ftype_name(hfinfo->type), tmp_str);
6599 wmem_free(NULL, tmp_str);
6601 if (hfinfo->bitmask != 0)
6602 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6603 hfinfo->name, hfinfo->abbrev,
6604 ftype_name(hfinfo->type));
6610 case FT_ABSOLUTE_TIME:
6611 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
6612 hfinfo->display == ABSOLUTE_TIME_UTC ||
6613 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
6614 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6615 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
6616 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
6617 wmem_free(NULL, tmp_str);
6619 if (hfinfo->bitmask != 0)
6620 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6621 hfinfo->name, hfinfo->abbrev,
6622 ftype_name(hfinfo->type));
6627 case FT_UINT_STRING:
6629 switch (hfinfo->display) {
6635 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6636 g_error("Field '%s' (%s) is an string value (%s)"
6637 " but is being displayed as %s\n",
6638 hfinfo->name, hfinfo->abbrev,
6639 ftype_name(hfinfo->type), tmp_str);
6640 wmem_free(NULL, tmp_str);
6643 if (hfinfo->bitmask != 0)
6644 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6645 hfinfo->name, hfinfo->abbrev,
6646 ftype_name(hfinfo->type));
6647 if (hfinfo->strings != NULL)
6648 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6649 hfinfo->name, hfinfo->abbrev,
6650 ftype_name(hfinfo->type));
6654 switch (hfinfo->display) {
6660 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6661 g_error("Field '%s' (%s) is an IPv4 value (%s)"
6662 " but is being displayed as %s\n",
6663 hfinfo->name, hfinfo->abbrev,
6664 ftype_name(hfinfo->type), tmp_str);
6665 wmem_free(NULL, tmp_str);
6670 if (hfinfo->display != BASE_NONE) {
6671 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6672 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6673 hfinfo->name, hfinfo->abbrev,
6674 ftype_name(hfinfo->type),
6676 wmem_free(NULL, tmp_str);
6678 if (hfinfo->bitmask != 0)
6679 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6680 hfinfo->name, hfinfo->abbrev,
6681 ftype_name(hfinfo->type));
6682 if (hfinfo->strings != NULL)
6683 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6684 hfinfo->name, hfinfo->abbrev,
6685 ftype_name(hfinfo->type));
6690 #ifdef ENABLE_CHECK_FILTER
6692 _ftype_common(enum ftenum type)
6715 case FT_UINT_STRING:
6728 case FT_ABSOLUTE_TIME:
6729 case FT_RELATIVE_TIME:
6730 return FT_ABSOLUTE_TIME;
6739 register_type_length_mismatch(void)
6741 static ei_register_info ei[] = {
6742 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
6743 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
6746 expert_module_t* expert_type_length_mismatch;
6748 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
6750 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
6751 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
6753 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
6754 disabling them makes no sense. */
6755 proto_set_cant_toggle(proto_type_length_mismatch);
6759 register_number_string_decoding_error(void)
6761 static ei_register_info ei[] = {
6762 { &ei_number_string_decoding_failed_error,
6763 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
6764 "Failed to decode number from string", EXPFILL
6767 { &ei_number_string_decoding_erange_error,
6768 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
6769 "Decoded number from string is out of valid range", EXPFILL
6774 expert_module_t* expert_number_string_decoding_error;
6776 proto_number_string_decoding_error =
6777 proto_register_protocol("Number-String Decoding Error",
6778 "Number-string decoding error",
6779 "_ws.number_string.decoding_error");
6781 expert_number_string_decoding_error =
6782 expert_register_protocol(proto_number_string_decoding_error);
6783 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
6785 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
6786 disabling them makes no sense. */
6787 proto_set_cant_toggle(proto_number_string_decoding_error);
6790 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (178000+PRE_ALLOC_EXPERT_FIELDS_MEM)
6792 proto_register_field_init(header_field_info *hfinfo, const int parent)
6795 tmp_fld_check_assert(hfinfo);
6797 hfinfo->parent = parent;
6798 hfinfo->same_name_next = NULL;
6799 hfinfo->same_name_prev_id = -1;
6801 /* if we always add and never delete, then id == len - 1 is correct */
6802 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
6803 if (!gpa_hfinfo.hfi) {
6804 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
6805 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
6807 gpa_hfinfo.allocated_len += 1000;
6808 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
6809 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
6810 /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
6813 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
6815 hfinfo->id = gpa_hfinfo.len - 1;
6817 /* if we have real names, enter this field in the name tree */
6818 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
6820 header_field_info *same_name_next_hfinfo;
6823 /* Check that the filter name (abbreviation) is legal;
6824 * it must contain only alphanumerics, '-', "_", and ".". */
6825 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
6827 if (g_ascii_isprint(c))
6828 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
6830 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
6831 DISSECTOR_ASSERT_NOT_REACHED();
6834 /* We allow multiple hfinfo's to be registered under the same
6835 * abbreviation. This was done for X.25, as, depending
6836 * on whether it's modulo-8 or modulo-128 operation,
6837 * some bitfield fields may be in different bits of
6838 * a byte, and we want to be able to refer to that field
6839 * with one name regardless of whether the packets
6840 * are modulo-8 or modulo-128 packets. */
6842 same_name_hfinfo = NULL;
6844 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
6845 /* GLIB 2.x - if it is already present
6846 * the previous hfinfo with the same name is saved
6847 * to same_name_hfinfo by value destroy callback */
6848 if (same_name_hfinfo) {
6849 /* There's already a field with this name.
6850 * Put the current field *before* that field
6851 * in the list of fields with this name, Thus,
6852 * we end up with an effectively
6853 * doubly-linked-list of same-named hfinfo's,
6854 * with the head of the list (stored in the
6855 * hash) being the last seen hfinfo.
6857 same_name_next_hfinfo =
6858 same_name_hfinfo->same_name_next;
6860 hfinfo->same_name_next = same_name_next_hfinfo;
6861 if (same_name_next_hfinfo)
6862 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
6864 same_name_hfinfo->same_name_next = hfinfo;
6865 hfinfo->same_name_prev_id = same_name_hfinfo->id;
6866 #ifdef ENABLE_CHECK_FILTER
6867 while (same_name_hfinfo) {
6868 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
6869 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));
6870 same_name_hfinfo = same_name_hfinfo->same_name_next;
6880 proto_register_subtree_array(gint *const *indices, const int num_indices)
6883 gint *const *ptr = indices;
6886 * If we've already allocated the array of tree types, expand
6887 * it; this lets plugins such as mate add tree types after
6888 * the initial startup. (If we haven't already allocated it,
6889 * we don't allocate it; on the first pass, we just assign
6890 * ett values and keep track of how many we've assigned, and
6891 * when we're finished registering all dissectors we allocate
6892 * the array, so that we do only one allocation rather than
6893 * wasting CPU time and memory by growing the array for each
6894 * dissector that registers ett values.)
6896 if (tree_is_expanded != NULL) {
6897 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
6899 /* set new items to 0 */
6900 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
6901 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
6902 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
6906 * Assign "num_indices" subtree numbers starting at "num_tree_types",
6907 * returning the indices through the pointers in the array whose
6908 * first element is pointed to by "indices", and update
6909 * "num_tree_types" appropriately.
6911 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
6913 /* g_error will terminate the program */
6914 g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
6915 " This is a development error:"
6916 " Either the subtree item type has already been assigned or"
6917 " was not initialized to -1.");
6919 **ptr = num_tree_types;
6924 label_concat(char *label_str, gsize pos, const char *str)
6926 if (pos < ITEM_LABEL_LENGTH)
6927 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
6933 label_mark_truncated(char *label_str, gsize name_pos)
6935 static const char trunc_str[] = " [truncated]";
6936 const size_t trunc_len = sizeof(trunc_str)-1;
6939 /* ..... field_name: dataaaaaaaaaaaaa
6943 * ..... field_name [truncated]: dataaaaaaaaaaaaa
6945 * name_pos==0 means that we have only data or only a field_name
6948 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
6949 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
6950 memcpy(label_str + name_pos, trunc_str, trunc_len);
6952 /* in general, label_str is UTF-8
6953 we can truncate it only at the beginning of a new character
6954 we go backwards from the byte right after our buffer and
6955 find the next starting byte of a UTF-8 character, this is
6957 there's no need to use g_utf8_find_prev_char(), the search
6958 will always succeed since we copied trunc_str into the
6960 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH]);
6963 } else if (name_pos < ITEM_LABEL_LENGTH)
6964 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
6968 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
6972 /* "%s: %s", hfinfo->name, text */
6973 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
6974 pos = label_concat(label_str, pos, ": ");
6975 pos = label_concat(label_str, pos, text ? text : "(null)");
6977 if (pos >= ITEM_LABEL_LENGTH) {
6978 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
6979 label_mark_truncated(label_str, name_pos);
6986 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
6990 /* "%s: %s (%s)", hfinfo->name, text, descr */
6991 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
6992 pos = label_concat(label_str, pos, ": ");
6993 pos = label_concat(label_str, pos, text ? text : "(null)");
6994 pos = label_concat(label_str, pos, " (");
6995 pos = label_concat(label_str, pos, descr ? descr : "(null)");
6996 pos = label_concat(label_str, pos, ")");
6998 if (pos >= ITEM_LABEL_LENGTH) {
6999 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7000 label_mark_truncated(label_str, name_pos);
7007 proto_item_fill_label(field_info *fi, gchar *label_str)
7009 header_field_info *hfinfo;
7013 ipv4_addr_and_mask *ipv4;
7015 guint32 n_addr; /* network-order IPv4 address */
7024 /* XXX: Check validity of hfinfo->type */
7028 hfinfo = fi->hfinfo;
7030 switch (hfinfo->type) {
7033 g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
7037 fill_label_boolean(fi, label_str);
7042 bytes = (guint8 *)fvalue_get(&fi->value);
7045 switch(hfinfo->display)
7048 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
7051 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
7054 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
7057 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7061 if (prefs.display_byte_fields_with_spaces)
7063 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7067 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
7071 label_fill(label_str, 0, hfinfo, str);
7072 wmem_free(NULL, str);
7074 if (hfinfo->display & BASE_ALLOW_ZERO) {
7075 label_fill(label_str, 0, hfinfo, "<none>");
7077 label_fill(label_str, 0, hfinfo, "<MISSING>");
7082 /* Four types of integers to take care of:
7083 * Bitfield, with val_string
7084 * Bitfield, w/o val_string
7085 * Non-bitfield, with val_string
7086 * Non-bitfield, w/o val_string
7092 if (hfinfo->bitmask) {
7093 fill_label_bitfield(fi, label_str, FALSE);
7095 fill_label_number(fi, label_str, FALSE);
7100 fill_label_number(fi, label_str, FALSE);
7107 if (hfinfo->bitmask) {
7108 fill_label_bitfield64(fi, label_str, FALSE);
7110 fill_label_number64(fi, label_str, FALSE);
7118 if (hfinfo->bitmask) {
7119 fill_label_bitfield(fi, label_str, TRUE);
7121 fill_label_number(fi, label_str, TRUE);
7129 if (hfinfo->bitmask) {
7130 fill_label_bitfield64(fi, label_str, TRUE);
7132 fill_label_number64(fi, label_str, TRUE);
7137 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7138 "%s: %." G_STRINGIFY(FLT_DIG) "g",
7139 hfinfo->name, fvalue_get_floating(&fi->value));
7143 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7144 "%s: %." G_STRINGIFY(DBL_DIG) "g",
7145 hfinfo->name, fvalue_get_floating(&fi->value));
7148 case FT_ABSOLUTE_TIME:
7149 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
7150 label_fill(label_str, 0, hfinfo, tmp);
7151 wmem_free(NULL, tmp);
7154 case FT_RELATIVE_TIME:
7155 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
7156 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7157 "%s: %s seconds", hfinfo->name, tmp);
7158 wmem_free(NULL, tmp);
7162 integer = fvalue_get_uinteger(&fi->value);
7163 tmp = get_ipxnet_name(NULL, integer);
7164 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7165 "%s: %s (0x%08X)", hfinfo->name,
7167 wmem_free(NULL, tmp);
7171 addr.type = AT_AX25;
7172 addr.len = AX25_ADDR_LEN;
7173 addr.data = (guint8 *)fvalue_get(&fi->value);
7175 addr_str = (char*)address_to_str(NULL, &addr);
7176 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7177 "%s: %s", hfinfo->name, addr_str);
7178 wmem_free(NULL, addr_str);
7182 addr.type = vines_address_type;
7183 addr.len = VINES_ADDR_LEN;
7184 addr.data = (guint8 *)fvalue_get(&fi->value);
7186 addr_str = (char*)address_to_str(NULL, &addr);
7187 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7188 "%s: %s", hfinfo->name, addr_str);
7189 wmem_free(NULL, addr_str);
7193 bytes = (guint8 *)fvalue_get(&fi->value);
7195 addr.type = AT_ETHER;
7199 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7200 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7201 "%s: %s", hfinfo->name, addr_str);
7202 wmem_free(NULL, addr_str);
7206 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&fi->value);
7207 n_addr = ipv4_get_net_order_addr(ipv4);
7209 addr.type = AT_IPv4;
7211 addr.data = &n_addr;
7213 if (hfinfo->display == BASE_NETMASK)
7215 addr_str = (char*)address_to_str(NULL, &addr);
7219 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7221 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7222 "%s: %s", hfinfo->name, addr_str);
7223 wmem_free(NULL, addr_str);
7227 bytes = (guint8 *)fvalue_get(&fi->value);
7229 addr.type = AT_IPv6;
7233 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7234 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7235 "%s: %s", hfinfo->name, addr_str);
7236 wmem_free(NULL, addr_str);
7240 addr.type = AT_FCWWN;
7241 addr.len = FCWWN_ADDR_LEN;
7242 addr.data = (guint8 *)fvalue_get(&fi->value);
7244 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7245 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7246 "%s: %s", hfinfo->name, addr_str);
7247 wmem_free(NULL, addr_str);
7251 guid = (e_guid_t *)fvalue_get(&fi->value);
7252 tmp = guid_to_str(NULL, guid);
7253 label_fill(label_str, 0, hfinfo, tmp);
7254 wmem_free(NULL, tmp);
7258 bytes = (guint8 *)fvalue_get(&fi->value);
7259 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7260 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7262 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7263 wmem_free(NULL, name);
7265 label_fill(label_str, 0, hfinfo, tmp);
7267 wmem_free(NULL, tmp);
7271 bytes = (guint8 *)fvalue_get(&fi->value);
7272 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7273 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7275 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7276 wmem_free(NULL, name);
7278 label_fill(label_str, 0, hfinfo, tmp);
7280 wmem_free(NULL, tmp);
7284 bytes = (guint8 *)fvalue_get(&fi->value);
7285 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
7286 label_fill(label_str, 0, hfinfo, tmp);
7287 wmem_free(NULL, tmp);
7291 integer64 = fvalue_get_uinteger64(&fi->value);
7292 addr_str = eui64_to_str(NULL, integer64);
7293 tmp = (char*)eui64_to_display(NULL, integer64);
7294 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
7295 wmem_free(NULL, tmp);
7296 wmem_free(NULL, addr_str);
7300 case FT_UINT_STRING:
7302 bytes = (guint8 *)fvalue_get(&fi->value);
7303 label_fill(label_str, 0, hfinfo, hfinfo_format_text(hfinfo, bytes));
7306 case FT_IEEE_11073_SFLOAT:
7307 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7308 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7311 wmem_free(NULL, tmp);
7313 case FT_IEEE_11073_FLOAT:
7314 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7315 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7318 wmem_free(NULL, tmp);
7322 g_error("hfinfo->type %d (%s) not handled\n",
7323 hfinfo->type, ftype_name(hfinfo->type));
7324 DISSECTOR_ASSERT_NOT_REACHED();
7330 fill_label_boolean(field_info *fi, gchar *label_str)
7332 char *p = label_str;
7333 int bitfield_byte_length = 0, bitwidth;
7334 guint64 unshifted_value;
7337 header_field_info *hfinfo = fi->hfinfo;
7338 const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
7340 if (hfinfo->strings) {
7341 tfstring = (const struct true_false_string*) hfinfo->strings;
7344 value = fvalue_get_uinteger64(&fi->value);
7345 if (hfinfo->bitmask) {
7346 /* Figure out the bit width */
7347 bitwidth = hfinfo_container_bitwidth(hfinfo);
7350 unshifted_value = value;
7351 unshifted_value <<= hfinfo_bitshift(hfinfo);
7353 /* Create the bitfield first */
7354 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7355 bitfield_byte_length = (int) (p - label_str);
7358 /* Fill in the textual info */
7359 label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
7363 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
7365 if (hfinfo->display & BASE_RANGE_STRING)
7366 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
7368 if (hfinfo->display & BASE_EXT_STRING)
7369 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
7371 if (hfinfo->display & BASE_VAL64_STRING)
7372 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7374 return try_val_to_str(value, (const value_string *) hfinfo->strings);
7378 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
7380 if (hfinfo->display & BASE_VAL64_STRING)
7381 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7383 /* If this is reached somebody registered a 64-bit field with a 32-bit
7384 * value-string, which isn't right. */
7385 DISSECTOR_ASSERT_NOT_REACHED();
7387 /* This is necessary to squelch MSVC errors; is there
7388 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
7394 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
7396 const char *str = hf_try_val_to_str(value, hfinfo);
7398 return (str) ? str : unknown_str;
7402 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
7404 const char *str = hf_try_val64_to_str(value, hfinfo);
7406 return (str) ? str : unknown_str;
7409 /* Fills data for bitfield ints with val_strings */
7411 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
7414 int bitfield_byte_length, bitwidth;
7415 guint32 unshifted_value;
7421 header_field_info *hfinfo = fi->hfinfo;
7423 /* Figure out the bit width */
7424 bitwidth = hfinfo_container_bitwidth(hfinfo);
7428 value = fvalue_get_sinteger(&fi->value);
7430 value = fvalue_get_uinteger(&fi->value);
7432 unshifted_value = value;
7433 if (hfinfo->bitmask) {
7434 unshifted_value <<= hfinfo_bitshift(hfinfo);
7437 /* Create the bitfield first */
7438 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7439 bitfield_byte_length = (int) (p - label_str);
7441 /* Fill in the textual info using stored (shifted) value */
7442 if (hfinfo->display == BASE_CUSTOM) {
7443 gchar tmp[ITEM_LABEL_LENGTH];
7444 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7446 DISSECTOR_ASSERT(fmtfunc);
7447 fmtfunc(tmp, value);
7448 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7450 else if (hfinfo->strings) {
7451 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7453 out = hfinfo_number_vals_format(hfinfo, buf, value);
7454 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7455 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7457 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7460 out = hfinfo_number_value_format(hfinfo, buf, value);
7462 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7467 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
7470 int bitfield_byte_length, bitwidth;
7471 guint64 unshifted_value;
7477 header_field_info *hfinfo = fi->hfinfo;
7479 /* Figure out the bit width */
7480 bitwidth = hfinfo_container_bitwidth(hfinfo);
7484 value = fvalue_get_sinteger64(&fi->value);
7486 value = fvalue_get_uinteger64(&fi->value);
7488 unshifted_value = value;
7489 if (hfinfo->bitmask) {
7490 unshifted_value <<= hfinfo_bitshift(hfinfo);
7493 /* Create the bitfield first */
7494 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7495 bitfield_byte_length = (int) (p - label_str);
7497 /* Fill in the textual info using stored (shifted) value */
7498 if (hfinfo->display == BASE_CUSTOM) {
7499 gchar tmp[ITEM_LABEL_LENGTH];
7500 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7502 DISSECTOR_ASSERT(fmtfunc64);
7503 fmtfunc64(tmp, value);
7504 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7506 else if (hfinfo->strings) {
7507 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7509 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7510 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7511 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7513 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7516 out = hfinfo_number_value_format64(hfinfo, buf, value);
7518 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7523 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
7525 header_field_info *hfinfo = fi->hfinfo;
7532 value = fvalue_get_sinteger(&fi->value);
7534 value = fvalue_get_uinteger(&fi->value);
7536 /* Fill in the textual info */
7537 if (hfinfo->display == BASE_CUSTOM) {
7538 gchar tmp[ITEM_LABEL_LENGTH];
7539 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7541 DISSECTOR_ASSERT(fmtfunc);
7542 fmtfunc(tmp, value);
7543 label_fill(label_str, 0, hfinfo, tmp);
7545 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) { /* Add fill_label_framenum? */
7546 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7548 out = hfinfo_number_vals_format(hfinfo, buf, value);
7549 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7550 label_fill(label_str, 0, hfinfo, val_str);
7552 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7554 else if (IS_BASE_PORT(hfinfo->display)) {
7555 gchar tmp[ITEM_LABEL_LENGTH];
7557 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
7558 display_to_port_type((field_display_e)hfinfo->display), value);
7559 label_fill(label_str, 0, hfinfo, tmp);
7562 out = hfinfo_number_value_format(hfinfo, buf, value);
7564 label_fill(label_str, 0, hfinfo, out);
7569 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
7571 header_field_info *hfinfo = fi->hfinfo;
7578 value = fvalue_get_sinteger64(&fi->value);
7580 value = fvalue_get_uinteger64(&fi->value);
7582 /* Fill in the textual info */
7583 if (hfinfo->display == BASE_CUSTOM) {
7584 gchar tmp[ITEM_LABEL_LENGTH];
7585 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7587 DISSECTOR_ASSERT(fmtfunc64);
7588 fmtfunc64(tmp, value);
7589 label_fill(label_str, 0, hfinfo, tmp);
7591 else if (hfinfo->strings) {
7592 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7594 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7595 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7596 label_fill(label_str, 0, hfinfo, val_str);
7598 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7601 out = hfinfo_number_value_format64(hfinfo, buf, value);
7603 label_fill(label_str, 0, hfinfo, out);
7608 hfinfo_bitshift(const header_field_info *hfinfo)
7610 return ws_ctz(hfinfo->bitmask);
7614 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
7616 if (!hfinfo->bitmask) {
7620 /* ilog2 = first set bit, ctz = last set bit */
7621 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
7625 hfinfo_type_bitwidth(enum ftenum type)
7663 DISSECTOR_ASSERT_NOT_REACHED();
7671 hfinfo_container_bitwidth(const header_field_info *hfinfo)
7673 if (!hfinfo->bitmask) {
7677 if (hfinfo->type == FT_BOOLEAN) {
7678 return hfinfo->display; /* hacky? :) */
7681 return hfinfo_type_bitwidth(hfinfo->type);
7685 hfinfo_hex_digits(const header_field_info *hfinfo)
7689 /* If we have a bitmask, hfinfo->type is the width of the container, so not
7690 * appropriate to determine the number of hex digits for the field.
7691 * So instead, we compute it from the bitmask.
7693 if (hfinfo->bitmask != 0) {
7694 bitwidth = hfinfo_mask_bitwidth(hfinfo);
7696 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
7699 /* Divide by 4, rounding up, to get number of hex digits. */
7700 return (bitwidth + 3) / 4;
7704 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
7706 char *ptr = &buf[31];
7707 gboolean isint = IS_FT_INT(hfinfo->type);
7710 /* Properly format value */
7711 switch (display & FIELD_DISPLAY_E_MASK) {
7713 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7717 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7720 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7724 return oct_to_str_back(ptr, value);
7727 return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7731 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7734 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7741 port_with_resolution_to_str_buf(buf, 32,
7742 display_to_port_type((field_display_e)display), value);
7746 g_assert_not_reached();
7752 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
7754 char *ptr = &buf[47];
7755 gboolean isint = IS_FT_INT(hfinfo->type);
7758 /* Properly format value */
7761 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7765 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7768 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7772 return oct64_to_str_back(ptr, value);
7775 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7779 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7782 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7786 g_assert_not_reached();
7792 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7794 int display = hfinfo->display;
7796 if (hfinfo->type == FT_FRAMENUM) {
7798 * Frame numbers are always displayed in decimal.
7803 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7807 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7809 int display = hfinfo->display;
7811 if (hfinfo->type == FT_FRAMENUM) {
7813 * Frame numbers are always displayed in decimal.
7818 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7822 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7824 /* Get the underlying BASE_ value */
7825 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7827 if (hfinfo->type == FT_FRAMENUM) {
7829 * Frame numbers are always displayed in decimal.
7834 if (IS_BASE_PORT(display)) {
7840 /* case BASE_DEC: */
7842 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
7847 /* case BASE_HEX: */
7853 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7857 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7859 /* Get the underlying BASE_ value */
7860 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7862 if (hfinfo->type == FT_FRAMENUM) {
7864 * Frame numbers are always displayed in decimal.
7871 /* case BASE_DEC: */
7873 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
7878 /* case BASE_HEX: */
7884 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7888 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7890 /* Get the underlying BASE_ value */
7891 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7893 if (display == BASE_NONE)
7896 if (display == BASE_DEC_HEX)
7898 if (display == BASE_HEX_DEC)
7901 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7905 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7907 /* Get the underlying BASE_ value */
7908 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7910 if (display == BASE_NONE)
7913 if (display == BASE_DEC_HEX)
7915 if (display == BASE_HEX_DEC)
7918 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7922 proto_registrar_get_name(const int n)
7924 header_field_info *hfinfo;
7926 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7927 return hfinfo->name;
7931 proto_registrar_get_abbrev(const int n)
7933 header_field_info *hfinfo;
7935 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7936 return hfinfo->abbrev;
7940 proto_registrar_get_ftype(const int n)
7942 header_field_info *hfinfo;
7944 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7945 return hfinfo->type;
7949 proto_registrar_get_parent(const int n)
7951 header_field_info *hfinfo;
7953 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7954 return hfinfo->parent;
7958 proto_registrar_is_protocol(const int n)
7960 header_field_info *hfinfo;
7962 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7963 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
7966 /* Returns length of field in packet (not necessarily the length
7967 * in our internal representation, as in the case of IPv4).
7968 * 0 means undeterminable at time of registration
7969 * -1 means the field is not registered. */
7971 proto_registrar_get_length(const int n)
7973 header_field_info *hfinfo;
7975 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7976 return ftype_length(hfinfo->type);
7979 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
7980 * it exists anywhere, or FALSE if it exists nowhere. */
7982 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
7984 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
7986 if (g_ptr_array_len(ptrs) > 0) {
7994 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
7995 * This only works if the hfindex was "primed" before the dissection
7996 * took place, as we just pass back the already-created GPtrArray*.
7997 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
8000 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
8005 if (PTREE_DATA(tree)->interesting_hfids != NULL)
8006 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
8007 GINT_TO_POINTER(id));
8013 proto_tracking_interesting_fields(const proto_tree *tree)
8015 GHashTable *interesting_hfids;
8020 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
8022 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
8025 /* Helper struct for proto_find_info() and proto_all_finfos() */
8031 /* Helper function for proto_find_info() */
8033 find_finfo(proto_node *node, gpointer data)
8035 field_info *fi = PNODE_FINFO(node);
8036 if (fi && fi->hfinfo) {
8037 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8038 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8042 /* Don't stop traversing. */
8046 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
8047 * This works on any proto_tree, primed or unprimed, but actually searches
8048 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8049 * The caller does need to free the returned GPtrArray with
8050 * g_ptr_array_free(<array>, TRUE).
8053 proto_find_finfo(proto_tree *tree, const int id)
8057 ffdata.array = g_ptr_array_new();
8060 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
8062 return ffdata.array;
8065 /* Helper function for proto_all_finfos() */
8067 every_finfo(proto_node *node, gpointer data)
8069 field_info *fi = PNODE_FINFO(node);
8070 if (fi && fi->hfinfo) {
8071 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8074 /* Don't stop traversing. */
8078 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
8080 proto_all_finfos(proto_tree *tree)
8084 ffdata.array = g_ptr_array_new();
8087 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
8089 return ffdata.array;
8100 check_for_offset(proto_node *node, gpointer data)
8102 field_info *fi = PNODE_FINFO(node);
8103 offset_search_t *offsearch = (offset_search_t *)data;
8105 /* !fi == the top most container node which holds nothing */
8106 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
8107 if (offsearch->offset >= (guint) fi->start &&
8108 offsearch->offset < (guint) (fi->start + fi->length)) {
8110 offsearch->finfo = fi;
8111 return FALSE; /* keep traversing */
8114 return FALSE; /* keep traversing */
8117 /* Search a proto_tree backwards (from leaves to root) looking for the field
8118 * whose start/length occupies 'offset' */
8119 /* XXX - I couldn't find an easy way to search backwards, so I search
8120 * forwards, w/o stopping. Therefore, the last finfo I find will the be
8121 * the one I want to return to the user. This algorithm is inefficient
8122 * and could be re-done, but I'd have to handle all the children and
8123 * siblings of each node myself. When I have more time I'll do that.
8126 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
8128 offset_search_t offsearch;
8130 offsearch.offset = offset;
8131 offsearch.finfo = NULL;
8132 offsearch.tvb = tvb;
8134 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
8136 return offsearch.finfo;
8141 check_for_undecoded(proto_node *node, gpointer data)
8143 field_info *fi = PNODE_FINFO(node);
8144 gchar* decoded = (gchar*)data;
8149 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
8150 for (i = fi->start; i < fi->start + fi->length; i++) {
8153 decoded[byte] |= (1 << bit);
8161 proto_find_undecoded_data(proto_tree *tree, guint length)
8163 gchar* decoded = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
8165 proto_tree_traverse_pre_order(tree, check_for_undecoded, decoded);
8169 /* Dumps the protocols in the registration database to stdout. An independent
8170 * program can take this output and format it into nice tables or HTML or
8173 * There is one record per line. The fields are tab-delimited.
8175 * Field 1 = protocol name
8176 * Field 2 = protocol short name
8177 * Field 3 = protocol filter name
8180 proto_registrar_dump_protocols(void)
8182 protocol_t *protocol;
8184 void *cookie = NULL;
8187 i = proto_get_first_protocol(&cookie);
8189 protocol = find_protocol_by_id(i);
8190 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
8191 protocol->filter_name);
8192 i = proto_get_next_protocol(&cookie);
8196 /* Dumps the value_strings, extended value string headers, range_strings
8197 * or true/false strings for fields that have them.
8198 * There is one record per line. Fields are tab-delimited.
8199 * There are four types of records: Value String, Extended Value String Header,
8200 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
8201 * the type of record.
8203 * Note that a record will be generated only if the value_string,... is referenced
8204 * in a registered hfinfo entry.
8210 * Field 2 = Field abbreviation to which this value string corresponds
8211 * Field 3 = Integer value
8214 * Extended Value String Headers
8215 * -----------------------------
8217 * Field 2 = Field abbreviation to which this extended value string header corresponds
8218 * Field 3 = Extended Value String "Name"
8219 * Field 4 = Number of entries in the associated value_string array
8220 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
8225 * Field 2 = Field abbreviation to which this range string corresponds
8226 * Field 3 = Integer value: lower bound
8227 * Field 4 = Integer value: upper bound
8230 * True/False Strings
8231 * ------------------
8233 * Field 2 = Field abbreviation to which this true/false string corresponds
8234 * Field 3 = True String
8235 * Field 4 = False String
8238 proto_registrar_dump_values(void)
8240 header_field_info *hfinfo;
8242 const value_string *vals;
8243 const val64_string *vals64;
8244 const range_string *range;
8245 const true_false_string *tfs;
8247 len = gpa_hfinfo.len;
8248 for (i = 0; i < len ; i++) {
8249 if (gpa_hfinfo.hfi[i] == NULL)
8250 continue; /* This is a deregistered protocol or field */
8252 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8254 if (hfinfo->id == hf_text_only) {
8258 /* ignore protocols */
8259 if (proto_registrar_is_protocol(i)) {
8262 /* process header fields */
8263 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
8265 * If this field isn't at the head of the list of
8266 * fields with this name, skip this field - all
8267 * fields with the same name are really just versions
8268 * of the same field stored in different bits, and
8269 * should have the same type/radix/value list, and
8270 * just differ in their bit masks. (If a field isn't
8271 * a bitfield, but can be, say, 1 or 2 bytes long,
8272 * it can just be made FT_UINT16, meaning the
8273 * *maximum* length is 2 bytes, and be used
8276 if (hfinfo->same_name_prev_id != -1)
8284 if (hfinfo->strings != NULL) {
8285 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) != BASE_CUSTOM &&
8286 (hfinfo->type == FT_UINT8 ||
8287 hfinfo->type == FT_UINT16 ||
8288 hfinfo->type == FT_UINT24 ||
8289 hfinfo->type == FT_UINT32 ||
8290 hfinfo->type == FT_UINT40 ||
8291 hfinfo->type == FT_UINT48 ||
8292 hfinfo->type == FT_UINT56 ||
8293 hfinfo->type == FT_UINT64 ||
8294 hfinfo->type == FT_INT8 ||
8295 hfinfo->type == FT_INT16 ||
8296 hfinfo->type == FT_INT24 ||
8297 hfinfo->type == FT_INT32 ||
8298 hfinfo->type == FT_INT40 ||
8299 hfinfo->type == FT_INT48 ||
8300 hfinfo->type == FT_INT56 ||
8301 hfinfo->type == FT_INT64)) {
8303 if (hfinfo->display & BASE_RANGE_STRING) {
8304 range = (const range_string *)hfinfo->strings;
8305 } else if (hfinfo->display & BASE_EXT_STRING) {
8306 vals = VALUE_STRING_EXT_VS_P((value_string_ext *)hfinfo->strings);
8307 } else if (hfinfo->display & BASE_VAL64_STRING) {
8308 vals64 = (const val64_string *)hfinfo->strings;
8310 vals = (const value_string *)hfinfo->strings;
8313 else if (hfinfo->type == FT_BOOLEAN) {
8314 tfs = (const struct true_false_string *)hfinfo->strings;
8318 /* Print value strings? */
8320 if (hfinfo->display & BASE_EXT_STRING) {
8321 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
8322 if (!value_string_ext_validate(vse_p)) {
8323 g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
8326 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
8327 printf("E\t%s\t%u\t%s\t%s\n",
8329 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
8330 VALUE_STRING_EXT_VS_NAME(vse_p),
8331 value_string_ext_match_type_str(vse_p));
8334 while (vals[vi].strptr) {
8335 /* Print in the proper base */
8336 if (hfinfo->display == BASE_HEX) {
8337 printf("V\t%s\t0x%x\t%s\n",
8343 printf("V\t%s\t%u\t%s\n",
8353 while (vals64[vi].strptr) {
8354 printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
8362 /* print range strings? */
8365 while (range[vi].strptr) {
8366 /* Print in the proper base */
8367 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_HEX) {
8368 printf("R\t%s\t0x%x\t0x%x\t%s\n",
8370 range[vi].value_min,
8371 range[vi].value_max,
8375 printf("R\t%s\t%u\t%u\t%s\n",
8377 range[vi].value_min,
8378 range[vi].value_max,
8385 /* Print true/false strings? */
8387 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
8388 tfs->true_string, tfs->false_string);
8393 /* Prints the number of registered fields.
8394 * Useful for determining an appropriate value for
8395 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
8397 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
8398 * the number of fields, TRUE otherwise.
8401 proto_registrar_dump_fieldcount(void)
8404 header_field_info *hfinfo;
8405 guint32 deregistered_count = 0;
8406 guint32 same_name_count = 0;
8407 guint32 protocol_count = 0;
8409 for (i = 0; i < gpa_hfinfo.len; i++) {
8410 if (gpa_hfinfo.hfi[i] == NULL) {
8411 deregistered_count++;
8412 continue; /* This is a deregistered protocol or header field */
8415 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8417 if (proto_registrar_is_protocol(i))
8420 if (hfinfo->same_name_prev_id != -1)
8424 printf ("There are %u header fields registered, of which:\n"
8425 "\t%u are deregistered\n"
8426 "\t%u are protocols\n"
8427 "\t%u have the same name as another field\n\n",
8428 gpa_hfinfo.len, deregistered_count, protocol_count,
8431 printf ("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
8432 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
8433 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
8436 printf ("The header field table consumes %u KiB of memory.\n",
8437 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
8438 printf ("The fields themselves consume %u KiB of memory.\n",
8439 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
8441 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8445 /* Dumps the contents of the registration database to stdout. An independent
8446 * program can take this output and format it into nice tables or HTML or
8449 * There is one record per line. Each record is either a protocol or a header
8450 * field, differentiated by the first field. The fields are tab-delimited.
8455 * Field 2 = descriptive protocol name
8456 * Field 3 = protocol abbreviation
8461 * Field 2 = descriptive field name
8462 * Field 3 = field abbreviation
8463 * Field 4 = type ( textual representation of the the ftenum type )
8464 * Field 5 = parent protocol abbreviation
8465 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
8466 * Field 7 = bitmask: format: hex: 0x....
8467 * Field 8 = blurb describing field
8470 proto_registrar_dump_fields(void)
8472 header_field_info *hfinfo, *parent_hfinfo;
8474 const char *enum_name;
8475 const char *base_name;
8479 len = gpa_hfinfo.len;
8480 for (i = 0; i < len ; i++) {
8481 if (gpa_hfinfo.hfi[i] == NULL)
8482 continue; /* This is a deregistered protocol or header field */
8484 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8487 * Skip the pseudo-field for "proto_tree_add_text()" since
8488 * we don't want it in the list of filterable fields.
8490 if (hfinfo->id == hf_text_only)
8493 /* format for protocols */
8494 if (proto_registrar_is_protocol(i)) {
8495 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
8497 /* format for header fields */
8500 * If this field isn't at the head of the list of
8501 * fields with this name, skip this field - all
8502 * fields with the same name are really just versions
8503 * of the same field stored in different bits, and
8504 * should have the same type/radix/value list, and
8505 * just differ in their bit masks. (If a field isn't
8506 * a bitfield, but can be, say, 1 or 2 bytes long,
8507 * it can just be made FT_UINT16, meaning the
8508 * *maximum* length is 2 bytes, and be used
8511 if (hfinfo->same_name_prev_id != -1)
8514 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
8516 enum_name = ftype_name(hfinfo->type);
8519 if (hfinfo->type == FT_UINT8 ||
8520 hfinfo->type == FT_UINT16 ||
8521 hfinfo->type == FT_UINT24 ||
8522 hfinfo->type == FT_UINT32 ||
8523 hfinfo->type == FT_UINT40 ||
8524 hfinfo->type == FT_UINT48 ||
8525 hfinfo->type == FT_UINT56 ||
8526 hfinfo->type == FT_UINT64 ||
8527 hfinfo->type == FT_INT8 ||
8528 hfinfo->type == FT_INT16 ||
8529 hfinfo->type == FT_INT24 ||
8530 hfinfo->type == FT_INT32 ||
8531 hfinfo->type == FT_INT40 ||
8532 hfinfo->type == FT_INT48 ||
8533 hfinfo->type == FT_INT56 ||
8534 hfinfo->type == FT_INT64) {
8536 switch (FIELD_DISPLAY(hfinfo->display)) {
8548 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
8554 } else if (hfinfo->type == FT_BOOLEAN) {
8555 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
8556 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
8560 blurb = hfinfo->blurb;
8563 else if (strlen(blurb) == 0)
8566 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
8567 hfinfo->name, hfinfo->abbrev, enum_name,
8568 parent_hfinfo->abbrev, base_name,
8569 hfinfo->bitmask, blurb);
8574 /* Dumps field types and descriptive names to stdout. An independent
8575 * program can take this output and format it into nice tables or HTML or
8578 * There is one record per line. The fields are tab-delimited.
8580 * Field 1 = field type name, e.g. FT_UINT8
8581 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
8584 proto_registrar_dump_ftypes(void)
8588 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
8589 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
8593 /* This function indicates whether it's possible to construct a
8594 * "match selected" display filter string for the specified field,
8595 * returns an indication of whether it's possible, and, if it's
8596 * possible and "filter" is non-null, constructs the filter and
8597 * sets "*filter" to point to it.
8598 * You do not need to [g_]free() this string since it will be automatically
8599 * freed once the next packet is dissected.
8602 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
8605 header_field_info *hfinfo;
8610 gint start, length, length_remaining;
8612 gchar is_signed_num = FALSE;
8617 hfinfo = finfo->hfinfo;
8618 DISSECTOR_ASSERT(hfinfo);
8619 abbrev_len = (int) strlen(hfinfo->abbrev);
8621 if (hfinfo->strings && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
8622 const gchar *str = NULL;
8624 switch (hfinfo->type) {
8630 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
8637 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
8644 if (str != NULL && filter != NULL) {
8645 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
8651 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
8652 * functions for FT_UINT and FT_INT types, as we choose the base in
8653 * the string expression based on the display base of the field.
8655 * Note that the base does matter, as this is also used for
8656 * the protocolinfo tap.
8658 * It might be nice to use them in "proto_item_fill_label()"
8659 * as well, although, there, you'd have to deal with the base
8660 * *and* with resolved values for addresses.
8662 * Perhaps we need two different val_to_string routines, one
8663 * to generate items for display filters and one to generate
8664 * strings for display, and pass to both of them the
8665 * "display" and "strings" values in the header_field_info
8666 * structure for the field, so they can get the base and,
8667 * if the field is Boolean or an enumerated integer type,
8668 * the tables used to generate human-readable values.
8670 switch (hfinfo->type) {
8676 is_signed_num = TRUE;
8683 if (filter != NULL) {
8690 number = fvalue_get_sinteger(&finfo->value);
8692 number = fvalue_get_uinteger(&finfo->value);
8694 out = hfinfo_numeric_value_format(hfinfo, buf, number);
8696 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
8704 is_signed_num = TRUE;
8710 if (filter != NULL) {
8717 number = fvalue_get_sinteger64(&finfo->value);
8719 number = fvalue_get_uinteger64(&finfo->value);
8721 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
8723 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
8729 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
8734 * If the length is 0, just match the name of the
8737 * (Also check for negative values, just in case,
8738 * as we'll cast it to an unsigned value later.)
8740 length = finfo->length;
8743 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
8750 * This doesn't have a value, so we'd match
8751 * on the raw bytes at this address.
8753 * Should we be allowed to access to the raw bytes?
8754 * If "edt" is NULL, the answer is "no".
8760 * Is this field part of the raw frame tvbuff?
8761 * If not, we can't use "frame[N:M]" to match
8764 * XXX - should this be frame-relative, or
8765 * protocol-relative?
8767 * XXX - does this fallback for non-registered
8768 * fields even make sense?
8770 if (finfo->ds_tvb != edt->tvb)
8771 return FALSE; /* you lose */
8774 * Don't go past the end of that tvbuff.
8776 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
8777 if (length > length_remaining)
8778 length = length_remaining;
8782 if (filter != NULL) {
8783 start = finfo->start;
8784 buf_len = 32 + length * 3;
8785 *filter = (char *)wmem_alloc0(NULL, buf_len);
8788 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
8789 "frame[%d:%d] == ", finfo->start, length);
8790 for (i=0; i<length; i++) {
8791 c = tvb_get_guint8(finfo->ds_tvb, start);
8794 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
8797 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
8804 /* FT_PCRE never appears as a type for a registered field. It is
8805 * only used internally. */
8806 DISSECTOR_ASSERT_NOT_REACHED();
8809 /* By default, use the fvalue's "to_string_repr" method. */
8811 /* Figure out the string length needed.
8812 * The ft_repr length.
8813 * 4 bytes for " == ".
8814 * 1 byte for trailing NUL.
8816 if (filter != NULL) {
8818 dfilter_len = fvalue_string_repr_len(&finfo->value,
8819 FTREPR_DFILTER, finfo->hfinfo->display);
8820 dfilter_len += abbrev_len + 4 + 1;
8821 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
8823 /* Create the string */
8824 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
8825 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
8826 wmem_free(NULL, str);
8835 * Returns TRUE if we can do a "match selected" on the field, FALSE
8839 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
8841 return construct_match_selected_string(finfo, edt, NULL);
8844 /* This function attempts to construct a "match selected" display filter
8845 * string for the specified field; if it can do so, it returns a pointer
8846 * to the string, otherwise it returns NULL.
8848 * The string is allocated with packet lifetime scope.
8849 * You do not need to [g_]free() this string since it will be automatically
8850 * freed once the next packet is dissected.
8853 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
8855 char *filter = NULL;
8857 if (!construct_match_selected_string(finfo, edt, &filter))
8859 wmem_free(NULL, filter);
8865 /* This function is common code for all proto_tree_add_bitmask... functions.
8869 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
8870 const int len, const gint ett, const int **fields,
8871 const int flags, gboolean first,
8872 gboolean use_parent_tree,
8873 proto_tree* tree, guint64 value)
8876 guint64 available_bits = 0;
8878 header_field_info *hf;
8880 if (len < 0 || len > 8)
8881 g_assert_not_reached();
8882 bitshift = (8 - (guint)len)*8;
8883 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
8885 if (use_parent_tree == FALSE)
8886 tree = proto_item_add_subtree(item, ett);
8889 guint64 present_bits;
8890 PROTO_REGISTRAR_GET_NTH(**fields,hf);
8891 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
8893 /* Skip fields that aren't fully present */
8894 present_bits = available_bits & hf->bitmask;
8895 if (present_bits != hf->bitmask) {
8909 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
8920 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
8924 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
8928 DISSECTOR_ASSERT_NOT_REACHED();
8931 if (flags & BMT_NO_APPEND) {
8935 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
8954 if (hf->display == BASE_CUSTOM) {
8955 gchar lbl[ITEM_LABEL_LENGTH];
8956 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
8958 DISSECTOR_ASSERT(fmtfunc);
8959 fmtfunc(lbl, (guint32) tmpval);
8960 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8964 else if (hf->strings) {
8965 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8966 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
8969 else if (!(flags & BMT_NO_INT)) {
8974 proto_item_append_text(item, ", ");
8977 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
8978 proto_item_append_text(item, "%s: %s", hf->name, out);
8984 if (hf->strings && !(flags & BMT_NO_TFS)) {
8985 /* If we have true/false strings, emit full - otherwise messages
8987 const struct true_false_string *tfs =
8988 (const struct true_false_string *)hf->strings;
8991 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8992 hf->name, tfs->true_string);
8994 } else if (!(flags & BMT_NO_FALSE)) {
8995 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8996 hf->name, tfs->false_string);
8999 } else if (hf->bitmask & value) {
9000 /* If the flag is set, show the name */
9001 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
9006 DISSECTOR_ASSERT_NOT_REACHED();
9016 /* This function will dissect a sequence of bytes that describe a
9017 * bitmask and supply the value of that sequence through a pointer.
9018 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9020 * This field will form an expansion under which the individual fields of the
9021 * bitmask is dissected and displayed.
9022 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9024 * fields is an array of pointers to int that lists all the fields of the
9025 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9026 * or another integer of the same type/size as hf_hdr with a mask specified.
9027 * This array is terminated by a NULL entry.
9029 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9030 * FT_integer fields that have a value_string attached will have the
9031 * matched string displayed on the expansion line.
9034 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
9035 const guint offset, const int hf_hdr,
9036 const gint ett, const int **fields,
9037 const guint encoding, guint64 *retval)
9039 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);
9042 /* This function will dissect a sequence of bytes that describe a
9044 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9046 * This field will form an expansion under which the individual fields of the
9047 * bitmask is dissected and displayed.
9048 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9050 * fields is an array of pointers to int that lists all the fields of the
9051 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9052 * or another integer of the same type/size as hf_hdr with a mask specified.
9053 * This array is terminated by a NULL entry.
9055 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9056 * FT_integer fields that have a value_string attached will have the
9057 * matched string displayed on the expansion line.
9060 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
9061 const guint offset, const int hf_hdr,
9062 const gint ett, const int **fields,
9063 const guint encoding)
9065 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
9068 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9069 * what data is appended to the header.
9072 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9073 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
9076 proto_item *item = NULL;
9077 header_field_info *hf;
9081 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9082 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9083 len = ftype_length(hf->type);
9084 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9087 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9088 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9089 flags, FALSE, FALSE, NULL, value);
9096 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9097 * what data is appended to the header.
9100 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9101 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
9103 proto_item *item = NULL;
9104 header_field_info *hf;
9108 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9109 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9112 len = ftype_length(hf->type);
9113 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9114 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9115 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9116 flags, FALSE, FALSE, NULL, value);
9122 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
9123 can't be retrieved directly from tvb) */
9125 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9126 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
9128 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
9129 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
9132 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
9133 WS_DLL_PUBLIC proto_item *
9134 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9135 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
9137 proto_item *item = NULL;
9138 header_field_info *hf;
9141 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9142 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9143 len = ftype_length(hf->type);
9147 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
9149 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
9151 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9152 flags, FALSE, FALSE, NULL, value);
9158 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
9160 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9161 const int len, const int **fields, const guint encoding)
9166 value = get_uint64_value(tree, tvb, offset, len, encoding);
9167 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9168 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9173 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9174 const int len, const int **fields, const guint64 value)
9177 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9178 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9183 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
9184 * This is intended to support bitmask fields whose lengths can vary, perhaps
9185 * as the underlying standard evolves over time.
9186 * With this API there is the possibility of being called to display more or
9187 * less data than the dissector was coded to support.
9188 * In such cases, it is assumed that bitmasks are extended on the MSb end.
9189 * Thus when presented with "too much" or "too little" data, MSbits will be
9190 * ignored or MSfields sacrificed.
9192 * Only fields for which all defined bits are available are displayed.
9195 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
9196 const guint offset, const guint len, const int hf_hdr,
9197 const gint ett, const int **fields, struct expert_field* exp,
9198 const guint encoding)
9200 proto_item *item = NULL;
9201 header_field_info *hf;
9202 guint decodable_len;
9203 guint decodable_offset;
9204 guint32 decodable_value;
9207 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
9208 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9210 decodable_offset = offset;
9211 decodable_len = MIN(len, (guint) ftype_length(hf->type));
9213 /* If we are ftype_length-limited,
9214 * make sure we decode as many LSBs as possible.
9216 if (encoding == ENC_BIG_ENDIAN) {
9217 decodable_offset += (len - decodable_len);
9221 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
9222 decodable_len, encoding);
9224 /* The root item covers all the bytes even if we can't decode them all */
9225 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
9229 if (decodable_len < len) {
9230 /* Dissector likely requires updating for new protocol revision */
9231 expert_add_info_format(NULL, item, exp,
9232 "Only least-significant %d of %d bytes decoded",
9233 decodable_len, len);
9237 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
9238 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
9239 ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
9245 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
9247 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
9248 const guint offset, const guint len,
9249 const char *name, const char *fallback,
9250 const gint ett, const int **fields,
9251 const guint encoding, const int flags)
9253 proto_item *item = NULL;
9257 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
9258 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9259 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9260 flags, TRUE, FALSE, NULL, value) && fallback) {
9261 /* Still at first item - append 'fallback' text if any */
9262 proto_item_append_text(item, "%s", fallback);
9270 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9271 const guint bit_offset, const gint no_of_bits,
9272 const guint encoding)
9274 header_field_info *hfinfo;
9278 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9280 octet_length = (no_of_bits + 7) >> 3;
9281 octet_offset = bit_offset >> 3;
9282 test_length(hfinfo, tvb, octet_offset, octet_length);
9284 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
9285 * but only after doing a bunch more work (which we can, in the common
9286 * case, shortcut here).
9288 CHECK_FOR_NULL_TREE(tree);
9289 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9291 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
9295 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
9296 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
9297 * Offset should be given in bits from the start of the tvb.
9301 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9302 const guint bit_offset, const gint no_of_bits,
9303 guint64 *return_value, const guint encoding)
9309 char lbl_str[ITEM_LABEL_LENGTH];
9313 header_field_info *hf_field;
9315 const true_false_string *tfstring;
9317 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
9318 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
9320 if (hf_field->bitmask != 0) {
9321 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9322 "Incompatible use of proto_tree_add_bits_ret_val"
9323 " with field '%s' (%s) with bitmask != 0",
9324 hf_field->abbrev, hf_field->name));
9327 DISSECTOR_ASSERT(no_of_bits > 0);
9329 /* Byte align offset */
9330 offset = bit_offset>>3;
9333 * Calculate the number of octets used to hold the bits
9335 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
9336 length = (tot_no_bits + 7) >> 3;
9338 if (no_of_bits < 65) {
9339 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
9341 DISSECTOR_ASSERT_NOT_REACHED();
9345 /* Sign extend for signed types */
9346 switch (hf_field->type) {
9355 value = ws_sign_ext64(value, no_of_bits);
9363 *return_value = value;
9366 /* Coast clear. Try and fake it */
9367 CHECK_FOR_NULL_TREE(tree);
9368 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9370 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
9372 switch (hf_field->type) {
9375 tfstring = (const true_false_string *) &tfs_true_false;
9376 if (hf_field->strings)
9377 tfstring = (const true_false_string *)hf_field->strings;
9378 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
9380 bf_str, hf_field->name,
9381 (guint64)value ? tfstring->true_string : tfstring->false_string);
9388 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
9389 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
9396 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
9397 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
9404 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
9405 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
9412 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
9413 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
9417 DISSECTOR_ASSERT_NOT_REACHED();
9422 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
9427 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9428 const guint bit_offset, const crumb_spec_t *crumb_spec,
9429 guint64 *return_value)
9434 guint mask_initial_bit_offset;
9435 guint mask_greatest_bit_offset;
9439 char lbl_str[ITEM_LABEL_LENGTH];
9441 guint64 composite_bitmask;
9442 guint64 composite_bitmap;
9444 header_field_info *hf_field;
9445 const true_false_string *tfstring;
9447 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
9448 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
9450 if (hf_field->bitmask != 0) {
9451 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9452 "Incompatible use of proto_tree_add_split_bits_item_ret_val"
9453 " with field '%s' (%s) with bitmask != 0",
9454 hf_field->abbrev, hf_field->name));
9457 mask_initial_bit_offset = bit_offset % 8;
9462 mask_greatest_bit_offset = 0;
9463 composite_bitmask = 0;
9464 composite_bitmap = 0;
9466 while (crumb_spec[i].crumb_bit_length != 0) {
9467 guint64 crumb_mask, crumb_value;
9468 guint8 crumb_end_bit_offset;
9470 DISSECTOR_ASSERT(i < 64);
9471 crumb_value = tvb_get_bits64(tvb,
9472 bit_offset + crumb_spec[i].crumb_bit_offset,
9473 crumb_spec[i].crumb_bit_length,
9475 value += crumb_value;
9476 no_of_bits += crumb_spec[i].crumb_bit_length;
9478 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
9479 octet containing the initial offset.
9480 If the mask is beyond 32 bits, then give up on bit map display.
9481 This could be improved in future, probably showing a table
9482 of 32 or 64 bits per row */
9483 if (mask_greatest_bit_offset < 32) {
9484 crumb_end_bit_offset = mask_initial_bit_offset
9485 + crumb_spec[i].crumb_bit_offset
9486 + crumb_spec[i].crumb_bit_length;
9487 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
9489 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
9490 mask_greatest_bit_offset = crumb_end_bit_offset;
9492 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
9493 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
9495 /* Shift left for the next segment */
9496 value <<= crumb_spec[++i].crumb_bit_length;
9499 /* Sign extend for signed types */
9500 switch (hf_field->type) {
9509 value = ws_sign_ext64(value, no_of_bits);
9516 *return_value = value;
9519 /* Coast clear. Try and fake it */
9520 CHECK_FOR_NULL_TREE(tree);
9521 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9523 /* initialise the format string */
9526 octet_offset = bit_offset >> 3;
9528 /* Round up mask length to nearest octet */
9529 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
9530 mask_greatest_bit_offset = octet_length << 3;
9532 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
9533 It would be a useful enhancement to eliminate this restriction. */
9534 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
9535 other_decode_bitfield_value(bf_str,
9536 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
9537 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
9538 mask_greatest_bit_offset);
9541 switch (hf_field->type) {
9542 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
9544 tfstring = (const true_false_string *) &tfs_true_false;
9545 if (hf_field->strings)
9546 tfstring = (const true_false_string *) hf_field->strings;
9547 return proto_tree_add_boolean_format(tree, hfindex,
9548 tvb, octet_offset, octet_length, (guint32)value,
9550 bf_str, hf_field->name,
9551 (guint64)value ? tfstring->true_string : tfstring->false_string);
9558 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
9559 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
9566 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
9567 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
9574 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
9575 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
9582 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
9583 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
9587 DISSECTOR_ASSERT_NOT_REACHED();
9591 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
9596 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
9597 const crumb_spec_t *crumb_spec, guint16 crumb_index)
9599 header_field_info *hfinfo;
9601 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9602 proto_tree_add_text_internal(tree, tvb,
9604 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
9605 "%s crumb %d of %s (decoded above)",
9606 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
9609 crumb_spec[crumb_index].crumb_bit_length,
9616 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9617 const guint bit_offset, const gint no_of_bits,
9618 guint64 *return_value, const guint encoding)
9622 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
9623 bit_offset, no_of_bits,
9624 return_value, encoding))) {
9625 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
9626 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
9632 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
9633 tvbuff_t *tvb, const guint bit_offset,
9634 const gint no_of_bits, void *value_ptr,
9642 header_field_info *hf_field;
9644 /* We do not have to return a value, try to fake it as soon as possible */
9645 CHECK_FOR_NULL_TREE(tree);
9646 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9648 if (hf_field->bitmask != 0) {
9649 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9650 "Incompatible use of proto_tree_add_bits_format_value"
9651 " with field '%s' (%s) with bitmask != 0",
9652 hf_field->abbrev, hf_field->name));
9655 DISSECTOR_ASSERT(no_of_bits > 0);
9657 /* Byte align offset */
9658 offset = bit_offset>>3;
9661 * Calculate the number of octets used to hold the bits
9663 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
9664 length = tot_no_bits>>3;
9665 /* If we are using part of the next octet, increase length by 1 */
9666 if (tot_no_bits & 0x07)
9669 if (no_of_bits < 65) {
9670 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
9672 DISSECTOR_ASSERT_NOT_REACHED();
9676 str = decode_bits_in_field(bit_offset, no_of_bits, value);
9678 g_strlcat(str, " = ", 256+64);
9679 g_strlcat(str, hf_field->name, 256+64);
9682 * This function does not receive an actual value but a dimensionless pointer to that value.
9683 * For this reason, the type of the header field is examined in order to determine
9684 * what kind of value we should read from this address.
9685 * The caller of this function must make sure that for the specific header field type the address of
9686 * a compatible value is provided.
9688 switch (hf_field->type) {
9690 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
9691 "%s: %s", str, value_str);
9698 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
9699 "%s: %s", str, value_str);
9706 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
9707 "%s: %s", str, value_str);
9714 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
9715 "%s: %s", str, value_str);
9722 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
9723 "%s: %s", str, value_str);
9727 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
9728 "%s: %s", str, value_str);
9732 DISSECTOR_ASSERT_NOT_REACHED();
9739 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
9740 tvbuff_t *tvb, const guint bit_offset,
9741 const gint no_of_bits, void *value_ptr,
9746 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
9747 tvb, bit_offset, no_of_bits,
9748 value_ptr, value_str))) {
9749 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
9750 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
9755 #define CREATE_VALUE_STRING(dst,format,ap) \
9756 va_start(ap, format); \
9757 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
9761 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
9762 tvbuff_t *tvb, const guint bit_offset,
9763 const gint no_of_bits, guint32 value,
9764 const char *format, ...)
9768 header_field_info *hf_field;
9770 CHECK_FOR_NULL_TREE(tree);
9772 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9774 switch (hf_field->type) {
9782 DISSECTOR_ASSERT_NOT_REACHED();
9787 CREATE_VALUE_STRING(dst, format, ap);
9789 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9793 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
9794 tvbuff_t *tvb, const guint bit_offset,
9795 const gint no_of_bits, guint64 value,
9796 const char *format, ...)
9800 header_field_info *hf_field;
9802 CHECK_FOR_NULL_TREE(tree);
9804 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9806 switch (hf_field->type) {
9814 DISSECTOR_ASSERT_NOT_REACHED();
9819 CREATE_VALUE_STRING(dst, format, ap);
9821 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9825 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
9826 tvbuff_t *tvb, const guint bit_offset,
9827 const gint no_of_bits, float value,
9828 const char *format, ...)
9832 header_field_info *hf_field;
9834 CHECK_FOR_NULL_TREE(tree);
9836 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9838 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
9840 CREATE_VALUE_STRING(dst, format, ap);
9842 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9846 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
9847 tvbuff_t *tvb, const guint bit_offset,
9848 const gint no_of_bits, gint32 value,
9849 const char *format, ...)
9853 header_field_info *hf_field;
9855 CHECK_FOR_NULL_TREE(tree);
9857 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9859 switch (hf_field->type) {
9867 DISSECTOR_ASSERT_NOT_REACHED();
9872 CREATE_VALUE_STRING(dst, format, ap);
9874 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9878 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
9879 tvbuff_t *tvb, const guint bit_offset,
9880 const gint no_of_bits, gint64 value,
9881 const char *format, ...)
9885 header_field_info *hf_field;
9887 CHECK_FOR_NULL_TREE(tree);
9889 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9891 switch (hf_field->type) {
9899 DISSECTOR_ASSERT_NOT_REACHED();
9904 CREATE_VALUE_STRING(dst, format, ap);
9906 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9910 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
9911 tvbuff_t *tvb, const guint bit_offset,
9912 const gint no_of_bits, guint32 value,
9913 const char *format, ...)
9917 header_field_info *hf_field;
9919 CHECK_FOR_NULL_TREE(tree);
9921 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9923 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
9925 CREATE_VALUE_STRING(dst, format, ap);
9927 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9931 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
9932 tvbuff_t *tvb, const guint bit_offset,
9933 const gint no_of_bits, guint64 value,
9934 const char *format, ...)
9938 header_field_info *hf_field;
9940 CHECK_FOR_NULL_TREE(tree);
9942 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9944 DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
9946 CREATE_VALUE_STRING(dst, format, ap);
9948 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9952 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9953 const guint bit_offset, const gint no_of_chars)
9956 header_field_info *hfinfo;
9961 CHECK_FOR_NULL_TREE(tree);
9963 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9965 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
9967 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
9968 byte_offset = bit_offset >> 3;
9970 string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
9972 if (hfinfo->display == STR_UNICODE) {
9973 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
9976 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
9977 DISSECTOR_ASSERT(byte_length >= 0);
9978 proto_tree_set_string(PNODE_FINFO(pi), string);
9984 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9985 const guint bit_offset, const gint no_of_chars)
9988 header_field_info *hfinfo;
9993 CHECK_FOR_NULL_TREE(tree);
9995 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9997 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
9999 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
10000 byte_offset = bit_offset >> 3;
10002 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
10004 if (hfinfo->display == STR_UNICODE) {
10005 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
10008 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
10009 DISSECTOR_ASSERT(byte_length >= 0);
10010 proto_tree_set_string(PNODE_FINFO(pi), string);
10016 proto_check_field_name(const gchar *field_name)
10018 return wrs_check_charset(fld_abbrev_chars, field_name);
10022 tree_expanded(int tree_type)
10024 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10025 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
10029 tree_expanded_set(int tree_type, gboolean value)
10031 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10034 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
10036 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
10040 * Editor modelines - http://www.wireshark.org/tools/modelines.html
10043 * c-basic-offset: 8
10045 * indent-tabs-mode: t
10048 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
10049 * :indentSize=8:tabSize=8:noTabs=false: