2 * Routines for protocol tree
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include <wsutil/bits_ctz.h>
32 #include <wsutil/bits_count_ones.h>
33 #include <wsutil/sign_ext.h>
35 #include <ftypes/ftypes-int.h>
38 #include "exceptions.h"
39 #include "ptvcursor.h"
41 #include "addr_resolv.h"
42 #include "address_types.h"
45 #include "epan_dissect.h"
47 #include "wmem/wmem.h"
49 #include "asm_utils.h"
50 #include "column-utils.h"
51 #include "to_str-int.h"
53 #include "osi-utils.h"
55 #include "show_exception.h"
58 #include <wsutil/plugins.h>
59 #include <wsutil/ws_printf.h> /* ws_debug_printf/ws_g_warning */
61 /* Ptvcursor limits */
62 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
63 #define SUBTREE_MAX_LEVELS 256
65 /* Throw an exception if our tree exceeds these. */
66 /* XXX - These should probably be preferences */
67 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
68 #define MAX_TREE_LEVELS (5 * 100)
70 typedef struct __subtree_lvl {
77 subtree_lvl *pushed_tree;
78 guint8 pushed_tree_index;
79 guint8 pushed_tree_max;
85 #define cVALS(x) (const value_string*)(x)
87 /** See inlined comments.
88 @param tree the tree to append this item to
89 @param free_block a code block to call to free resources if this returns
90 @return NULL if 'tree' is null */
91 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block) \
97 /** See inlined comments.
98 @param tree the tree to append this item to
99 @param free_block a code block to call to free resources if this returns
100 @return NULL if 'tree' is null */
101 #define CHECK_FOR_NULL_TREE(tree) \
102 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
104 /** See inlined comments.
105 @param tree the tree to append this item to
106 @param hfindex field index
107 @param hfinfo header_field
108 @param free_block a code block to call to free resources if this returns
109 @return the header field matching 'hfinfo' */
110 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
111 /* If this item is not referenced we don't have to do much work \
112 at all but we should still return a node so that field items \
113 below this node (think proto_item_add_subtree()) will still \
114 have somewhere to attach to or else filtering will not work \
115 (they would be ignored since tree would be NULL). \
116 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
117 since dissectors that want to do proto_item_set_len() or \
118 other operations that dereference this would crash. \
119 We fake FT_PROTOCOL unless some clients have requested us \
122 PTREE_DATA(tree)->count++; \
123 if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
125 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
126 g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
127 /* Let the exception handler add items to the tree */ \
128 PTREE_DATA(tree)->count = 0; \
129 THROW_MESSAGE(DissectorError, \
130 wmem_strdup_printf(wmem_packet_scope(), "More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
132 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
133 if (!(PTREE_DATA(tree)->visible)) { \
134 if (PTREE_FINFO(tree)) { \
135 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
136 && (hfinfo->type != FT_PROTOCOL || \
137 PTREE_DATA(tree)->fake_protocols)) { \
139 /* just return tree back to the caller */\
145 /** See inlined comments.
146 @param tree the tree to append this item to
147 @param hfindex field index
148 @param hfinfo header_field
149 @return the header field matching 'hfinfo' */
150 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
151 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
154 /** See inlined comments.
155 @param pi the created protocol item we're about to return */
156 #define TRY_TO_FAKE_THIS_REPR(pi) \
158 if (!(PTREE_DATA(pi)->visible)) { \
159 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
160 * items string representation */ \
163 /* Same as above but returning void */
164 #define TRY_TO_FAKE_THIS_REPR_VOID(pi) \
167 if (!(PTREE_DATA(pi)->visible)) { \
168 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
169 * items string representation */ \
173 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
174 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
175 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
177 static void label_mark_truncated(char *label_str, gsize name_pos);
178 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
180 static void fill_label_boolean(field_info *fi, gchar *label_str);
181 static void fill_label_bitfield_char(field_info *fi, gchar *label_str);
182 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
183 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
184 static void fill_label_char(field_info *fi, gchar *label_str);
185 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
186 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
188 static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value);
189 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
190 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
191 static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
192 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
193 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
194 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
195 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
196 static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
197 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
198 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
201 proto_tree_add_node(proto_tree *tree, field_info *fi);
204 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
208 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
209 gint length, guint item_length, const gint encoding);
212 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
213 const gint start, const gint item_length);
216 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
217 gint start, gint *length);
220 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
222 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
225 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
227 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
229 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
231 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
233 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
235 proto_tree_set_string(field_info *fi, const char* value);
237 proto_tree_set_ax25(field_info *fi, const guint8* value);
239 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
241 proto_tree_set_vines(field_info *fi, const guint8* value);
243 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
245 proto_tree_set_ether(field_info *fi, const guint8* value);
247 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
249 proto_tree_set_ipxnet(field_info *fi, guint32 value);
251 proto_tree_set_ipv4(field_info *fi, guint32 value);
253 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
255 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
257 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
259 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
261 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
263 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
265 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
267 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
269 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
271 proto_tree_set_boolean(field_info *fi, guint64 value);
273 proto_tree_set_float(field_info *fi, float value);
275 proto_tree_set_double(field_info *fi, double value);
277 proto_tree_set_uint(field_info *fi, guint32 value);
279 proto_tree_set_int(field_info *fi, gint32 value);
281 proto_tree_set_uint64(field_info *fi, guint64 value);
283 proto_tree_set_int64(field_info *fi, gint64 value);
285 proto_tree_set_eui64(field_info *fi, const guint64 value);
287 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
289 /* Handle type length mismatch (now filterable) expert info */
290 static int proto_type_length_mismatch = -1;
291 static expert_field ei_type_length_mismatch_error = EI_INIT;
292 static expert_field ei_type_length_mismatch_warn = EI_INIT;
293 static void register_type_length_mismatch(void);
295 /* Handle number string decoding errors with expert info */
296 static int proto_number_string_decoding_error = -1;
297 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
298 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
299 static void register_number_string_decoding_error(void);
301 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
303 /* special-case header field used within proto.c */
304 static header_field_info hfi_text_only =
305 { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
306 int hf_text_only = -1;
308 /* Structure for information about a protocol */
310 const char *name; /* long description */
311 const char *short_name; /* short description */
312 const char *filter_name; /* name of this protocol in filters */
313 GPtrArray *fields; /* fields for this protocol */
314 int proto_id; /* field ID for this protocol */
315 gboolean is_enabled; /* TRUE if protocol is enabled */
316 gboolean enabled_by_default; /* TRUE if protocol is enabled by default */
317 gboolean can_toggle; /* TRUE if is_enabled can be changed */
318 GList *heur_list; /* Heuristic dissectors associated with this protocol */
321 /* List of all protocols */
322 static GList *protocols = NULL;
324 /* Deregistered fields */
325 static GPtrArray *deregistered_fields = NULL;
326 static GPtrArray *deregistered_data = NULL;
328 /* Contains information about a field when a dissector calls
329 * proto_tree_add_item. */
330 #define FIELD_INFO_NEW(pool, fi) fi = wmem_new(pool, field_info)
331 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
333 /* Contains the space for proto_nodes. */
334 #define PROTO_NODE_INIT(node) \
335 node->first_child = NULL; \
336 node->last_child = NULL; \
339 #define PROTO_NODE_FREE(pool, node) \
340 wmem_free(pool, node)
342 /* String space for protocol and field items for the GUI */
343 #define ITEM_LABEL_NEW(pool, il) \
344 il = wmem_new(pool, item_label_t);
345 #define ITEM_LABEL_FREE(pool, il) \
348 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
349 if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
350 g_error("Unregistered hf! index=%d", hfindex); \
351 DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
352 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
353 hfinfo = gpa_hfinfo.hfi[hfindex];
355 /* List which stores protocols and fields that have been registered */
356 typedef struct _gpa_hfinfo_t {
358 guint32 allocated_len;
359 header_field_info **hfi;
362 static gpa_hfinfo_t gpa_hfinfo;
364 /* Hash table of abbreviations and IDs */
365 static GHashTable *gpa_name_map = NULL;
366 static header_field_info *same_name_hfinfo;
368 * We're called repeatedly with the same field name when sorting a column.
369 * Cache our last gpa_name_map hit for faster lookups.
371 static char *last_field_name = NULL;
372 static header_field_info *last_hfinfo;
374 static void save_same_name_hfinfo(gpointer data)
376 same_name_hfinfo = (header_field_info*)data;
379 /* Cached value for VINES address type (used for FT_VINES) */
380 static int vines_address_type = -1;
382 /* Points to the first element of an array of bits, indexed by
383 a subtree item type; that array element is TRUE if subtrees of
384 an item of that type are to be expanded. */
385 static guint32 *tree_is_expanded;
387 /* Number of elements in that array. */
390 /* Name hashtables for fast detection of duplicate names */
391 static GHashTable* proto_names = NULL;
392 static GHashTable* proto_short_names = NULL;
393 static GHashTable* proto_filter_names = NULL;
396 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
398 const protocol_t *p1 = (const protocol_t *)p1_arg;
399 const protocol_t *p2 = (const protocol_t *)p2_arg;
401 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
406 * List of dissector plugins.
409 void (*register_protoinfo)(void); /* routine to call to register protocol information */
410 void (*reg_handoff)(void); /* routine to call to register dissector handoff */
413 static GSList *dissector_plugins = NULL;
416 * Callback for each plugin found.
419 check_for_dissector_plugin(GModule *handle)
422 void (*register_protoinfo)(void);
423 void (*reg_handoff)(void);
424 dissector_plugin *plugin;
427 * Do we have a register routine?
429 if (g_module_symbol(handle, "plugin_register", &gp)) {
431 register_protoinfo = (void (*)(void))gp;
435 register_protoinfo = NULL;
439 * Do we have a reg_handoff routine?
441 if (g_module_symbol(handle, "plugin_reg_handoff", &gp)) {
443 reg_handoff = (void (*)(void))gp;
451 * If we have neither, we're not a dissector plugin.
453 if (register_protoinfo == NULL && reg_handoff == NULL)
457 * Add this one to the list of dissector plugins.
459 plugin = (dissector_plugin *)g_malloc(sizeof (dissector_plugin));
460 plugin->register_protoinfo = register_protoinfo;
461 plugin->reg_handoff = reg_handoff;
462 dissector_plugins = g_slist_prepend(dissector_plugins, plugin);
467 register_dissector_plugin(gpointer data, gpointer user_data _U_)
469 dissector_plugin *plugin = (dissector_plugin *)data;
471 if (plugin->register_protoinfo)
472 (plugin->register_protoinfo)();
476 reg_handoff_dissector_plugin(gpointer data, gpointer user_data _U_)
478 dissector_plugin *plugin = (dissector_plugin *)data;
480 if (plugin->reg_handoff)
481 (plugin->reg_handoff)();
485 * Register dissector plugin type.
488 register_dissector_plugin_type(void)
490 add_plugin_type("dissector", check_for_dissector_plugin);
492 #endif /* HAVE_PLUGINS */
494 /* initialize data structures and register protocols and fields */
496 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
497 void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
499 gpointer client_data)
503 proto_names = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
504 proto_short_names = g_hash_table_new(wrs_str_hash, g_str_equal);
505 proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
508 gpa_hfinfo.allocated_len = 0;
509 gpa_hfinfo.hfi = NULL;
510 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
511 deregistered_fields = g_ptr_array_new();
512 deregistered_data = g_ptr_array_new();
514 /* Initialize the ftype subsystem */
517 /* Initialize the addres type subsystem */
518 address_types_initialize();
520 /* Register one special-case FT_TEXT_ONLY field for use when
521 converting wireshark to new-style proto_tree. These fields
522 are merely strings on the GUI tree; they are not filterable */
523 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
525 /* Register the pseudo-protocols used for exceptions. */
526 register_show_exception();
527 register_type_length_mismatch();
528 register_number_string_decoding_error();
530 /* Have each built-in dissector register its protocols, fields,
531 dissector tables, and dissectors to be called through a
532 handle, and do whatever one-time initialization it needs to
534 register_all_protocols_func(cb, client_data);
536 /* Now that the VINES dissector has registered it's address
537 type, grab the value for the field type */
538 vines_address_type = address_type_get_by_name("AT_VINES");
540 /* Now call the registration routines for all disssector
543 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
544 g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL);
547 /* Now call the "handoff registration" routines of all built-in
548 dissectors; those routines register the dissector in other
549 dissectors' handoff tables, and fetch any dissector handles
551 register_all_handoffs_func(cb, client_data);
554 /* Now do the same with plugins. */
556 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
557 g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL);
560 /* sort the protocols by protocol name */
561 protocols = g_list_sort(protocols, proto_compare_name);
563 /* We've assigned all the subtree type values; allocate the array
564 for them, and zero it out. */
565 tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
571 /* Free the abbrev/ID hash table */
573 g_hash_table_destroy(gpa_name_map);
576 g_free(last_field_name);
577 last_field_name = NULL;
580 protocol_t *protocol = (protocol_t *)protocols->data;
581 header_field_info *hfinfo;
582 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
583 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
585 g_slice_free(header_field_info, hfinfo);
586 if (protocol->fields) {
587 g_ptr_array_free(protocol->fields, TRUE);
589 g_list_free(protocol->heur_list);
590 protocols = g_list_remove(protocols, protocol);
595 g_hash_table_destroy(proto_names);
599 if (proto_short_names) {
600 g_hash_table_destroy(proto_short_names);
601 proto_short_names = NULL;
604 if (proto_filter_names) {
605 g_hash_table_destroy(proto_filter_names);
606 proto_filter_names = NULL;
609 if (gpa_hfinfo.allocated_len) {
611 gpa_hfinfo.allocated_len = 0;
612 g_free(gpa_hfinfo.hfi);
613 gpa_hfinfo.hfi = NULL;
616 if (deregistered_fields) {
617 g_ptr_array_free(deregistered_fields, FALSE);
618 deregistered_fields = NULL;
621 if (deregistered_data) {
622 g_ptr_array_free(deregistered_data, FALSE);
623 deregistered_data = NULL;
626 g_free(tree_is_expanded);
627 tree_is_expanded = NULL;
631 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
634 proto_node *pnode = tree;
638 if (func(pnode, data))
641 child = pnode->first_child;
642 while (child != NULL) {
644 * The routine we call might modify the child, e.g. by
645 * freeing it, so we get the child's successor before
646 * calling that routine.
649 child = current->next;
650 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
658 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
661 proto_node *pnode = tree;
665 child = pnode->first_child;
666 while (child != NULL) {
668 * The routine we call might modify the child, e.g. by
669 * freeing it, so we get the child's successor before
670 * calling that routine.
673 child = current->next;
674 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
677 if (func(pnode, data))
684 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
687 proto_node *node = tree;
693 node = node->first_child;
694 while (node != NULL) {
696 node = current->next;
697 func((proto_tree *)current, data);
702 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
704 GPtrArray *ptrs = (GPtrArray *)value;
705 gint hfid = GPOINTER_TO_UINT(key);
706 header_field_info *hfinfo;
708 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
709 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
710 /* when a field is referenced by a filter this also
711 affects the refcount for the parent protocol so we need
712 to adjust the refcount for the parent as well
714 if (hfinfo->parent != -1) {
715 header_field_info *parent_hfinfo;
716 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
717 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
719 hfinfo->ref_type = HF_REF_TYPE_NONE;
722 g_ptr_array_free(ptrs, TRUE);
726 proto_tree_free_node(proto_node *node, gpointer data _U_)
728 field_info *finfo = PNODE_FINFO(node);
730 proto_tree_children_foreach(node, proto_tree_free_node, NULL);
732 FVALUE_CLEANUP(&finfo->value);
736 proto_tree_reset(proto_tree *tree)
738 tree_data_t *tree_data = PTREE_DATA(tree);
740 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
743 if (tree_data->interesting_hfids) {
744 /* Free all the GPtrArray's in the interesting_hfids hash. */
745 g_hash_table_foreach(tree_data->interesting_hfids,
746 free_GPtrArray_value, NULL);
748 /* And then remove all values. */
749 g_hash_table_remove_all(tree_data->interesting_hfids);
752 /* Reset track of the number of children */
753 tree_data->count = 0;
755 PROTO_NODE_INIT(tree);
758 /* frees the resources that the dissection a proto_tree uses */
760 proto_tree_free(proto_tree *tree)
762 tree_data_t *tree_data = PTREE_DATA(tree);
764 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
767 if (tree_data->interesting_hfids) {
768 /* Free all the GPtrArray's in the interesting_hfids hash. */
769 g_hash_table_foreach(tree_data->interesting_hfids,
770 free_GPtrArray_value, NULL);
772 /* And then destroy the hash. */
773 g_hash_table_destroy(tree_data->interesting_hfids);
776 g_slice_free(tree_data_t, tree_data);
778 g_slice_free(proto_tree, tree);
781 /* Is the parsing being done for a visible proto_tree or an invisible one?
782 * By setting this correctly, the proto_tree creation is sped up by not
783 * having to call g_vsnprintf and copy strings around.
786 proto_tree_set_visible(proto_tree *tree, gboolean visible)
788 gboolean old_visible = PTREE_DATA(tree)->visible;
790 PTREE_DATA(tree)->visible = visible;
796 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
798 PTREE_DATA(tree)->fake_protocols = fake_protocols;
801 /* Assume dissector set only its protocol fields.
802 This function is called by dissectors and allows the speeding up of filtering
803 in wireshark; if this function returns FALSE it is safe to reset tree to NULL
804 and thus skip calling most of the expensive proto_tree_add_...()
806 If the tree is visible we implicitly assume the field is referenced.
809 proto_field_is_referenced(proto_tree *tree, int proto_id)
811 register header_field_info *hfinfo;
817 if (PTREE_DATA(tree)->visible)
820 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
821 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
824 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
831 /* Finds a record in the hfinfo array by id. */
833 proto_registrar_get_nth(guint hfindex)
835 register header_field_info *hfinfo;
837 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
842 /* Prefix initialization
843 * this allows for a dissector to register a display filter name prefix
844 * so that it can delay the initialization of the hf array as long as
848 /* compute a hash for the part before the dot of a display filter */
850 prefix_hash (gconstpointer key) {
851 /* end the string at the dot and compute its hash */
852 gchar* copy = g_strdup((const gchar *)key);
863 tmp = g_str_hash(copy);
868 /* are both strings equal up to the end or the dot? */
870 prefix_equal (gconstpointer ap, gconstpointer bp) {
871 const gchar* a = (const gchar *)ap;
872 const gchar* b = (const gchar *)bp;
878 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
880 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
881 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
883 if (ac != bc) return FALSE;
890 /* indexed by prefix, contains initializers */
891 static GHashTable* prefixes = NULL;
894 /* Register a new prefix for "delayed" initialization of field arrays */
896 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
898 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
901 g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
904 /* helper to call all prefix initializers */
906 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
907 ((prefix_initializer_t)v)((const char *)k);
911 /** Initialize every remaining uninitialized prefix. */
913 proto_initialize_all_prefixes(void) {
914 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
917 /* Finds a record in the hfinfo array by name.
918 * If it fails to find it in the already registered fields,
919 * it tries to find and call an initializer in the prefixes
920 * table and if so it looks again.
924 proto_registrar_get_byname(const char *field_name)
926 header_field_info *hfinfo;
927 prefix_initializer_t pi;
932 if (g_strcmp0(field_name, last_field_name) == 0) {
936 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
939 g_free(last_field_name);
940 last_field_name = g_strdup(field_name);
941 last_hfinfo = hfinfo;
948 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
950 g_hash_table_remove(prefixes, field_name);
955 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
958 g_free(last_field_name);
959 last_field_name = g_strdup(field_name);
960 last_hfinfo = hfinfo;
966 proto_registrar_get_id_byname(const char *field_name)
968 header_field_info *hfinfo;
970 hfinfo = proto_registrar_get_byname(field_name);
980 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
982 subtree_lvl *pushed_tree;
984 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
985 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
987 pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
988 DISSECTOR_ASSERT(pushed_tree != NULL);
989 if (ptvc->pushed_tree)
990 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
991 ptvc->pushed_tree = pushed_tree;
995 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
997 ptvc->pushed_tree = NULL;
998 ptvc->pushed_tree_max = 0;
999 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1000 ptvc->pushed_tree_index = 0;
1003 /* Allocates an initializes a ptvcursor_t with 3 variables:
1004 * proto_tree, tvbuff, and offset. */
1006 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
1010 ptvc = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
1013 ptvc->offset = offset;
1014 ptvc->pushed_tree = NULL;
1015 ptvc->pushed_tree_max = 0;
1016 ptvc->pushed_tree_index = 0;
1021 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1023 ptvcursor_free(ptvcursor_t *ptvc)
1025 ptvcursor_free_subtree_levels(ptvc);
1029 /* Returns tvbuff. */
1031 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1036 /* Returns current offset. */
1038 ptvcursor_current_offset(ptvcursor_t *ptvc)
1040 return ptvc->offset;
1044 ptvcursor_tree(ptvcursor_t *ptvc)
1053 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1058 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1060 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1062 subtree_lvl *subtree;
1063 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1064 ptvcursor_new_subtree_levels(ptvc);
1066 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1067 subtree->tree = ptvc->tree;
1069 ptvc->pushed_tree_index++;
1070 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1073 /* pops a subtree */
1075 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1077 subtree_lvl *subtree;
1079 if (ptvc->pushed_tree_index <= 0)
1082 ptvc->pushed_tree_index--;
1083 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1084 if (subtree->it != NULL)
1085 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1087 ptvc->tree = subtree->tree;
1090 /* saves the current tvb offset and the item in the current subtree level */
1092 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1094 subtree_lvl *subtree;
1096 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1098 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1100 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1103 /* Creates a subtree and adds it to the cursor as the working tree but does not
1104 * save the old working tree */
1106 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1108 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1113 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1115 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1116 if (length == SUBTREE_UNDEFINED_LENGTH)
1117 ptvcursor_subtree_set_item(ptvc, it);
1118 return ptvcursor_tree(ptvc);
1121 /* Add an item to the tree and create a subtree
1122 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1123 * In this case, when the subtree will be closed, the parent item length will
1124 * be equal to the advancement of the cursor since the creation of the subtree.
1127 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1128 const guint encoding, gint ett_subtree)
1132 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1133 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1137 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1139 /* Add a text node to the tree and create a subtree
1140 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1141 * In this case, when the subtree will be closed, the item length will be equal
1142 * to the advancement of the cursor since the creation of the subtree.
1145 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1146 gint ett_subtree, const char *format, ...)
1150 header_field_info *hfinfo;
1153 tree = ptvcursor_tree(ptvc);
1155 CHECK_FOR_NULL_TREE(tree);
1157 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1159 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1160 ptvcursor_current_offset(ptvc), length);
1162 TRY_TO_FAKE_THIS_REPR(pi);
1164 va_start(ap, format);
1165 proto_tree_set_representation(pi, format, ap);
1168 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1171 /* Add a text-only node, leaving it to our caller to fill the text in */
1173 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1180 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1185 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1187 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1188 const char *format, ...)
1192 header_field_info *hfinfo;
1195 /* If we're fetching until the end of the TVB, only validate
1196 * that the offset is within range.
1200 tvb_ensure_bytes_exist(tvb, start, length);
1202 CHECK_FOR_NULL_TREE(tree);
1204 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1206 pi = proto_tree_add_text_node(tree, tvb, start, length);
1208 TRY_TO_FAKE_THIS_REPR(pi);
1210 va_start(ap, format);
1211 proto_tree_set_representation(pi, format, ap);
1217 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1219 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1220 gint length, const char *format, va_list ap)
1223 header_field_info *hfinfo;
1226 /* If we're fetching until the end of the TVB, only validate
1227 * that the offset is within range.
1231 tvb_ensure_bytes_exist(tvb, start, length);
1233 CHECK_FOR_NULL_TREE(tree);
1235 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1237 pi = proto_tree_add_text_node(tree, tvb, start, length);
1239 TRY_TO_FAKE_THIS_REPR(pi);
1241 proto_tree_set_representation(pi, format, ap);
1246 /* Add a text-only node that creates a subtree underneath.
1249 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1251 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1254 /* Add a text-only node that creates a subtree underneath.
1257 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1263 va_start(ap, format);
1264 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1267 if (tree_item != NULL)
1270 pt = proto_item_add_subtree(pi, idx);
1275 /* Add a text-only node for debugging purposes. The caller doesn't need
1276 * to worry about tvbuff, start, or length. Debug message gets sent to
1279 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1284 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1287 va_start(ap, format);
1288 proto_tree_set_representation(pi, format, ap);
1291 va_start(ap, format);
1292 vprintf(format, ap);
1294 ws_debug_printf("\n");
1300 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1303 header_field_info *hfinfo;
1305 CHECK_FOR_NULL_TREE(tree);
1307 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1309 pi = proto_tree_add_text_node(tree, tvb, start, length);
1311 TRY_TO_FAKE_THIS_REPR(pi);
1313 proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1319 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1322 header_field_info *hfinfo;
1324 CHECK_FOR_NULL_TREE(tree);
1326 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1328 pi = proto_tree_add_text_node(tree, tvb, start, length);
1330 TRY_TO_FAKE_THIS_REPR(pi);
1332 proto_item_set_text(pi, "%s", tvb_format_text_wsp(tvb, start, length));
1337 void proto_report_dissector_bug(const char *message)
1339 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1342 THROW_MESSAGE(DissectorError, message);
1345 /* We could probably get away with changing is_error to a minimum length value. */
1347 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1350 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1352 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1356 THROW(ReportedBoundsError);
1361 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1364 gboolean length_error;
1369 value = tvb_get_guint8(tvb, offset);
1373 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1374 : tvb_get_ntohs(tvb, offset);
1378 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1379 : tvb_get_ntoh24(tvb, offset);
1383 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1384 : tvb_get_ntohl(tvb, offset);
1389 length_error = TRUE;
1392 length_error = FALSE;
1393 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1394 : tvb_get_ntohl(tvb, offset);
1396 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1402 static inline guint64
1403 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1406 gboolean length_error;
1411 value = tvb_get_guint8(tvb, offset);
1415 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1416 : tvb_get_ntohs(tvb, offset);
1420 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1421 : tvb_get_ntoh24(tvb, offset);
1425 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1426 : tvb_get_ntohl(tvb, offset);
1430 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1431 : tvb_get_ntoh40(tvb, offset);
1435 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1436 : tvb_get_ntoh48(tvb, offset);
1440 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1441 : tvb_get_ntoh56(tvb, offset);
1445 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1446 : tvb_get_ntoh64(tvb, offset);
1451 length_error = TRUE;
1454 length_error = FALSE;
1455 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1456 : tvb_get_ntoh64(tvb, offset);
1458 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1465 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1468 gboolean length_error;
1473 value = (gint8)tvb_get_guint8(tvb, offset);
1477 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1478 : tvb_get_ntohs(tvb, offset));
1482 value = encoding ? tvb_get_letoh24(tvb, offset)
1483 : tvb_get_ntoh24(tvb, offset);
1484 if (value & 0x00800000) {
1485 /* Sign bit is set; sign-extend it. */
1486 value |= 0xFF000000;
1491 value = encoding ? tvb_get_letohl(tvb, offset)
1492 : tvb_get_ntohl(tvb, offset);
1497 length_error = TRUE;
1500 length_error = FALSE;
1501 value = encoding ? tvb_get_letohl(tvb, offset)
1502 : tvb_get_ntohl(tvb, offset);
1504 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1510 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1511 * be cast-able as a gint64. This is weird, but what the code has always done.
1513 static inline guint64
1514 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1516 guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1521 value = ws_sign_ext64(value, 56);
1524 value = ws_sign_ext64(value, 48);
1527 value = ws_sign_ext64(value, 40);
1530 value = ws_sign_ext64(value, 32);
1533 value = ws_sign_ext64(value, 24);
1536 value = ws_sign_ext64(value, 16);
1539 value = ws_sign_ext64(value, 8);
1547 static inline const guint8 *
1548 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1549 gint length, gint *ret_length, const guint encoding)
1552 length = tvb_ensure_captured_length_remaining(tvb, start);
1554 *ret_length = length;
1555 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1558 /* For FT_STRINGZ */
1559 static inline const guint8 *
1560 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1561 gint start, gint length, gint *ret_length, const guint encoding)
1563 const guint8 *value;
1566 report_type_length_mismatch(tree, "a string", length, TRUE);
1569 /* This can throw an exception */
1570 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1571 } else if (length == 0) {
1574 /* In this case, length signifies the length of the string.
1576 * This could either be a null-padded string, which doesn't
1577 * necessarily have a '\0' at the end, or a null-terminated
1578 * string, with a trailing '\0'. (Yes, there are cases
1579 * where you have a string that's both counted and null-
1582 * In the first case, we must allocate a buffer of length
1583 * "length+1", to make room for a trailing '\0'.
1585 * In the second case, we don't assume that there is a
1586 * trailing '\0' there, as the packet might be malformed.
1587 * (XXX - should we throw an exception if there's no
1588 * trailing '\0'?) Therefore, we allocate a buffer of
1589 * length "length+1", and put in a trailing '\0', just to
1592 * (XXX - this would change if we made string values counted
1593 * rather than null-terminated.)
1595 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1597 *ret_length = length;
1601 /* For FT_UINT_STRING */
1602 static inline const guint8 *
1603 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1604 tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1605 const guint encoding)
1608 const guint8 *value;
1610 /* I believe it's ok if this is called with a NULL tree */
1611 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1612 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1614 *ret_length = length;
1618 /* For FT_STRINGZPAD */
1619 static inline const guint8 *
1620 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1621 gint length, gint *ret_length, const guint encoding)
1624 * XXX - currently, string values are null-
1625 * terminated, so a "zero-padded" string
1626 * isn't special. If we represent string
1627 * values as something that includes a counted
1628 * array of bytes, we'll need to strip
1632 length = tvb_ensure_captured_length_remaining(tvb, start);
1634 *ret_length = length;
1635 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1638 /* this can be called when there is no tree, so don't add that as a param */
1640 get_time_value(tvbuff_t *tvb, const gint start, const gint length, const guint encoding,
1641 nstime_t *time_stamp, const gboolean is_relative)
1646 /* relative timestamps don't do TOD/NTP */
1648 (encoding != (ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN)) &&
1649 (encoding != (ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN)) )
1651 /* XXX: I think this should call REPORT_DISSECTOR_BUG(), but
1652 the existing code didn't do that, so I'm not either */
1658 case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1660 * 4-byte UNIX epoch, possibly followed by
1661 * 4-byte fractional time in nanoseconds,
1664 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1666 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1668 time_stamp->nsecs = 0;
1671 case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1673 * 4-byte UNIX epoch, possibly followed by
1674 * 4-byte fractional time in nanoseconds,
1675 * both little-endian.
1677 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1679 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1681 time_stamp->nsecs = 0;
1684 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1686 * TOD time stamp, big-endian.
1688 /* XXX - where should this go? */
1689 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800)
1691 todsecs = tvb_get_ntoh64(tvb, start) >> 12;
1692 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1693 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1696 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1698 * TOD time stamp, big-endian.
1700 todsecs = tvb_get_letoh64(tvb, start) >> 12 ;
1701 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1702 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1705 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1707 * NTP time stamp, big-endian.
1710 /* XXX - where should this go? */
1711 #define NTP_BASETIME G_GUINT64_CONSTANT(2208988800)
1713 /* We need a temporary variable here so the unsigned math
1714 * works correctly (for years > 2036 according to RFC 2030
1717 tmpsecs = tvb_get_ntohl(tvb, start);
1719 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1721 time_stamp->secs = tmpsecs; /* 0 */
1725 * We're using nanoseconds here (and we will
1726 * display nanoseconds), but NTP's timestamps
1727 * have a precision in microseconds or greater.
1728 * Round to 1 microsecond.
1730 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1731 time_stamp->nsecs *= 1000;
1733 time_stamp->nsecs = 0;
1737 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1739 * NTP time stamp, big-endian.
1741 tmpsecs = tvb_get_letohl(tvb, start);
1743 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1745 time_stamp->secs = tmpsecs; /* 0 */
1749 * We're using nanoseconds here (and we will
1750 * display nanoseconds), but NTP's timestamps
1751 * have a precision in microseconds or greater.
1752 * Round to 1 microsecond.
1754 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1755 time_stamp->nsecs *= 1000;
1757 time_stamp->nsecs = 0;
1760 case ENC_TIME_NTP_BASE_ZERO|ENC_BIG_ENDIAN:
1762 * DDS NTP time stamp, big-endian.
1765 #define NTP_BASETIME_ZERO G_GUINT64_CONSTANT(0)
1767 tmpsecs = tvb_get_ntohl(tvb, start);
1769 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1771 time_stamp->secs = tmpsecs; /* 0 */
1775 * We're using nanoseconds here (and we will
1776 * display nanoseconds), but NTP's timestamps
1777 * have a precision in microseconds or greater.
1778 * Round to 1 microsecond.
1780 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1781 time_stamp->nsecs *= 1000;
1783 time_stamp->nsecs = 0;
1787 case ENC_TIME_NTP_BASE_ZERO|ENC_LITTLE_ENDIAN:
1789 * NTP time stamp, big-endian.
1791 tmpsecs = tvb_get_letohl(tvb, start);
1793 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1795 time_stamp->secs = tmpsecs; /* 0 */
1796 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1799 * We're using nanoseconds here (and we will
1800 * display nanoseconds), but NTP's timestamps
1801 * have a precision in microseconds or greater.
1802 * Round to 1 microsecond.
1804 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1805 time_stamp->nsecs *= 1000;
1807 time_stamp->nsecs = 0;
1812 DISSECTOR_ASSERT_NOT_REACHED();
1818 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
1820 const header_field_info *hfinfo = fi->hfinfo;
1822 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
1823 GPtrArray *ptrs = NULL;
1825 if (tree_data->interesting_hfids == NULL) {
1826 /* Initialize the hash because we now know that it is needed */
1827 tree_data->interesting_hfids =
1828 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
1829 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
1830 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
1831 GINT_TO_POINTER(hfinfo->id));
1835 /* First element triggers the creation of pointer array */
1836 ptrs = g_ptr_array_new();
1837 g_hash_table_insert(tree_data->interesting_hfids,
1838 GINT_TO_POINTER(hfinfo->id), ptrs);
1841 g_ptr_array_add(ptrs, fi);
1845 /* Add an item to a proto_tree, using the text label registered to that item;
1846 the item is extracted from the tvbuff handed to it. */
1848 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
1849 tvbuff_t *tvb, gint start, gint length,
1856 const char *stringval;
1857 nstime_t time_stamp;
1858 gboolean length_error;
1860 switch (new_fi->hfinfo->type) {
1862 /* no value to set for FT_NONE */
1866 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
1870 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
1875 * Map all non-zero values to little-endian for
1876 * backwards compatibility.
1879 encoding = ENC_LITTLE_ENDIAN;
1880 n = get_uint_value(tree, tvb, start, length, encoding);
1881 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
1883 /* Instead of calling proto_item_set_len(), since we don't yet
1884 * have a proto_item, we set the field_info's length ourselves. */
1885 new_fi->length = n + length;
1890 * Map all non-zero values to little-endian for
1891 * backwards compatibility.
1894 encoding = ENC_LITTLE_ENDIAN;
1895 proto_tree_set_boolean(new_fi,
1896 get_uint64_value(tree, tvb, start, length, encoding));
1900 /* XXX - make these just FT_UINT? */
1906 * Map all non-zero values to little-endian for
1907 * backwards compatibility.
1910 encoding = ENC_LITTLE_ENDIAN;
1911 proto_tree_set_uint(new_fi,
1912 get_uint_value(tree, tvb, start, length, encoding));
1920 * Map all non-zero values to little-endian for
1921 * backwards compatibility.
1924 encoding = ENC_LITTLE_ENDIAN;
1925 proto_tree_set_uint64(new_fi,
1926 get_uint64_value(tree, tvb, start, length, encoding));
1929 /* XXX - make these just FT_INT? */
1935 * Map all non-zero values to little-endian for
1936 * backwards compatibility.
1939 encoding = ENC_LITTLE_ENDIAN;
1940 proto_tree_set_int(new_fi,
1941 get_int_value(tree, tvb, start, length, encoding));
1949 * Map all non-zero values to little-endian for
1950 * backwards compatibility.
1953 encoding = ENC_LITTLE_ENDIAN;
1954 proto_tree_set_int64(new_fi,
1955 get_int64_value(tree, tvb, start, length, encoding));
1960 * Map all non-zero values to little-endian for
1961 * backwards compatibility.
1964 encoding = ENC_LITTLE_ENDIAN;
1965 if (length != FT_IPv4_LEN) {
1966 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
1967 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
1969 value = tvb_get_ipv4(tvb, start);
1971 * NOTE: to support code written when
1972 * proto_tree_add_item() took a gboolean as its
1973 * last argument, with FALSE meaning "big-endian"
1974 * and TRUE meaning "little-endian", we treat any
1975 * non-zero value of "encoding" as meaning
1978 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
1982 if (length != FT_IPXNET_LEN) {
1983 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
1984 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
1986 proto_tree_set_ipxnet(new_fi,
1987 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
1991 if (length != FT_IPv6_LEN) {
1992 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
1993 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
1995 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
1999 if (length != FT_FCWWN_LEN) {
2000 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2001 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2003 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2008 length_error = length < 7 ? TRUE : FALSE;
2009 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2011 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2015 if (length != VINES_ADDR_LEN) {
2016 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2017 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2019 proto_tree_set_vines_tvb(new_fi, tvb, start);
2023 if (length != FT_ETHER_LEN) {
2024 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2025 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2027 proto_tree_set_ether_tvb(new_fi, tvb, start);
2032 * Map all non-zero values to little-endian for
2033 * backwards compatibility.
2036 encoding = ENC_LITTLE_ENDIAN;
2037 if (length != FT_EUI64_LEN) {
2038 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2039 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2041 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2045 * Map all non-zero values to little-endian for
2046 * backwards compatibility.
2049 encoding = ENC_LITTLE_ENDIAN;
2050 if (length != FT_GUID_LEN) {
2051 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2052 report_type_length_mismatch(tree, "a GUID", length, length_error);
2054 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2059 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2063 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2068 * NOTE: to support code written when
2069 * proto_tree_add_item() took a gboolean as its
2070 * last argument, with FALSE meaning "big-endian"
2071 * and TRUE meaning "little-endian", we treat any
2072 * non-zero value of "encoding" as meaning
2075 * At some point in the future, we might
2076 * support non-IEEE-binary floating-point
2077 * formats in the encoding as well
2078 * (IEEE decimal, System/3x0, VAX).
2081 encoding = ENC_LITTLE_ENDIAN;
2083 length_error = length < 4 ? TRUE : FALSE;
2084 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2087 floatval = tvb_get_letohieee_float(tvb, start);
2089 floatval = tvb_get_ntohieee_float(tvb, start);
2090 proto_tree_set_float(new_fi, floatval);
2095 * NOTE: to support code written when
2096 * proto_tree_add_item() took a gboolean as its
2097 * last argument, with FALSE meaning "big-endian"
2098 * and TRUE meaning "little-endian", we treat any
2099 * non-zero value of "encoding" as meaning
2102 * At some point in the future, we might
2103 * support non-IEEE-binary floating-point
2104 * formats in the encoding as well
2105 * (IEEE decimal, System/3x0, VAX).
2107 if (encoding == TRUE)
2108 encoding = ENC_LITTLE_ENDIAN;
2110 length_error = length < 8 ? TRUE : FALSE;
2111 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2114 doubleval = tvb_get_letohieee_double(tvb, start);
2116 doubleval = tvb_get_ntohieee_double(tvb, start);
2117 proto_tree_set_double(new_fi, doubleval);
2121 stringval = get_string_value(wmem_packet_scope(),
2122 tvb, start, length, &length, encoding);
2123 proto_tree_set_string(new_fi, stringval);
2125 /* Instead of calling proto_item_set_len(), since we
2126 * don't yet have a proto_item, we set the
2127 * field_info's length ourselves.
2129 * XXX - our caller can't use that length to
2130 * advance an offset unless they arrange that
2131 * there always be a protocol tree into which
2132 * we're putting this item.
2134 new_fi->length = length;
2138 stringval = get_stringz_value(wmem_packet_scope(),
2139 tree, tvb, start, length, &length, encoding);
2140 proto_tree_set_string(new_fi, stringval);
2142 /* Instead of calling proto_item_set_len(),
2143 * since we don't yet have a proto_item, we
2144 * set the field_info's length ourselves.
2146 * XXX - our caller can't use that length to
2147 * advance an offset unless they arrange that
2148 * there always be a protocol tree into which
2149 * we're putting this item.
2151 new_fi->length = length;
2154 case FT_UINT_STRING:
2156 * NOTE: to support code written when
2157 * proto_tree_add_item() took a gboolean as its
2158 * last argument, with FALSE meaning "big-endian"
2159 * and TRUE meaning "little-endian", if the
2160 * encoding value is TRUE, treat that as
2161 * ASCII with a little-endian length.
2163 * This won't work for code that passes
2164 * arbitrary non-zero values; that code
2165 * will need to be fixed.
2167 if (encoding == TRUE)
2168 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2169 stringval = get_uint_string_value(wmem_packet_scope(),
2170 tree, tvb, start, length, &length, encoding);
2171 proto_tree_set_string(new_fi, stringval);
2173 /* Instead of calling proto_item_set_len(), since we
2174 * don't yet have a proto_item, we set the
2175 * field_info's length ourselves.
2177 * XXX - our caller can't use that length to
2178 * advance an offset unless they arrange that
2179 * there always be a protocol tree into which
2180 * we're putting this item.
2182 new_fi->length = length;
2186 stringval = get_stringzpad_value(wmem_packet_scope(),
2187 tvb, start, length, &length, encoding);
2188 proto_tree_set_string(new_fi, stringval);
2190 /* Instead of calling proto_item_set_len(), since we
2191 * don't yet have a proto_item, we set the
2192 * field_info's length ourselves.
2194 * XXX - our caller can't use that length to
2195 * advance an offset unless they arrange that
2196 * there always be a protocol tree into which
2197 * we're putting this item.
2199 new_fi->length = length;
2202 case FT_ABSOLUTE_TIME:
2204 * Absolute times can be in any of a number of
2205 * formats, and they can be big-endian or
2208 * Historically FT_TIMEs were only timespecs;
2209 * the only question was whether they were stored
2210 * in big- or little-endian format.
2212 * For backwards compatibility, we interpret an
2213 * encoding of 1 as meaning "little-endian timespec",
2214 * so that passing TRUE is interpreted as that.
2216 if (encoding == TRUE)
2217 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2219 if (length != 8 && length != 4) {
2220 length_error = length < 4 ? TRUE : FALSE;
2221 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2224 get_time_value(tvb, start, length, encoding, &time_stamp, FALSE);
2226 proto_tree_set_time(new_fi, &time_stamp);
2229 case FT_RELATIVE_TIME:
2231 * Relative times can be in any of a number of
2232 * formats, and they can be big-endian or
2235 * Historically FT_TIMEs were only timespecs;
2236 * the only question was whether they were stored
2237 * in big- or little-endian format.
2239 * For backwards compatibility, we interpret an
2240 * encoding of 1 as meaning "little-endian timespec",
2241 * so that passing TRUE is interpreted as that.
2243 if (encoding == TRUE)
2244 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2246 if (length != 8 && length != 4) {
2247 length_error = length < 4 ? TRUE : FALSE;
2248 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2251 get_time_value(tvb, start, length, encoding, &time_stamp, TRUE);
2253 proto_tree_set_time(new_fi, &time_stamp);
2255 case FT_IEEE_11073_SFLOAT:
2257 encoding = ENC_LITTLE_ENDIAN;
2259 length_error = length < 2 ? TRUE : FALSE;
2260 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2263 fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2266 case FT_IEEE_11073_FLOAT:
2268 encoding = ENC_LITTLE_ENDIAN;
2270 length_error = length < 4 ? TRUE : FALSE;
2271 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2276 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2277 new_fi->hfinfo->type,
2278 ftype_name(new_fi->hfinfo->type));
2279 DISSECTOR_ASSERT_NOT_REACHED();
2282 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2284 /* Don't add new node to proto_tree until now so that any exceptions
2285 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2286 /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2287 * to know which item caused exception? */
2288 pi = proto_tree_add_node(tree, new_fi);
2294 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2295 const gint start, gint length,
2296 const guint encoding, gint32 *retval)
2298 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2302 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2304 switch (hfinfo->type){
2311 DISSECTOR_ASSERT_NOT_REACHED();
2314 /* length validation for native number encoding caught by get_uint_value() */
2315 /* length has to be -1 or > 0 regardless of encoding */
2316 if (length < -1 || length == 0)
2317 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2318 "Invalid length %d passed to proto_tree_add_item_ret_int",
2321 if (encoding & ENC_STRING) {
2322 REPORT_DISSECTOR_BUG("wrong encoding");
2324 /* I believe it's ok if this is called with a NULL tree */
2325 value = get_int_value(tree, tvb, start, length, encoding);
2330 if (hfinfo->bitmask) {
2331 /* Mask out irrelevant portions */
2332 *retval &= (guint32)(hfinfo->bitmask);
2334 *retval >>= hfinfo_bitshift(hfinfo);
2336 no_of_bits = ws_count_ones(hfinfo->bitmask);
2337 *retval = ws_sign_ext32(*retval, no_of_bits);
2340 CHECK_FOR_NULL_TREE(tree);
2342 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2344 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2346 proto_tree_set_int(new_fi, value);
2348 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2350 return proto_tree_add_node(tree, new_fi);
2354 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2355 const gint start, gint length,
2356 const guint encoding, guint32 *retval)
2358 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2362 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2364 switch (hfinfo->type){
2372 DISSECTOR_ASSERT_NOT_REACHED();
2375 /* length validation for native number encoding caught by get_uint_value() */
2376 /* length has to be -1 or > 0 regardless of encoding */
2377 if (length < -1 || length == 0)
2378 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2379 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2382 if (encoding & ENC_STRING) {
2383 REPORT_DISSECTOR_BUG("wrong encoding");
2385 /* I believe it's ok if this is called with a NULL tree */
2386 /* XXX - modify if we ever support EBCDIC FT_CHAR */
2387 value = get_uint_value(tree, tvb, start, length, encoding);
2391 if (hfinfo->bitmask) {
2392 /* Mask out irrelevant portions */
2393 *retval &= (guint32)(hfinfo->bitmask);
2395 *retval >>= hfinfo_bitshift(hfinfo);
2399 CHECK_FOR_NULL_TREE(tree);
2401 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2403 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2405 proto_tree_set_uint(new_fi, value);
2407 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2409 return proto_tree_add_node(tree, new_fi);
2413 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
2415 const gint start, gint length,
2416 const guint encoding,
2417 wmem_allocator_t *scope,
2418 const guint8 **retval,
2421 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2423 const guint8 *value;
2425 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2427 switch (hfinfo->type){
2429 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
2432 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
2434 case FT_UINT_STRING:
2435 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
2438 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
2441 DISSECTOR_ASSERT_NOT_REACHED();
2447 CHECK_FOR_NULL_TREE(tree);
2449 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2451 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
2453 proto_tree_set_string(new_fi, value);
2455 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2457 return proto_tree_add_node(tree, new_fi);
2461 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2462 const gint start, gint length,
2463 const guint encoding, wmem_allocator_t *scope,
2464 const guint8 **retval)
2466 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
2467 tvb, start, length, encoding, scope, retval, &length);
2471 * Validates that field length bytes are available starting from
2472 * start (pos/neg). Throws an exception if they aren't.
2475 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2476 gint start, gint length)
2483 if (hfinfo->type == FT_STRINGZ) {
2484 /* If we're fetching until the end of the TVB, only validate
2485 * that the offset is within range.
2491 tvb_ensure_bytes_exist(tvb, start, size);
2494 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2495 and returns proto_item* */
2497 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
2498 const guint encoding)
2501 header_field_info *hfinfo;
2505 offset = ptvc->offset;
2506 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2507 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
2508 test_length(hfinfo, ptvc->tvb, offset, item_length);
2510 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2511 item_length, encoding);
2513 CHECK_FOR_NULL_TREE(ptvc->tree);
2515 /* Coast clear. Try and fake it */
2516 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2518 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2520 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2521 offset, length, encoding);
2524 /* Add an item to a proto_tree, using the text label registered to that item;
2525 the item is extracted from the tvbuff handed to it. */
2527 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
2528 const gint start, gint length, const guint encoding)
2533 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2535 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2536 test_length(hfinfo, tvb, start, item_length);
2538 CHECK_FOR_NULL_TREE(tree);
2540 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2542 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2544 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2548 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2549 const gint start, gint length, const guint encoding)
2551 register header_field_info *hfinfo;
2553 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2554 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
2557 /* Add an item to a proto_tree, using the text label registered to that item;
2558 the item is extracted from the tvbuff handed to it.
2560 Return the length of the item through the pointer. */
2562 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
2563 tvbuff_t *tvb, const gint start,
2564 gint length, const guint encoding,
2571 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2573 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2574 test_length(hfinfo, tvb, start, item_length);
2578 * We need to get the correct item length here.
2579 * That's normally done by proto_tree_new_item(),
2580 * but we won't be calling it.
2582 *lenretval = get_full_length(hfinfo, tvb, start, length,
2583 item_length, encoding);
2587 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2589 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2591 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2592 *lenretval = new_fi->length;
2597 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2598 const gint start, gint length,
2599 const guint encoding, gint *lenretval)
2601 register header_field_info *hfinfo;
2603 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2604 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
2607 /* which FT_ types can use proto_tree_add_bytes_item() */
2608 static inline gboolean
2609 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
2611 return (type == FT_BYTES ||
2612 type == FT_UINT_BYTES ||
2614 type == FT_REL_OID ||
2615 type == FT_SYSTEM_ID );
2618 /* Note: this does no validation that the byte array of an FT_OID or
2619 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
2620 so I think it's ok to continue not validating it?
2623 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2624 const gint start, gint length, const guint encoding,
2625 GByteArray *retval, gint *endoff, gint *err)
2628 GByteArray *bytes = retval;
2629 GByteArray *created_bytes = NULL;
2632 header_field_info *hfinfo;
2633 gboolean generate = (bytes || tree) ? TRUE : FALSE;
2635 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2637 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2639 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
2640 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
2642 /* length has to be -1 or > 0 regardless of encoding */
2643 /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
2644 if (length < -1 || length == 0) {
2645 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2646 "Invalid length %d passed to proto_tree_add_bytes_item for %s",
2647 length, ftype_name(hfinfo->type)));
2650 if (encoding & ENC_STR_NUM) {
2651 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
2654 if (generate && (encoding & ENC_STR_HEX)) {
2655 if (hfinfo->type == FT_UINT_BYTES) {
2656 /* can't decode FT_UINT_BYTES from strings */
2657 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
2658 "FT_UINT_BYTES type, but as ENC_STR_HEX");
2662 /* caller doesn't care about return value, but we need it to
2663 call tvb_get_string_bytes() and set the tree later */
2664 bytes = created_bytes = g_byte_array_new();
2667 /* bytes might be NULL after this, but can't add expert error until later */
2668 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
2670 /* grab the errno now before it gets overwritten */
2673 else if (generate) {
2674 tvb_ensure_bytes_exist(tvb, start, length);
2677 /* caller doesn't care about return value, but we need it to
2678 call tvb_get_string_bytes() and set the tree later */
2679 bytes = created_bytes = g_byte_array_new();
2682 if (hfinfo->type == FT_UINT_BYTES) {
2683 n = length; /* n is now the "header" length */
2684 length = get_uint_value(tree, tvb, start, n, encoding);
2685 /* length is now the value's length; only store the value in the array */
2686 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
2688 else if (length > 0) {
2689 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
2693 *endoff = start + n + length;
2696 if (err) *err = saved_err;
2698 CHECK_FOR_NULL_TREE_AND_FREE(tree,
2701 g_byte_array_free(created_bytes, TRUE);
2702 created_bytes = NULL;
2706 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
2709 g_byte_array_free(created_bytes, TRUE);
2710 created_bytes = NULL;
2714 /* n will be zero except when it's a FT_UINT_BYTES */
2715 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
2717 if (encoding & ENC_STRING) {
2718 if (saved_err == ERANGE)
2719 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2720 else if (!bytes || saved_err != 0)
2721 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2724 proto_tree_set_bytes_gbytearray(new_fi, bytes);
2726 proto_tree_set_bytes(new_fi, NULL, 0);
2729 g_byte_array_free(created_bytes, TRUE);
2732 /* n will be zero except when it's a FT_UINT_BYTES */
2733 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
2736 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2739 return proto_tree_add_node(tree, new_fi);
2744 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2745 const gint start, gint length, const guint encoding,
2746 nstime_t *retval, gint *endoff, gint *err)
2749 nstime_t time_stamp;
2751 header_field_info *hfinfo;
2753 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2755 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2757 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
2759 /* length has to be -1 or > 0 regardless of encoding */
2760 if (length < -1 || length == 0) {
2761 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2762 "Invalid length %d passed to proto_tree_add_time_item", length));
2765 time_stamp.secs = 0;
2766 time_stamp.nsecs = 0;
2768 if (encoding & ENC_STR_TIME_MASK) {
2769 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
2770 /* grab the errno now before it gets overwritten */
2774 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
2776 if (length != 8 && length != 4) {
2777 const gboolean length_error = length < 4 ? TRUE : FALSE;
2779 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2781 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2784 tvb_ensure_bytes_exist(tvb, start, length);
2785 get_time_value(tvb, start, length, encoding, &time_stamp, is_relative);
2786 if (endoff) *endoff = length;
2789 if (err) *err = saved_err;
2792 retval->secs = time_stamp.secs;
2793 retval->nsecs = time_stamp.nsecs;
2796 CHECK_FOR_NULL_TREE(tree);
2798 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2800 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2802 proto_tree_set_time(new_fi, &time_stamp);
2804 if (encoding & ENC_STRING) {
2805 if (saved_err == ERANGE)
2806 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2807 else if (saved_err == EDOM)
2808 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2812 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2815 return proto_tree_add_node(tree, new_fi);
2818 /* Add a FT_NONE to a proto_tree */
2820 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
2821 const gint start, gint length, const char *format,
2826 header_field_info *hfinfo;
2828 CHECK_FOR_NULL_TREE(tree);
2830 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2832 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
2834 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2836 TRY_TO_FAKE_THIS_REPR(pi);
2838 va_start(ap, format);
2839 proto_tree_set_representation(pi, format, ap);
2842 /* no value to set for FT_NONE */
2846 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
2847 * offset, and returns proto_item* */
2849 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
2850 const guint encoding)
2854 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
2860 /* Advance the ptvcursor's offset within its tvbuff without
2861 * adding anything to the proto_tree. */
2863 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
2865 ptvc->offset += length;
2870 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
2872 fvalue_set_protocol(&fi->value, tvb, field_data);
2875 /* Add a FT_PROTOCOL to a proto_tree */
2877 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2878 gint start, gint length, const char *format, ...)
2882 header_field_info *hfinfo;
2883 gchar* protocol_rep;
2885 CHECK_FOR_NULL_TREE(tree);
2887 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2889 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
2891 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2893 va_start(ap, format);
2894 protocol_rep = g_strdup_vprintf(format, ap);
2895 proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length)), protocol_rep);
2896 g_free(protocol_rep);
2899 TRY_TO_FAKE_THIS_REPR(pi);
2901 va_start(ap, format);
2902 proto_tree_set_representation(pi, format, ap);
2908 /* Add a FT_BYTES to a proto_tree */
2910 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2911 gint length, const guint8 *start_ptr)
2914 header_field_info *hfinfo;
2917 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2918 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2919 test_length(hfinfo, tvb, start, item_length);
2921 CHECK_FOR_NULL_TREE(tree);
2923 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2925 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2927 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2928 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
2933 /* Add a FT_BYTES to a proto_tree */
2935 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2936 gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
2939 header_field_info *hfinfo;
2942 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2943 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length);
2944 test_length(hfinfo, tvb, start, item_length);
2946 CHECK_FOR_NULL_TREE(tree);
2948 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2950 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2952 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
2953 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
2959 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2960 gint start, gint length,
2961 const guint8 *start_ptr,
2962 const char *format, ...)
2966 header_field_info *hfinfo;
2969 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2970 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2971 test_length(hfinfo, tvb, start, item_length);
2973 CHECK_FOR_NULL_TREE(tree);
2975 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2978 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2981 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2982 tvb_get_ptr(tvb, start, length));
2984 va_start(ap, format);
2985 proto_tree_set_representation_value(pi, format, ap);
2992 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2993 gint start, gint length, const guint8 *start_ptr,
2994 const char *format, ...)
2998 header_field_info *hfinfo;
3001 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3002 get_hfi_length(hfinfo, tvb, start, &length, &item_length);
3003 test_length(hfinfo, tvb, start, item_length);
3005 CHECK_FOR_NULL_TREE(tree);
3007 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3010 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
3013 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
3014 tvb_get_ptr(tvb, start, length));
3016 TRY_TO_FAKE_THIS_REPR(pi);
3018 va_start(ap, format);
3019 proto_tree_set_representation(pi, format, ap);
3026 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
3030 DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
3032 bytes = g_byte_array_new();
3034 g_byte_array_append(bytes, start_ptr, length);
3036 fvalue_set_byte_array(&fi->value, bytes);
3041 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
3043 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
3047 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
3051 DISSECTOR_ASSERT(value != NULL);
3053 bytes = byte_array_dup(value);
3055 fvalue_set_byte_array(&fi->value, bytes);
3058 /* Add a FT_*TIME to a proto_tree */
3060 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3061 gint length, const nstime_t *value_ptr)
3064 header_field_info *hfinfo;
3066 CHECK_FOR_NULL_TREE(tree);
3068 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3070 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3072 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3073 proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
3079 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3080 gint start, gint length, nstime_t *value_ptr,
3081 const char *format, ...)
3086 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3088 va_start(ap, format);
3089 proto_tree_set_representation_value(pi, format, ap);
3097 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3098 gint start, gint length, nstime_t *value_ptr,
3099 const char *format, ...)
3104 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3106 TRY_TO_FAKE_THIS_REPR(pi);
3108 va_start(ap, format);
3109 proto_tree_set_representation(pi, format, ap);
3116 /* Set the FT_*TIME value */
3118 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
3120 DISSECTOR_ASSERT(value_ptr != NULL);
3122 fvalue_set_time(&fi->value, value_ptr);
3125 /* Add a FT_IPXNET to a proto_tree */
3127 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3128 gint length, guint32 value)
3131 header_field_info *hfinfo;
3133 CHECK_FOR_NULL_TREE(tree);
3135 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3137 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
3139 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3140 proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
3146 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3147 gint start, gint length, guint32 value,
3148 const char *format, ...)
3153 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3155 va_start(ap, format);
3156 proto_tree_set_representation_value(pi, format, ap);
3164 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3165 gint start, gint length, guint32 value,
3166 const char *format, ...)
3171 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3173 TRY_TO_FAKE_THIS_REPR(pi);
3175 va_start(ap, format);
3176 proto_tree_set_representation(pi, format, ap);
3183 /* Set the FT_IPXNET value */
3185 proto_tree_set_ipxnet(field_info *fi, guint32 value)
3187 fvalue_set_uinteger(&fi->value, value);
3190 /* Add a FT_IPv4 to a proto_tree */
3192 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3193 gint length, guint32 value)
3196 header_field_info *hfinfo;
3198 CHECK_FOR_NULL_TREE(tree);
3200 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3202 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
3204 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3205 proto_tree_set_ipv4(PNODE_FINFO(pi), value);
3211 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3212 gint start, gint length, guint32 value,
3213 const char *format, ...)
3218 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3220 va_start(ap, format);
3221 proto_tree_set_representation_value(pi, format, ap);
3229 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3230 gint start, gint length, guint32 value,
3231 const char *format, ...)
3236 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3238 TRY_TO_FAKE_THIS_REPR(pi);
3240 va_start(ap, format);
3241 proto_tree_set_representation(pi, format, ap);
3248 /* Set the FT_IPv4 value */
3250 proto_tree_set_ipv4(field_info *fi, guint32 value)
3252 fvalue_set_uinteger(&fi->value, value);
3255 /* Add a FT_IPv6 to a proto_tree */
3257 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3258 gint length, const struct e_in6_addr *value_ptr)
3261 header_field_info *hfinfo;
3263 CHECK_FOR_NULL_TREE(tree);
3265 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3267 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
3269 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3270 proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
3276 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3277 gint start, gint length,
3278 const struct e_in6_addr *value_ptr,
3279 const char *format, ...)
3284 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3286 va_start(ap, format);
3287 proto_tree_set_representation_value(pi, format, ap);
3295 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3296 gint start, gint length,
3297 const struct e_in6_addr *value_ptr,
3298 const char *format, ...)
3303 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3305 TRY_TO_FAKE_THIS_REPR(pi);
3307 va_start(ap, format);
3308 proto_tree_set_representation(pi, format, ap);
3315 /* Set the FT_IPv6 value */
3317 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
3319 DISSECTOR_ASSERT(value_ptr != NULL);
3320 fvalue_set_bytes(&fi->value, value_ptr);
3324 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3326 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
3329 /* Set the FT_FCWWN value */
3331 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
3333 DISSECTOR_ASSERT(value_ptr != NULL);
3334 fvalue_set_bytes(&fi->value, value_ptr);
3338 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3340 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
3343 /* Add a FT_GUID to a proto_tree */
3345 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3346 gint length, const e_guid_t *value_ptr)
3349 header_field_info *hfinfo;
3351 CHECK_FOR_NULL_TREE(tree);
3353 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3355 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
3357 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3358 proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
3364 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3365 gint start, gint length,
3366 const e_guid_t *value_ptr,
3367 const char *format, ...)
3372 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3374 va_start(ap, format);
3375 proto_tree_set_representation_value(pi, format, ap);
3383 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3384 gint start, gint length, const e_guid_t *value_ptr,
3385 const char *format, ...)
3390 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3392 TRY_TO_FAKE_THIS_REPR(pi);
3394 va_start(ap, format);
3395 proto_tree_set_representation(pi, format, ap);
3402 /* Set the FT_GUID value */
3404 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
3406 DISSECTOR_ASSERT(value_ptr != NULL);
3407 fvalue_set_guid(&fi->value, value_ptr);
3411 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
3412 const guint encoding)
3416 tvb_get_guid(tvb, start, &guid, encoding);
3417 proto_tree_set_guid(fi, &guid);
3420 /* Add a FT_OID to a proto_tree */
3422 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3423 gint length, const guint8* value_ptr)
3426 header_field_info *hfinfo;
3428 CHECK_FOR_NULL_TREE(tree);
3430 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3432 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
3434 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3435 proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
3441 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3442 gint start, gint length,
3443 const guint8* value_ptr,
3444 const char *format, ...)
3449 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3451 va_start(ap, format);
3452 proto_tree_set_representation_value(pi, format, ap);
3460 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3461 gint start, gint length, const guint8* value_ptr,
3462 const char *format, ...)
3467 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3469 TRY_TO_FAKE_THIS_REPR(pi);
3471 va_start(ap, format);
3472 proto_tree_set_representation(pi, format, ap);
3479 /* Set the FT_OID value */
3481 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
3485 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3487 bytes = g_byte_array_new();
3489 g_byte_array_append(bytes, value_ptr, length);
3491 fvalue_set_byte_array(&fi->value, bytes);
3495 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3497 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
3500 /* Set the FT_SYSTEM_ID value */
3502 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
3506 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3508 bytes = g_byte_array_new();
3510 g_byte_array_append(bytes, value_ptr, length);
3512 fvalue_set_byte_array(&fi->value, bytes);
3516 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3518 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
3521 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
3522 * own copy of string, and frees it when the proto_tree is destroyed. */
3524 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3525 gint length, const char* value)
3528 header_field_info *hfinfo;
3530 CHECK_FOR_NULL_TREE(tree);
3532 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3534 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
3536 if (hfinfo->display == STR_UNICODE) {
3537 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
3540 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3541 DISSECTOR_ASSERT(length >= 0);
3542 proto_tree_set_string(PNODE_FINFO(pi), value);
3548 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3549 gint start, gint length, const char* value,
3556 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3558 va_start(ap, format);
3559 proto_tree_set_representation_value(pi, format, ap);
3567 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3568 gint start, gint length, const char* value,
3569 const char *format, ...)
3574 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3576 TRY_TO_FAKE_THIS_REPR(pi);
3578 va_start(ap, format);
3579 proto_tree_set_representation(pi, format, ap);
3586 /* Set the FT_STRING value */
3588 proto_tree_set_string(field_info *fi, const char* value)
3591 fvalue_set_string(&fi->value, value);
3593 fvalue_set_string(&fi->value, "[ Null ]");
3597 /* Set the FT_AX25 value */
3599 proto_tree_set_ax25(field_info *fi, const guint8* value)
3601 fvalue_set_bytes(&fi->value, value);
3605 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3607 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
3610 /* Set the FT_VINES value */
3612 proto_tree_set_vines(field_info *fi, const guint8* value)
3614 fvalue_set_bytes(&fi->value, value);
3618 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3620 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
3623 /* Add a FT_ETHER to a proto_tree */
3625 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3626 gint length, const guint8* value)
3629 header_field_info *hfinfo;
3631 CHECK_FOR_NULL_TREE(tree);
3633 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3635 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
3637 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3638 proto_tree_set_ether(PNODE_FINFO(pi), value);
3644 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3645 gint start, gint length, const guint8* value,
3646 const char *format, ...)
3651 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3653 va_start(ap, format);
3654 proto_tree_set_representation_value(pi, format, ap);
3662 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3663 gint start, gint length, const guint8* value,
3664 const char *format, ...)
3669 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3671 TRY_TO_FAKE_THIS_REPR(pi);
3673 va_start(ap, format);
3674 proto_tree_set_representation(pi, format, ap);
3681 /* Set the FT_ETHER value */
3683 proto_tree_set_ether(field_info *fi, const guint8* value)
3685 fvalue_set_bytes(&fi->value, value);
3689 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3691 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
3694 /* Add a FT_BOOLEAN to a proto_tree */
3696 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3697 gint length, guint32 value)
3700 header_field_info *hfinfo;
3702 CHECK_FOR_NULL_TREE(tree);
3704 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3706 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3708 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3709 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3715 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
3716 tvbuff_t *tvb, gint start, gint length,
3717 guint32 value, const char *format, ...)
3722 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3724 va_start(ap, format);
3725 proto_tree_set_representation_value(pi, format, ap);
3733 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3734 gint start, gint length, guint32 value,
3735 const char *format, ...)
3740 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3742 TRY_TO_FAKE_THIS_REPR(pi);
3744 va_start(ap, format);
3745 proto_tree_set_representation(pi, format, ap);
3753 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3754 gint length, guint64 value)
3757 header_field_info *hfinfo;
3759 CHECK_FOR_NULL_TREE(tree);
3761 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3763 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3765 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3766 proto_tree_set_boolean(PNODE_FINFO(pi), value);
3771 /* Set the FT_BOOLEAN value */
3773 proto_tree_set_boolean(field_info *fi, guint64 value)
3775 proto_tree_set_uint64(fi, value);
3778 /* Generate, into "buf", a string showing the bits of a bitfield.
3779 Return a pointer to the character after that string. */
3780 /*XXX this needs a buf_len check */
3782 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3790 bit = G_GUINT64_CONSTANT(1) << (width - 1);
3793 /* This bit is part of the field. Show its value. */
3799 /* This bit is not part of the field. */
3814 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3818 p = other_decode_bitfield_value(buf, val, mask, width);
3819 p = g_stpcpy(p, " = ");
3824 /* Add a FT_FLOAT to a proto_tree */
3826 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3827 gint length, float value)
3830 header_field_info *hfinfo;
3832 CHECK_FOR_NULL_TREE(tree);
3834 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3836 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
3838 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3839 proto_tree_set_float(PNODE_FINFO(pi), value);
3845 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3846 gint start, gint length, float value,
3847 const char *format, ...)
3852 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3854 va_start(ap, format);
3855 proto_tree_set_representation_value(pi, format, ap);
3863 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3864 gint start, gint length, float value,
3865 const char *format, ...)
3870 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3872 TRY_TO_FAKE_THIS_REPR(pi);
3874 va_start(ap, format);
3875 proto_tree_set_representation(pi, format, ap);
3882 /* Set the FT_FLOAT value */
3884 proto_tree_set_float(field_info *fi, float value)
3886 fvalue_set_floating(&fi->value, value);
3889 /* Add a FT_DOUBLE to a proto_tree */
3891 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3892 gint length, double value)
3895 header_field_info *hfinfo;
3897 CHECK_FOR_NULL_TREE(tree);
3899 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3901 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
3903 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3904 proto_tree_set_double(PNODE_FINFO(pi), value);
3910 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3911 gint start, gint length, double value,
3912 const char *format, ...)
3917 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3919 va_start(ap, format);
3920 proto_tree_set_representation_value(pi, format, ap);
3928 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3929 gint start, gint length, double value,
3930 const char *format, ...)
3935 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3937 TRY_TO_FAKE_THIS_REPR(pi);
3939 va_start(ap, format);
3940 proto_tree_set_representation(pi, format, ap);
3947 /* Set the FT_DOUBLE value */
3949 proto_tree_set_double(field_info *fi, double value)
3951 fvalue_set_floating(&fi->value, value);
3954 /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
3956 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3957 gint length, guint32 value)
3959 proto_item *pi = NULL;
3960 header_field_info *hfinfo;
3962 CHECK_FOR_NULL_TREE(tree);
3964 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3966 switch (hfinfo->type) {
3973 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3974 proto_tree_set_uint(PNODE_FINFO(pi), value);
3978 DISSECTOR_ASSERT_NOT_REACHED();
3985 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3986 gint start, gint length, guint32 value,
3987 const char *format, ...)
3992 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3994 va_start(ap, format);
3995 proto_tree_set_representation_value(pi, format, ap);
4003 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4004 gint start, gint length, guint32 value,
4005 const char *format, ...)
4010 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
4012 TRY_TO_FAKE_THIS_REPR(pi);
4014 va_start(ap, format);
4015 proto_tree_set_representation(pi, format, ap);
4022 /* Set the FT_UINT{8,16,24,32} value */
4024 proto_tree_set_uint(field_info *fi, guint32 value)
4026 header_field_info *hfinfo;
4029 hfinfo = fi->hfinfo;
4032 if (hfinfo->bitmask) {
4033 /* Mask out irrelevant portions */
4034 integer &= (guint32)(hfinfo->bitmask);
4037 integer >>= hfinfo_bitshift(hfinfo);
4040 fvalue_set_uinteger(&fi->value, integer);
4043 /* Add FT_UINT{40,48,56,64} to a proto_tree */
4045 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4046 gint length, guint64 value)
4048 proto_item *pi = NULL;
4049 header_field_info *hfinfo;
4051 CHECK_FOR_NULL_TREE(tree);
4053 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4055 switch (hfinfo->type) {
4061 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4062 proto_tree_set_uint64(PNODE_FINFO(pi), value);
4066 DISSECTOR_ASSERT_NOT_REACHED();
4073 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4074 gint start, gint length, guint64 value,
4075 const char *format, ...)
4080 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4082 va_start(ap, format);
4083 proto_tree_set_representation_value(pi, format, ap);
4091 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4092 gint start, gint length, guint64 value,
4093 const char *format, ...)
4098 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4100 TRY_TO_FAKE_THIS_REPR(pi);
4102 va_start(ap, format);
4103 proto_tree_set_representation(pi, format, ap);
4110 /* Set the FT_UINT{40,48,56,64} value */
4112 proto_tree_set_uint64(field_info *fi, guint64 value)
4114 header_field_info *hfinfo;
4117 hfinfo = fi->hfinfo;
4120 if (hfinfo->bitmask) {
4121 /* Mask out irrelevant portions */
4122 integer &= hfinfo->bitmask;
4125 integer >>= hfinfo_bitshift(hfinfo);
4128 fvalue_set_uinteger64(&fi->value, integer);
4131 /* Add FT_INT{8,16,24,32} to a proto_tree */
4133 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4134 gint length, gint32 value)
4136 proto_item *pi = NULL;
4137 header_field_info *hfinfo;
4139 CHECK_FOR_NULL_TREE(tree);
4141 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4143 switch (hfinfo->type) {
4148 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4149 proto_tree_set_int(PNODE_FINFO(pi), value);
4153 DISSECTOR_ASSERT_NOT_REACHED();
4160 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4161 gint start, gint length, gint32 value,
4162 const char *format, ...)
4167 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4169 va_start(ap, format);
4170 proto_tree_set_representation_value(pi, format, ap);
4178 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4179 gint start, gint length, gint32 value,
4180 const char *format, ...)
4185 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4187 TRY_TO_FAKE_THIS_REPR(pi);
4189 va_start(ap, format);
4190 proto_tree_set_representation(pi, format, ap);
4197 /* Set the FT_INT{8,16,24,32} value */
4199 proto_tree_set_int(field_info *fi, gint32 value)
4201 header_field_info *hfinfo;
4205 hfinfo = fi->hfinfo;
4206 integer = (guint32) value;
4208 if (hfinfo->bitmask) {
4209 /* Mask out irrelevant portions */
4210 integer &= (guint32)(hfinfo->bitmask);
4213 integer >>= hfinfo_bitshift(hfinfo);
4215 no_of_bits = ws_count_ones(hfinfo->bitmask);
4216 integer = ws_sign_ext32(integer, no_of_bits);
4219 fvalue_set_sinteger(&fi->value, integer);
4222 /* Add FT_INT{40,48,56,64} to a proto_tree */
4224 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4225 gint length, gint64 value)
4227 proto_item *pi = NULL;
4228 header_field_info *hfinfo;
4230 CHECK_FOR_NULL_TREE(tree);
4232 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4234 switch (hfinfo->type) {
4239 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4240 proto_tree_set_int64(PNODE_FINFO(pi), value);
4244 DISSECTOR_ASSERT_NOT_REACHED();
4251 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4252 gint start, gint length, gint64 value,
4253 const char *format, ...)
4258 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4260 va_start(ap, format);
4261 proto_tree_set_representation_value(pi, format, ap);
4268 /* Set the FT_INT{40,48,56,64} value */
4270 proto_tree_set_int64(field_info *fi, gint64 value)
4272 header_field_info *hfinfo;
4276 hfinfo = fi->hfinfo;
4279 if (hfinfo->bitmask) {
4280 /* Mask out irrelevant portions */
4281 integer &= hfinfo->bitmask;
4284 integer >>= hfinfo_bitshift(hfinfo);
4286 no_of_bits = ws_count_ones(hfinfo->bitmask);
4287 integer = ws_sign_ext64(integer, no_of_bits);
4290 fvalue_set_sinteger64(&fi->value, integer);
4294 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4295 gint start, gint length, gint64 value,
4296 const char *format, ...)
4301 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4303 TRY_TO_FAKE_THIS_REPR(pi);
4305 va_start(ap, format);
4306 proto_tree_set_representation(pi, format, ap);
4313 /* Add a FT_EUI64 to a proto_tree */
4315 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4316 gint length, const guint64 value)
4319 header_field_info *hfinfo;
4321 CHECK_FOR_NULL_TREE(tree);
4323 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4325 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
4327 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4328 proto_tree_set_eui64(PNODE_FINFO(pi), value);
4334 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4335 gint start, gint length, const guint64 value,
4336 const char *format, ...)
4341 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4343 va_start(ap, format);
4344 proto_tree_set_representation_value(pi, format, ap);
4352 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4353 gint start, gint length, const guint64 value,
4354 const char *format, ...)
4359 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4361 TRY_TO_FAKE_THIS_REPR(pi);
4363 va_start(ap, format);
4364 proto_tree_set_representation(pi, format, ap);
4371 /* Set the FT_EUI64 value */
4373 proto_tree_set_eui64(field_info *fi, const guint64 value)
4375 fvalue_set_uinteger64(&fi->value, value);
4378 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
4382 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
4384 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
4388 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
4390 proto_tree_add_node(proto_tree *tree, field_info *fi)
4392 proto_node *pnode, *tnode, *sibling;
4397 * Restrict our depth. proto_tree_traverse_pre_order and
4398 * proto_tree_traverse_post_order (and possibly others) are recursive
4399 * so we need to be mindful of our stack size.
4401 if (tree->first_child == NULL) {
4402 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
4404 if (G_UNLIKELY(depth > MAX_TREE_LEVELS)) {
4405 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
4406 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u)",
4408 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
4414 * Make sure "tree" is ready to have subtrees under it, by
4415 * checking whether it's been given an ett_ value.
4417 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
4418 * node of the protocol tree. That node is not displayed,
4419 * so it doesn't need an ett_ value to remember whether it
4423 tfi = PNODE_FINFO(tnode);
4424 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
4425 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4426 "\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
4427 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
4428 /* XXX - is it safe to continue here? */
4431 pnode = wmem_new(PNODE_POOL(tree), proto_node);
4432 PROTO_NODE_INIT(pnode);
4433 pnode->parent = tnode;
4434 PNODE_FINFO(pnode) = fi;
4435 pnode->tree_data = PTREE_DATA(tree);
4437 if (tnode->last_child != NULL) {
4438 sibling = tnode->last_child;
4439 DISSECTOR_ASSERT(sibling->next == NULL);
4440 sibling->next = pnode;
4442 tnode->first_child = pnode;
4443 tnode->last_child = pnode;
4445 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
4447 return (proto_item *)pnode;
4451 /* Generic way to allocate field_info and add to proto_tree.
4452 * Sets *pfi to address of newly-allocated field_info struct */
4454 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
4461 get_hfi_length(hfinfo, tvb, start, length, &item_length);
4462 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4463 pi = proto_tree_add_node(tree, fi);
4470 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
4473 gint length_remaining;
4476 * We only allow a null tvbuff if the item has a zero length,
4477 * i.e. if there's no data backing it.
4479 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
4482 * XXX - in some protocols, there are 32-bit unsigned length
4483 * fields, so lengths in protocol tree and tvbuff routines
4484 * should really be unsigned. We should have, for those
4485 * field types for which "to the end of the tvbuff" makes sense,
4486 * additional routines that take no length argument and
4487 * add fields that run to the end of the tvbuff.
4489 if (*length == -1) {
4491 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
4492 * FT_STRINGZPAD fields, a length of -1 means "set the
4493 * length to what remains in the tvbuff".
4495 * The assumption is either that
4497 * 1) the length of the item can only be determined
4498 * by dissection (typically true of items with
4499 * subitems, which are probably FT_NONE or
4504 * 2) if the tvbuff is "short" (either due to a short
4505 * snapshot length or due to lack of reassembly of
4506 * fragments/segments/whatever), we want to display
4507 * what's available in the field (probably FT_BYTES
4508 * or FT_STRING) and then throw an exception later
4512 * 3) the field is defined to be "what's left in the
4515 * so we set the length to what remains in the tvbuff so
4516 * that, if we throw an exception while dissecting, it
4517 * has what is probably the right value.
4519 * For FT_STRINGZ, it means "the string is null-terminated,
4520 * not null-padded; set the length to the actual length
4521 * of the string", and if the tvbuff if short, we just
4522 * throw an exception.
4524 * It's not valid for any other type of field. For those
4525 * fields, we treat -1 the same way we treat other
4526 * negative values - we assume the length is a Really
4527 * Big Positive Number, and throw a ReportedBoundsError
4528 * exception, under the assumption that the Really Big
4529 * Length would run past the end of the packet.
4531 switch (hfinfo->type) {
4539 * We allow FT_PROTOCOLs to be zero-length -
4540 * for example, an ONC RPC NULL procedure has
4541 * neither arguments nor reply, so the
4542 * payload for that protocol is empty.
4544 * We also allow the others to be zero-length -
4545 * because that's the way the code has been for a
4548 * However, we want to ensure that the start
4549 * offset is not *past* the byte past the end
4550 * of the tvbuff: we throw an exception in that
4553 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
4554 DISSECTOR_ASSERT(*length >= 0);
4559 * Leave the length as -1, so our caller knows
4565 THROW(ReportedBoundsError);
4566 DISSECTOR_ASSERT_NOT_REACHED();
4568 *item_length = *length;
4570 *item_length = *length;
4571 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
4573 * These types are for interior nodes of the
4574 * tree, and don't have data associated with
4575 * them; if the length is negative (XXX - see
4576 * above) or goes past the end of the tvbuff,
4577 * cut it short at the end of the tvbuff.
4578 * That way, if this field is selected in
4579 * Wireshark, we don't highlight stuff past
4580 * the end of the data.
4582 /* XXX - what to do, if we don't have a tvb? */
4584 length_remaining = tvb_captured_length_remaining(tvb, start);
4585 if (*item_length < 0 ||
4586 (*item_length > 0 &&
4587 (length_remaining < *item_length)))
4588 *item_length = length_remaining;
4591 if (*item_length < 0) {
4592 THROW(ReportedBoundsError);
4598 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
4599 gint length, guint item_length, const gint encoding)
4604 * We need to get the correct item length here.
4605 * That's normally done by proto_tree_new_item(),
4606 * but we won't be calling it.
4608 switch (hfinfo->type) {
4614 * The length is the specified length.
4620 * Map all non-zero values to little-endian for
4621 * backwards compatibility.
4623 n = get_uint_value(NULL, tvb, start, length,
4624 encoding ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
4630 /* XXX - make these just FT_UINT? */
4639 /* XXX - make these just FT_INT? */
4664 * The length is the specified length.
4670 report_type_length_mismatch(NULL, "a string", length, TRUE);
4673 /* This can throw an exception */
4674 /* XXX - do this without fetching the string? */
4675 tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
4677 item_length = length;
4680 case FT_UINT_STRING:
4681 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
4686 case FT_ABSOLUTE_TIME:
4687 case FT_RELATIVE_TIME:
4688 case FT_IEEE_11073_SFLOAT:
4689 case FT_IEEE_11073_FLOAT:
4691 * The length is the specified length.
4696 g_error("hfinfo->type %d (%s) not handled\n",
4698 ftype_name(hfinfo->type));
4699 DISSECTOR_ASSERT_NOT_REACHED();
4706 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4707 const gint start, const gint item_length)
4711 FIELD_INFO_NEW(PNODE_POOL(tree), fi);
4713 fi->hfinfo = hfinfo;
4715 fi->start += (tvb)?tvb_raw_offset(tvb):0;
4716 fi->length = item_length;
4719 if (!PTREE_DATA(tree)->visible)
4720 FI_SET_FLAG(fi, FI_HIDDEN);
4721 fvalue_init(&fi->value, fi->hfinfo->type);
4724 /* add the data source tvbuff */
4725 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
4727 fi->appendix_start = 0;
4728 fi->appendix_length = 0;
4733 /* If the protocol tree is to be visible, set the representation of a
4734 proto_tree entry with the name of the field for the item and with
4735 the value formatted with the supplied printf-style format and
4738 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
4742 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
4743 * items string representation */
4744 if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
4746 field_info *fi = PITEM_FINFO(pi);
4747 header_field_info *hf;
4749 DISSECTOR_ASSERT(fi);
4753 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4754 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
4758 if (IS_FT_UINT(hf->type))
4759 val = fvalue_get_uinteger(&fi->value);
4761 val = fvalue_get_uinteger64(&fi->value);
4763 val <<= hfinfo_bitshift(hf);
4765 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
4766 ret = (int) (p - fi->rep->representation);
4769 /* put in the hf name */
4770 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
4772 /* If possible, Put in the value of the string */
4773 if (ret < ITEM_LABEL_LENGTH) {
4774 ret += g_vsnprintf(fi->rep->representation + ret,
4775 ITEM_LABEL_LENGTH - ret, format, ap);
4777 if (ret >= ITEM_LABEL_LENGTH) {
4778 /* Uh oh, we don't have enough room. Tell the user
4779 * that the field is truncated.
4781 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4786 /* If the protocol tree is to be visible, set the representation of a
4787 proto_tree entry with the representation formatted with the supplied
4788 printf-style format and argument list. */
4790 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
4792 int ret; /*tmp return value */
4793 field_info *fi = PITEM_FINFO(pi);
4795 DISSECTOR_ASSERT(fi);
4797 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4798 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4799 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
4801 if (ret >= ITEM_LABEL_LENGTH) {
4802 /* Uh oh, we don't have enough room. Tell the user
4803 * that the field is truncated.
4805 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4811 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
4813 switch (hfinfo->display) {
4815 return format_text(string, strlen(string));
4818 return format_text_wsp(string, strlen(string));
4821 /* XXX, format_unicode_text() */
4825 return format_text(string, strlen(string));
4829 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
4831 gsize res = g_strlcpy(dest, src, dest_size);
4833 if (res > dest_size)
4838 static header_field_info *
4839 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
4841 header_field_info *dup_hfinfo;
4843 if (hfinfo->same_name_prev_id == -1)
4845 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
4850 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
4852 g_free(last_field_name);
4853 last_field_name = NULL;
4855 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
4856 /* No hfinfo with the same name */
4857 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
4861 if (hfinfo->same_name_next) {
4862 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
4865 if (hfinfo->same_name_prev_id != -1) {
4866 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
4867 same_name_prev->same_name_next = hfinfo->same_name_next;
4868 if (!hfinfo->same_name_next) {
4869 /* It's always the latest added hfinfo which is stored in gpa_name_map */
4870 g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
4875 /* -------------------------- */
4877 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
4878 gchar *result, gchar *expr, const int size)
4883 ipv4_addr_and_mask *ipv4;
4884 struct e_in6_addr *ipv6;
4886 guint32 n_addr; /* network-order IPv4 address */
4888 const true_false_string *tfstring;
4890 int len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
4892 field_info *finfo = NULL;
4893 header_field_info* hfinfo;
4894 const gchar *abbrev = NULL;
4896 const char *hf_str_val;
4897 char number_buf[48];
4898 const char *number_out;
4904 g_assert(field_ids != NULL);
4905 while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
4906 field_id = *field_idx;
4907 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
4909 /* do we need to rewind ? */
4913 if (occurrence < 0) {
4914 /* Search other direction */
4915 while (hfinfo->same_name_prev_id != -1) {
4916 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
4921 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
4923 if (!finfos || !(len = g_ptr_array_len(finfos))) {
4924 if (occurrence < 0) {
4925 hfinfo = hfinfo->same_name_next;
4927 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4932 /* Are there enough occurrences of the field? */
4933 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
4934 if (occurrence < 0) {
4935 hfinfo = hfinfo->same_name_next;
4937 hfinfo = hfinfo_same_name_get_prev(hfinfo);
4943 /* Calculate single index or set outer bounderies */
4944 if (occurrence < 0) {
4945 i = occurrence + len + prev_len;
4947 } else if (occurrence > 0) {
4948 i = occurrence - 1 - prev_len;
4955 prev_len += len; /* Count handled occurrences */
4958 finfo = (field_info *)g_ptr_array_index(finfos, i);
4960 if (offset_r && (offset_r < (size - 2)))
4961 result[offset_r++] = ',';
4963 if (offset_e && (offset_e < (size - 2)))
4964 expr[offset_e++] = ',';
4966 switch (hfinfo->type) {
4968 case FT_NONE: /* Nothing to add */
4969 if (offset_r == 0) {
4971 } else if (result[offset_r-1] == ',') {
4972 result[offset_r-1] = '\0';
4977 /* prevent multiple "yes" entries by setting result directly */
4978 g_strlcpy(result, "Yes", size);
4983 bytes = (guint8 *)fvalue_get(&finfo->value);
4985 switch(hfinfo->display)
4988 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
4991 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
4994 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
4997 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5001 if (prefs.display_byte_fields_with_spaces)
5003 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5007 str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
5011 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5012 wmem_free(NULL, str);
5015 if (hfinfo->display & BASE_ALLOW_ZERO) {
5016 offset_r += protoo_strlcpy(result+offset_r, "<none>", size-offset_r);
5018 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
5023 case FT_ABSOLUTE_TIME:
5024 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
5025 offset_r += protoo_strlcpy(result+offset_r,
5028 wmem_free(NULL, tmpbuf);
5031 case FT_RELATIVE_TIME:
5032 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
5033 offset_r += protoo_strlcpy(result+offset_r,
5036 wmem_free(NULL, tmpbuf);
5040 number64 = fvalue_get_uinteger64(&finfo->value);
5041 tfstring = (const true_false_string *)&tfs_true_false;
5042 if (hfinfo->strings) {
5043 tfstring = (const struct true_false_string*) hfinfo->strings;
5045 offset_r += protoo_strlcpy(result+offset_r,
5047 tfstring->true_string :
5048 tfstring->false_string, size-offset_r);
5050 offset_e += protoo_strlcpy(expr+offset_e,
5051 number64 ? "1" : "0", size-offset_e);
5056 number = fvalue_get_uinteger(&finfo->value);
5058 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5059 gchar tmp[ITEM_LABEL_LENGTH];
5060 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5062 DISSECTOR_ASSERT(fmtfunc);
5063 fmtfunc(tmp, number);
5065 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5067 } else if (hfinfo->strings) {
5068 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5071 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
5073 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5076 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5078 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5081 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5082 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5084 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5086 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5089 offset_e = (int)strlen(expr);
5092 /* XXX - make these just FT_NUMBER? */
5103 number = IS_FT_INT(hfinfo->type) ?
5104 (guint32) fvalue_get_sinteger(&finfo->value) :
5105 fvalue_get_uinteger(&finfo->value);
5107 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5108 gchar tmp[ITEM_LABEL_LENGTH];
5109 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5111 DISSECTOR_ASSERT(fmtfunc);
5112 fmtfunc(tmp, number);
5114 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5116 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
5117 if (hfinfo->display & BASE_UNIT_STRING) {
5118 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5119 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5120 hf_str_val = hf_try_val_to_str(number, hfinfo);
5121 offset_r += protoo_strlcpy(result+offset_r, hf_str_val, size-offset_r);
5124 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5127 number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
5129 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5132 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
5134 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5137 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5138 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5140 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5142 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5145 offset_e = (int)strlen(expr);
5157 number64 = IS_FT_INT(hfinfo->type) ?
5158 (guint64) fvalue_get_sinteger64(&finfo->value) :
5159 fvalue_get_uinteger64(&finfo->value);
5161 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5162 gchar tmp[ITEM_LABEL_LENGTH];
5163 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
5165 DISSECTOR_ASSERT(fmtfunc64);
5166 fmtfunc64(tmp, number64);
5167 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5168 } else if (hfinfo->strings) {
5169 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
5172 number_out = hfinfo_number_value_format_display64(hfinfo, BASE_DEC, number_buf, number64);
5174 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5177 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
5179 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5182 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5183 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5185 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
5187 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5190 offset_e = (int)strlen(expr);
5194 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
5195 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5196 wmem_free(NULL, str);
5200 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&finfo->value);
5201 n_addr = ipv4_get_net_order_addr(ipv4);
5202 set_address (&addr, AT_IPv4, 4, &n_addr);
5203 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5204 offset_r = (int)strlen(result);
5208 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
5209 set_address (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
5210 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5211 offset_r = (int)strlen(result);
5215 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
5216 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5217 offset_r = (int)strlen(result);
5221 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
5222 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5223 offset_r = (int)strlen(result);
5227 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
5228 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5229 wmem_free(NULL, str);
5233 bytes = (guint8 *)fvalue_get(&finfo->value);
5234 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5235 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5236 wmem_free(NULL, str);
5238 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5239 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5240 wmem_free(NULL, str);
5244 bytes = (guint8 *)fvalue_get(&finfo->value);
5245 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5246 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5247 wmem_free(NULL, str);
5249 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5250 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5251 wmem_free(NULL, str);
5255 bytes = (guint8 *)fvalue_get(&finfo->value);
5256 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
5257 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5258 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5259 wmem_free(NULL, str);
5263 if (hfinfo->display & BASE_UNIT_STRING) {
5264 double d_value = fvalue_get_floating(&finfo->value);
5265 g_snprintf(result+offset_r, size-offset_r,
5266 "%." G_STRINGIFY(FLT_DIG) "g%s", d_value,
5267 unit_name_string_get_value64((guint64)d_value, (unit_name_string*)hfinfo->strings));
5269 g_snprintf(result+offset_r, size-offset_r,
5270 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
5272 offset_r = (int)strlen(result);
5276 if (hfinfo->display & BASE_UNIT_STRING) {
5277 double d_value = fvalue_get_floating(&finfo->value);
5278 g_snprintf(result+offset_r, size-offset_r,
5279 "%." G_STRINGIFY(DBL_DIG) "g%s", d_value,
5280 unit_name_string_get_value64((guint64)d_value, (unit_name_string*)hfinfo->strings));
5282 g_snprintf(result+offset_r, size-offset_r,
5283 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
5285 offset_r = (int)strlen(result);
5290 case FT_UINT_STRING:
5292 bytes = (guint8 *)fvalue_get(&finfo->value);
5293 offset_r += protoo_strlcpy(result+offset_r,
5294 hfinfo_format_text(hfinfo, bytes),
5298 case FT_IEEE_11073_SFLOAT:
5299 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5300 g_snprintf(result+offset_r, size-offset_r,
5303 wmem_free(NULL, str);
5304 offset_r = (int)strlen(result);
5307 case FT_IEEE_11073_FLOAT:
5308 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5309 g_snprintf(result+offset_r, size-offset_r,
5312 offset_r = (int)strlen(result);
5313 wmem_free(NULL, str);
5316 case FT_IPXNET: /*XXX really No column custom ?*/
5319 g_error("hfinfo->type %d (%s) not handled\n",
5321 ftype_name(hfinfo->type));
5322 DISSECTOR_ASSERT_NOT_REACHED();
5328 switch (hfinfo->type) {
5352 /* for these types, "expr" is filled in the loop above */
5356 /* for all others, just copy "result" to "expr" */
5357 g_strlcpy(expr, result, size);
5362 /* Store abbrev for return value */
5363 abbrev = hfinfo->abbrev;
5366 if (occurrence == 0) {
5367 /* Fetch next hfinfo with same name (abbrev) */
5368 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5375 return abbrev ? abbrev : "";
5379 /* Set text of proto_item after having already been created. */
5381 proto_item_set_text(proto_item *pi, const char *format, ...)
5383 field_info *fi = NULL;
5386 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5388 fi = PITEM_FINFO(pi);
5393 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
5397 va_start(ap, format);
5398 proto_tree_set_representation(pi, format, ap);
5402 /* Append to text of proto_item after having already been created. */
5404 proto_item_append_text(proto_item *pi, const char *format, ...)
5406 field_info *fi = NULL;
5410 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5412 fi = PITEM_FINFO(pi);
5417 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5419 * If we don't already have a representation,
5420 * generate the default representation.
5422 if (fi->rep == NULL) {
5423 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5424 proto_item_fill_label(fi, fi->rep->representation);
5427 curlen = strlen(fi->rep->representation);
5428 if (ITEM_LABEL_LENGTH > curlen) {
5429 va_start(ap, format);
5430 g_vsnprintf(fi->rep->representation + curlen,
5431 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
5437 /* Prepend to text of proto_item after having already been created. */
5439 proto_item_prepend_text(proto_item *pi, const char *format, ...)
5441 field_info *fi = NULL;
5442 char representation[ITEM_LABEL_LENGTH];
5445 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5447 fi = PITEM_FINFO(pi);
5452 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5454 * If we don't already have a representation,
5455 * generate the default representation.
5457 if (fi->rep == NULL) {
5458 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5459 proto_item_fill_label(fi, representation);
5461 g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
5463 va_start(ap, format);
5464 g_vsnprintf(fi->rep->representation,
5465 ITEM_LABEL_LENGTH, format, ap);
5467 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
5472 finfo_set_len(field_info *fi, const gint length)
5474 DISSECTOR_ASSERT(length >= 0);
5475 fi->length = length;
5478 * You cannot just make the "len" field of a GByteArray
5479 * larger, if there's no data to back that length;
5480 * you can only make it smaller.
5482 if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
5483 fi->value.value.bytes->len = length;
5487 proto_item_set_len(proto_item *pi, const gint length)
5491 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5493 fi = PITEM_FINFO(pi);
5497 finfo_set_len(fi, length);
5501 * Sets the length of the item based on its start and on the specified
5502 * offset, which is the offset past the end of the item; as the start
5503 * in the item is relative to the beginning of the data source tvbuff,
5504 * we need to pass in a tvbuff - the end offset is relative to the beginning
5508 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
5513 TRY_TO_FAKE_THIS_REPR_VOID(pi);
5515 fi = PITEM_FINFO(pi);
5519 end += tvb_raw_offset(tvb);
5520 DISSECTOR_ASSERT(end >= fi->start);
5521 length = end - fi->start;
5523 finfo_set_len(fi, length);
5527 proto_item_get_len(const proto_item *pi)
5529 field_info *fi = PITEM_FINFO(pi);
5530 return fi ? fi->length : -1;
5534 proto_tree_create_root(packet_info *pinfo)
5538 /* Initialize the proto_node */
5539 pnode = g_slice_new(proto_tree);
5540 PROTO_NODE_INIT(pnode);
5541 pnode->parent = NULL;
5542 PNODE_FINFO(pnode) = NULL;
5543 pnode->tree_data = g_slice_new(tree_data_t);
5545 /* Make sure we can access pinfo everywhere */
5546 pnode->tree_data->pinfo = pinfo;
5548 /* Don't initialize the tree_data_t. Wait until we know we need it */
5549 pnode->tree_data->interesting_hfids = NULL;
5551 /* Set the default to FALSE so it's easier to
5552 * find errors; if we expect to see the protocol tree
5553 * but for some reason the default 'visible' is not
5554 * changed, then we'll find out very quickly. */
5555 pnode->tree_data->visible = FALSE;
5557 /* Make sure that we fake protocols (if possible) */
5558 pnode->tree_data->fake_protocols = TRUE;
5560 /* Keep track of the number of children */
5561 pnode->tree_data->count = 0;
5563 return (proto_tree *)pnode;
5567 /* "prime" a proto_tree with a single hfid that a dfilter
5568 * is interested in. */
5570 proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
5572 header_field_info *hfinfo;
5574 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
5575 /* this field is referenced by a filter so increase the refcount.
5576 also increase the refcount for the parent, i.e the protocol.
5578 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
5579 /* only increase the refcount if there is a parent.
5580 if this is a protocol and not a field then parent will be -1
5581 and there is no parent to add any refcounting for.
5583 if (hfinfo->parent != -1) {
5584 header_field_info *parent_hfinfo;
5585 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
5587 /* Mark parent as indirectly referenced unless it is already directly
5588 * referenced, i.e. the user has specified the parent in a filter.
5590 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
5591 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
5596 proto_item_add_subtree(proto_item *pi, const gint idx) {
5602 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
5604 fi = PITEM_FINFO(pi);
5606 return (proto_tree *)pi;
5608 fi->tree_type = idx;
5610 return (proto_tree *)pi;
5614 proto_item_get_subtree(proto_item *pi) {
5619 fi = PITEM_FINFO(pi);
5620 if ( (!fi) || (fi->tree_type == -1) )
5622 return (proto_tree *)pi;
5626 proto_item_get_parent(const proto_item *ti) {
5633 proto_item_get_parent_nth(proto_item *ti, int gen) {
5646 proto_tree_get_parent(proto_tree *tree) {
5649 return (proto_item *)tree;
5653 proto_tree_get_parent_tree(proto_tree *tree) {
5657 /* we're the root tree, there's no parent
5658 return ourselves so the caller has at least a tree to attach to */
5662 return (proto_tree *)tree->parent;
5666 proto_tree_get_root(proto_tree *tree) {
5669 while (tree->parent) {
5670 tree = tree->parent;
5676 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
5677 proto_item *item_to_move)
5680 /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
5681 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
5683 /* This function doesn't generate any values. It only reorganizes the prococol tree
5684 * so we can bail out immediately if it isn't visible. */
5685 if (!tree || !PTREE_DATA(tree)->visible)
5688 DISSECTOR_ASSERT(item_to_move->parent == tree);
5689 DISSECTOR_ASSERT(fixed_item->parent == tree);
5691 /*** cut item_to_move out ***/
5693 /* is item_to_move the first? */
5694 if (tree->first_child == item_to_move) {
5695 /* simply change first child to next */
5696 tree->first_child = item_to_move->next;
5698 DISSECTOR_ASSERT(tree->last_child != item_to_move);
5700 proto_item *curr_item;
5701 /* find previous and change it's next */
5702 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
5703 if (curr_item->next == item_to_move) {
5708 DISSECTOR_ASSERT(curr_item);
5710 curr_item->next = item_to_move->next;
5712 /* fix last_child if required */
5713 if (tree->last_child == item_to_move) {
5714 tree->last_child = curr_item;
5718 /*** insert to_move after fixed ***/
5719 item_to_move->next = fixed_item->next;
5720 fixed_item->next = item_to_move;
5721 if (tree->last_child == fixed_item) {
5722 tree->last_child = item_to_move;
5727 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
5735 fi = PTREE_FINFO(tree);
5739 start += tvb_raw_offset(tvb);
5740 DISSECTOR_ASSERT(start >= 0);
5741 DISSECTOR_ASSERT(length >= 0);
5743 fi->appendix_start = start;
5744 fi->appendix_length = length;
5748 proto_register_protocol(const char *name, const char *short_name,
5749 const char *filter_name)
5751 protocol_t *protocol;
5752 const protocol_t *existing_protocol = NULL;
5753 header_field_info *hfinfo;
5755 const char *existing_name;
5759 gboolean found_invalid;
5762 * Make sure there's not already a protocol with any of those
5763 * names. Crash if there is, as that's an error in the code
5764 * or an inappropriate plugin.
5765 * This situation has to be fixed to not register more than one
5766 * protocol with the same name.
5768 * This is done by reducing the number of strcmp (and alike) calls
5769 * as much as possible, as this significally slows down startup time.
5771 * Drawback: As a hash value is used to reduce insert time,
5772 * this might lead to a hash collision.
5773 * However, although we have somewhat over 1000 protocols, we're using
5774 * a 32 bit int so this is very, very unlikely.
5777 key = (gint *)g_malloc (sizeof(gint));
5778 *key = wrs_str_hash(name);
5780 existing_name = (const char *)g_hash_table_lookup(proto_names, key);
5781 if (existing_name != NULL) {
5782 /* g_error will terminate the program */
5783 g_error("Duplicate protocol name \"%s\"!"
5784 " This might be caused by an inappropriate plugin or a development error.", name);
5786 g_hash_table_insert(proto_names, key, (gpointer)name);
5788 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5789 if (existing_protocol != NULL) {
5790 g_error("Duplicate protocol short_name \"%s\"!"
5791 " This might be caused by an inappropriate plugin or a development error.", short_name);
5794 found_invalid = FALSE;
5795 for (i = 0; filter_name[i]; i++) {
5797 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
5798 found_invalid = TRUE;
5801 if (found_invalid) {
5802 g_error("Protocol filter name \"%s\" has one or more invalid characters."
5803 " Allowed are lower characters, digits, '-', '_' and '.'."
5804 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5806 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5807 if (existing_protocol != NULL) {
5808 g_error("Duplicate protocol filter_name \"%s\"!"
5809 " This might be caused by an inappropriate plugin or a development error.", filter_name);
5812 /* Add this protocol to the list of known protocols; the list
5813 is sorted by protocol short name. */
5814 protocol = g_new(protocol_t, 1);
5815 protocol->name = name;
5816 protocol->short_name = short_name;
5817 protocol->filter_name = filter_name;
5818 /*protocol->fields = g_ptr_array_new();*/
5819 /* Delegate until actually needed and use g_ptr_array_sized_new*/
5820 protocol->fields = NULL;
5821 protocol->is_enabled = TRUE; /* protocol is enabled by default */
5822 protocol->enabled_by_default = TRUE; /* see previous comment */
5823 protocol->can_toggle = TRUE;
5824 protocol->heur_list = NULL;
5825 /* list will be sorted later by name, when all protocols completed registering */
5826 protocols = g_list_prepend(protocols, protocol);
5827 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
5828 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
5830 /* Here we allocate a new header_field_info struct */
5831 hfinfo = g_slice_new(header_field_info);
5832 hfinfo->name = name;
5833 hfinfo->abbrev = filter_name;
5834 hfinfo->type = FT_PROTOCOL;
5835 hfinfo->display = BASE_NONE;
5836 hfinfo->strings = protocol;
5837 hfinfo->bitmask = 0;
5838 hfinfo->ref_type = HF_REF_TYPE_NONE;
5839 hfinfo->blurb = NULL;
5840 hfinfo->parent = -1; /* this field differentiates protos and fields */
5842 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
5843 protocol->proto_id = proto_id;
5848 proto_deregister_protocol(const char *short_name)
5850 protocol_t *protocol;
5851 header_field_info *hfinfo;
5856 proto_id = proto_get_id_by_short_name(short_name);
5857 protocol = find_protocol_by_id(proto_id);
5858 if (protocol == NULL)
5861 key = wrs_str_hash(protocol->name);
5862 g_hash_table_remove(proto_names, &key);
5864 g_hash_table_remove(proto_short_names, (gpointer)short_name);
5865 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
5867 if (protocol->fields) {
5868 for (i = 0; i < protocol->fields->len; i++) {
5869 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
5870 hfinfo_remove_from_gpa_name_map(hfinfo);
5871 expert_deregister_expertinfo(hfinfo->abbrev);
5872 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
5874 g_ptr_array_free(protocol->fields, TRUE);
5875 protocol->fields = NULL;
5878 /* Remove this protocol from the list of known protocols */
5879 protocols = g_list_remove(protocols, protocol);
5881 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
5882 g_hash_table_steal(gpa_name_map, protocol->filter_name);
5884 g_free(last_field_name);
5885 last_field_name = NULL;
5891 * Routines to use to iterate over the protocols.
5892 * The argument passed to the iterator routines is an opaque cookie to
5893 * their callers; it's the GList pointer for the current element in
5895 * The ID of the protocol is returned, or -1 if there is no protocol.
5898 proto_get_first_protocol(void **cookie)
5900 protocol_t *protocol;
5902 if (protocols == NULL)
5904 *cookie = protocols;
5905 protocol = (protocol_t *)protocols->data;
5906 return protocol->proto_id;
5910 proto_get_data_protocol(void *cookie)
5912 GList *list_item = (GList *)cookie;
5914 protocol_t *protocol = (protocol_t *)list_item->data;
5915 return protocol->proto_id;
5919 proto_get_next_protocol(void **cookie)
5921 GList *list_item = (GList *)*cookie;
5922 protocol_t *protocol;
5924 list_item = g_list_next(list_item);
5925 if (list_item == NULL)
5927 *cookie = list_item;
5928 protocol = (protocol_t *)list_item->data;
5929 return protocol->proto_id;
5932 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
5933 assume that the cookie stored by
5934 proto_get_(first|next)_protocol_field() will never have a
5935 value of NULL. So, to preserve this semantic, the cookie value
5936 below is adjusted so that the cookie value stored is 1 + the
5937 current (zero-based) array index.
5940 proto_get_first_protocol_field(const int proto_id, void **cookie)
5942 protocol_t *protocol = find_protocol_by_id(proto_id);
5944 if ((protocol == NULL) || (protocol->fields == NULL))
5947 *cookie = GUINT_TO_POINTER(0 + 1);
5948 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
5952 proto_get_next_protocol_field(const int proto_id, void **cookie)
5954 protocol_t *protocol = find_protocol_by_id(proto_id);
5955 guint i = GPOINTER_TO_UINT(*cookie) - 1;
5959 if ((protocol->fields == NULL) || (i >= protocol->fields->len))
5962 *cookie = GUINT_TO_POINTER(i + 1);
5963 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
5967 find_protocol_by_id(const int proto_id)
5969 header_field_info *hfinfo;
5974 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
5975 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
5976 return (protocol_t *)hfinfo->strings;
5980 proto_get_id(const protocol_t *protocol)
5982 return protocol->proto_id;
5986 proto_name_already_registered(const gchar *name)
5990 DISSECTOR_ASSERT_HINT(name, "No name present");
5992 key = wrs_str_hash(name);
5993 if (g_hash_table_lookup(proto_names, &key) != NULL)
5999 proto_get_id_by_filter_name(const gchar *filter_name)
6001 const protocol_t *protocol = NULL;
6003 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
6005 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
6007 if (protocol == NULL)
6009 return protocol->proto_id;
6013 proto_get_id_by_short_name(const gchar *short_name)
6015 const protocol_t *protocol = NULL;
6017 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
6019 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
6021 if (protocol == NULL)
6023 return protocol->proto_id;
6027 proto_get_protocol_name(const int proto_id)
6029 protocol_t *protocol;
6031 protocol = find_protocol_by_id(proto_id);
6033 if (protocol == NULL)
6035 return protocol->name;
6039 proto_get_protocol_short_name(const protocol_t *protocol)
6041 if (protocol == NULL)
6043 return protocol->short_name;
6047 proto_get_protocol_long_name(const protocol_t *protocol)
6049 if (protocol == NULL)
6051 return protocol->name;
6055 proto_get_protocol_filter_name(const int proto_id)
6057 protocol_t *protocol;
6059 protocol = find_protocol_by_id(proto_id);
6060 if (protocol == NULL)
6062 return protocol->filter_name;
6065 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
6067 heur_dtbl_entry_t* heuristic_dissector;
6069 if (protocol == NULL)
6072 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
6073 if (heuristic_dissector != NULL)
6075 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
6079 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
6081 if (protocol == NULL)
6084 g_list_foreach(protocol->heur_list, func, user_data);
6088 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
6089 gboolean *is_tcp, gboolean *is_udp,
6090 gboolean *is_sctp, gboolean *is_ssl,
6092 gboolean *is_lte_rlc)
6094 wmem_list_frame_t *protos = wmem_list_head(layers);
6096 const char *proto_name;
6098 /* Walk the list of a available protocols in the packet and
6099 find "major" ones. */
6100 /* It might make more sense to assemble and return a bitfield. */
6101 while (protos != NULL)
6103 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6104 proto_name = proto_get_protocol_filter_name(proto_id);
6106 if (is_ip && ((!strcmp(proto_name, "ip")) ||
6107 (!strcmp(proto_name, "ipv6")))) {
6109 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
6111 } else if (is_udp && !strcmp(proto_name, "udp")) {
6113 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
6115 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
6117 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
6119 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
6123 protos = wmem_list_frame_next(protos);
6128 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
6130 wmem_list_frame_t *protos = wmem_list_head(layers);
6134 /* Walk the list of a available protocols in the packet and
6135 find "major" ones. */
6136 /* It might make more sense to assemble and return a bitfield. */
6137 while (protos != NULL)
6139 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6140 name = proto_get_protocol_filter_name(proto_id);
6142 if (!strcmp(name, proto_name))
6147 protos = wmem_list_frame_next(protos);
6155 proto_is_protocol_enabled(const protocol_t *protocol)
6157 return protocol->is_enabled;
6161 proto_is_protocol_enabled_by_default(const protocol_t *protocol)
6163 return protocol->enabled_by_default;
6167 proto_can_toggle_protocol(const int proto_id)
6169 protocol_t *protocol;
6171 protocol = find_protocol_by_id(proto_id);
6172 return protocol->can_toggle;
6176 proto_disable_by_default(const int proto_id)
6178 protocol_t *protocol;
6180 protocol = find_protocol_by_id(proto_id);
6181 DISSECTOR_ASSERT(protocol->can_toggle);
6182 protocol->is_enabled = FALSE;
6183 protocol->enabled_by_default = FALSE;
6187 proto_set_decoding(const int proto_id, const gboolean enabled)
6189 protocol_t *protocol;
6191 protocol = find_protocol_by_id(proto_id);
6192 DISSECTOR_ASSERT(protocol->can_toggle);
6193 protocol->is_enabled = enabled;
6197 proto_enable_all(void)
6199 protocol_t *protocol;
6200 GList *list_item = protocols;
6202 if (protocols == NULL)
6206 protocol = (protocol_t *)list_item->data;
6207 if (protocol->can_toggle && protocol->enabled_by_default)
6208 protocol->is_enabled = TRUE;
6209 list_item = g_list_next(list_item);
6214 proto_set_cant_toggle(const int proto_id)
6216 protocol_t *protocol;
6218 protocol = find_protocol_by_id(proto_id);
6219 protocol->can_toggle = FALSE;
6223 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
6225 if (proto != NULL) {
6226 g_ptr_array_add(proto->fields, hfi);
6229 return proto_register_field_init(hfi, parent);
6232 /* for use with static arrays only, since we don't allocate our own copies
6233 of the header_field_info struct contained within the hf_register_info struct */
6235 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
6237 hf_register_info *ptr = hf;
6241 proto = find_protocol_by_id(parent);
6243 if (proto->fields == NULL) {
6244 proto->fields = g_ptr_array_sized_new(num_records);
6247 for (i = 0; i < num_records; i++, ptr++) {
6249 * Make sure we haven't registered this yet.
6250 * Most fields have variables associated with them
6251 * that are initialized to -1; some have array elements,
6252 * or possibly uninitialized variables, so we also allow
6253 * 0 (which is unlikely to be the field ID we get back
6254 * from "proto_register_field_init()").
6256 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
6258 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
6259 ptr->hfinfo.abbrev);
6263 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
6268 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
6273 proto = find_protocol_by_id(parent);
6275 if (proto->fields == NULL) {
6276 proto->fields = g_ptr_array_sized_new(num_records);
6279 for (i = 0; i < num_records; i++) {
6281 * Make sure we haven't registered this yet.
6283 if (hfi[i].id != -1) {
6285 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6290 proto_register_field_common(proto, &hfi[i], parent);
6295 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
6300 proto = find_protocol_by_id(parent);
6302 if (proto->fields == NULL) {
6303 proto->fields = g_ptr_array_sized_new(num_records);
6307 for (i = 0; i < num_records; i++) {
6309 * Make sure we haven't registered this yet.
6311 if (hfi[i]->id != -1) {
6313 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6318 proto_register_field_common(proto, hfi[i], parent);
6322 /* deregister already registered fields */
6324 proto_deregister_field (const int parent, gint hf_id)
6326 header_field_info *hfi;
6330 g_free(last_field_name);
6331 last_field_name = NULL;
6333 if (hf_id == -1 || hf_id == 0)
6336 proto = find_protocol_by_id (parent);
6337 if (!proto || proto->fields == NULL) {
6341 for (i = 0; i < proto->fields->len; i++) {
6342 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
6343 if (hfi->id == hf_id) {
6344 /* Found the hf_id in this protocol */
6345 g_hash_table_steal(gpa_name_map, hfi->abbrev);
6346 g_ptr_array_remove_index_fast(proto->fields, i);
6347 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
6354 proto_add_deregistered_data (void *data)
6356 g_ptr_array_add(deregistered_data, data);
6360 free_deregistered_field (gpointer data, gpointer user_data _U_)
6362 header_field_info *hfi = (header_field_info *) data;
6363 gint hf_id = hfi->id;
6365 g_free((char *)hfi->name);
6366 g_free((char *)hfi->abbrev);
6367 g_free((char *)hfi->blurb);
6370 switch (hfi->type) {
6372 /* This is just an integer represented as a pointer */
6375 protocol_t *protocol = (protocol_t *)hfi->strings;
6376 g_free((gchar *)protocol->short_name);
6380 true_false_string *tf = (true_false_string *)hfi->strings;
6381 g_free ((gchar *)tf->true_string);
6382 g_free ((gchar *)tf->false_string);
6387 if (hfi->display & BASE_UNIT_STRING) {
6388 unit_name_string *unit = (unit_name_string*)hfi->strings;
6389 g_free ((gchar *)unit->singular);
6390 g_free ((gchar *)unit->plural);
6392 val64_string *vs64 = (val64_string *)hfi->strings;
6393 while (vs64->strptr) {
6394 g_free((gchar *)vs64->strptr);
6401 /* Other Integer types */
6402 if (hfi->display & BASE_UNIT_STRING) {
6403 unit_name_string *unit = (unit_name_string*)hfi->strings;
6404 g_free ((gchar *)unit->singular);
6405 g_free ((gchar *)unit->plural);
6407 value_string *vs = (value_string *)hfi->strings;
6408 while (vs->strptr) {
6409 g_free((gchar *)vs->strptr);
6416 if (hfi->type != FT_FRAMENUM) {
6417 g_free((void *)hfi->strings);
6421 if (hfi->parent == -1)
6422 g_slice_free(header_field_info, hfi);
6424 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
6428 free_deregistered_data (gpointer data, gpointer user_data _U_)
6433 /* free deregistered fields and data */
6435 proto_free_deregistered_fields (void)
6437 expert_free_deregistered_expertinfos();
6439 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
6440 g_ptr_array_free(deregistered_fields, TRUE);
6441 deregistered_fields = g_ptr_array_new();
6443 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
6444 g_ptr_array_free(deregistered_data, TRUE);
6445 deregistered_data = g_ptr_array_new();
6448 /* chars allowed in field abbrev */
6450 const guint8 fld_abbrev_chars[256] = {
6451 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
6452 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
6453 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
6454 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
6455 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
6456 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
6457 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
6458 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
6459 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
6460 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
6461 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
6462 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
6463 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
6464 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
6465 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
6466 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
6469 static const value_string hf_display[] = {
6470 { BASE_NONE, "BASE_NONE" },
6471 { BASE_DEC, "BASE_DEC" },
6472 { BASE_HEX, "BASE_HEX" },
6473 { BASE_OCT, "BASE_OCT" },
6474 { BASE_DEC_HEX, "BASE_DEC_HEX" },
6475 { BASE_HEX_DEC, "BASE_HEX_DEC" },
6476 { BASE_CUSTOM, "BASE_CUSTOM" },
6477 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
6478 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
6479 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
6480 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
6481 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
6482 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
6483 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
6484 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
6485 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
6486 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
6487 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
6488 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
6489 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
6490 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
6491 /* Alias: BASE_NONE { BASE_FLOAT, "BASE_FLOAT" }, */
6492 /* Alias: BASE_NONE { STR_ASCII, "STR_ASCII" }, */
6493 { STR_UNICODE, "STR_UNICODE" },
6494 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
6495 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
6496 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
6497 { BASE_PT_UDP, "BASE_PT_UDP" },
6498 { BASE_PT_TCP, "BASE_PT_TCP" },
6499 { BASE_PT_DCCP, "BASE_PT_DCCP" },
6500 { BASE_PT_SCTP, "BASE_PT_SCTP" },
6503 const char* proto_field_display_to_string(int field_display)
6505 return val_to_str_const(field_display, hf_display, "Unknown");
6508 static inline port_type
6509 display_to_port_type(field_display_e e)
6526 /* temporary function containing assert part for easier profiling */
6528 tmp_fld_check_assert(header_field_info *hfinfo)
6532 /* The field must have a name (with length > 0) */
6533 if (!hfinfo->name || !hfinfo->name[0]) {
6535 /* Try to identify the field */
6536 g_error("Field (abbrev='%s') does not have a name\n",
6540 g_error("Field does not have a name (nor an abbreviation)\n");
6543 /* fields with an empty string for an abbreviation aren't filterable */
6544 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
6545 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
6547 /* These types of fields are allowed to have value_strings,
6548 * true_false_strings or a protocol_t struct
6550 if (hfinfo->strings != NULL) {
6551 switch(hfinfo->type) {
6575 //allowed to support string if its a unit decsription
6576 if (hfinfo->display & BASE_UNIT_STRING)
6581 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
6582 " (which is not allowed to have strings)\n",
6583 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
6587 /* TODO: This check may slow down startup, and output quite a few warnings.
6588 It would be good to be able to enable this (and possibly other checks?)
6589 in non-release builds. */
6591 /* Check for duplicate value_string values.
6592 There are lots that have the same value *and* string, so for now only
6593 report those that have same value but different string. */
6594 if ((hfinfo->strings != NULL) &&
6595 !(hfinfo->display & BASE_RANGE_STRING) &&
6596 !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
6598 (hfinfo->type == FT_CHAR) ||
6599 (hfinfo->type == FT_UINT8) ||
6600 (hfinfo->type == FT_UINT16) ||
6601 (hfinfo->type == FT_UINT24) ||
6602 (hfinfo->type == FT_UINT32) ||
6603 (hfinfo->type == FT_INT8) ||
6604 (hfinfo->type == FT_INT16) ||
6605 (hfinfo->type == FT_INT24) ||
6606 (hfinfo->type == FT_INT32) ||
6607 (hfinfo->type == FT_FRAMENUM) )) {
6610 const value_string *start_values;
6611 const value_string *current;
6613 if (hfinfo->display & BASE_EXT_STRING)
6614 start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
6616 start_values = (const value_string*)hfinfo->strings;
6617 current = start_values;
6619 for (n=0; current; n++, current++) {
6620 /* Drop out if we reached the end. */
6621 if ((current->value == 0) && (current->strptr == NULL)) {
6625 /* Check value against all previous */
6626 for (m=0; m < n; m++) {
6627 /* There are lots of duplicates with the same string,
6628 so only report if different... */
6629 if ((start_values[m].value == current->value) &&
6630 (strcmp(start_values[m].strptr, current->strptr) != 0)) {
6631 ws_g_warning("Field '%s' (%s) has a conflicting entry in its"
6632 " value_string: %u is at indices %u (%s) and %u (%s))\n",
6633 hfinfo->name, hfinfo->abbrev,
6634 current->value, m, start_values[m].strptr, n, current->strptr);
6642 switch (hfinfo->type) {
6645 /* Require the char type to have BASE_HEX, BASE_OCT,
6646 * BASE_CUSTOM, or BASE_NONE as its base.
6648 * If the display value is BASE_NONE and there is a
6649 * strings conversion then the dissector writer is
6650 * telling us that the field's numerical value is
6651 * meaningless; we'll avoid showing the value to the
6654 switch (FIELD_DISPLAY(hfinfo->display)) {
6657 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6660 if (hfinfo->strings == NULL)
6661 g_error("Field '%s' (%s) is an integral value (%s)"
6662 " but is being displayed as BASE_NONE but"
6663 " without a strings conversion",
6664 hfinfo->name, hfinfo->abbrev,
6665 ftype_name(hfinfo->type));
6668 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6669 g_error("Field '%s' (%s) is a character value (%s)"
6670 " but is being displayed as %s\n",
6671 hfinfo->name, hfinfo->abbrev,
6672 ftype_name(hfinfo->type), tmp_str);
6673 wmem_free(NULL, tmp_str);
6675 if (hfinfo->display & BASE_UNIT_STRING) {
6676 g_error("Field '%s' (%s) is a character value (%s) but has a unit string\n",
6677 hfinfo->name, hfinfo->abbrev,
6678 ftype_name(hfinfo->type));
6689 /* Hexadecimal and octal are, in printf() and everywhere
6690 * else, unsigned so don't allow dissectors to register a
6691 * signed field to be displayed unsigned. (Else how would
6692 * we display negative values?)
6694 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6699 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6700 g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
6701 hfinfo->name, hfinfo->abbrev,
6702 ftype_name(hfinfo->type), tmp_str);
6703 wmem_free(NULL, tmp_str);
6714 if (IS_BASE_PORT(hfinfo->display)) {
6715 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6716 if (hfinfo->type != FT_UINT16) {
6717 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
6718 hfinfo->name, hfinfo->abbrev,
6719 tmp_str, ftype_name(hfinfo->type));
6721 if (hfinfo->strings != NULL) {
6722 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
6723 hfinfo->name, hfinfo->abbrev,
6724 ftype_name(hfinfo->type), tmp_str);
6726 if (hfinfo->bitmask != 0) {
6727 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
6728 hfinfo->name, hfinfo->abbrev,
6729 ftype_name(hfinfo->type), tmp_str);
6731 wmem_free(NULL, tmp_str);
6735 /* Require integral types (other than frame number,
6736 * which is always displayed in decimal) to have a
6739 * If the display value is BASE_NONE and there is a
6740 * strings conversion then the dissector writer is
6741 * telling us that the field's numerical value is
6742 * meaningless; we'll avoid showing the value to the
6745 switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6751 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6754 if (hfinfo->strings == NULL) {
6755 g_error("Field '%s' (%s) is an integral value (%s)"
6756 " but is being displayed as BASE_NONE but"
6757 " without a strings conversion",
6758 hfinfo->name, hfinfo->abbrev,
6759 ftype_name(hfinfo->type));
6764 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6765 g_error("Field '%s' (%s) is an integral value (%s)"
6766 " but is being displayed as %s\n",
6767 hfinfo->name, hfinfo->abbrev,
6768 ftype_name(hfinfo->type), tmp_str);
6769 wmem_free(NULL, tmp_str);
6773 /* Require bytes to have a "display type" that could
6774 * add a character between displayed bytes.
6776 switch (FIELD_DISPLAY(hfinfo->display)) {
6784 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6785 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",
6786 hfinfo->name, hfinfo->abbrev, tmp_str);
6787 wmem_free(NULL, tmp_str);
6789 if (hfinfo->bitmask != 0)
6790 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6791 hfinfo->name, hfinfo->abbrev,
6792 ftype_name(hfinfo->type));
6793 if (hfinfo->strings != NULL)
6794 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6795 hfinfo->name, hfinfo->abbrev,
6796 ftype_name(hfinfo->type));
6801 if (hfinfo->display != BASE_NONE) {
6802 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6803 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6804 hfinfo->name, hfinfo->abbrev,
6805 ftype_name(hfinfo->type), tmp_str);
6806 wmem_free(NULL, tmp_str);
6808 if (hfinfo->bitmask != 0)
6809 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6810 hfinfo->name, hfinfo->abbrev,
6811 ftype_name(hfinfo->type));
6817 case FT_ABSOLUTE_TIME:
6818 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
6819 hfinfo->display == ABSOLUTE_TIME_UTC ||
6820 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
6821 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6822 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
6823 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
6824 wmem_free(NULL, tmp_str);
6826 if (hfinfo->bitmask != 0)
6827 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6828 hfinfo->name, hfinfo->abbrev,
6829 ftype_name(hfinfo->type));
6834 case FT_UINT_STRING:
6836 switch (hfinfo->display) {
6842 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6843 g_error("Field '%s' (%s) is an string value (%s)"
6844 " but is being displayed as %s\n",
6845 hfinfo->name, hfinfo->abbrev,
6846 ftype_name(hfinfo->type), tmp_str);
6847 wmem_free(NULL, tmp_str);
6850 if (hfinfo->bitmask != 0)
6851 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6852 hfinfo->name, hfinfo->abbrev,
6853 ftype_name(hfinfo->type));
6854 if (hfinfo->strings != NULL)
6855 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6856 hfinfo->name, hfinfo->abbrev,
6857 ftype_name(hfinfo->type));
6861 switch (hfinfo->display) {
6867 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6868 g_error("Field '%s' (%s) is an IPv4 value (%s)"
6869 " but is being displayed as %s\n",
6870 hfinfo->name, hfinfo->abbrev,
6871 ftype_name(hfinfo->type), tmp_str);
6872 wmem_free(NULL, tmp_str);
6878 if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
6879 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6880 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6881 hfinfo->name, hfinfo->abbrev,
6882 ftype_name(hfinfo->type),
6884 wmem_free(NULL, tmp_str);
6886 if (hfinfo->bitmask != 0)
6887 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6888 hfinfo->name, hfinfo->abbrev,
6889 ftype_name(hfinfo->type));
6890 if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_UNIT_STRING)))
6891 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6892 hfinfo->name, hfinfo->abbrev,
6893 ftype_name(hfinfo->type));
6896 if (hfinfo->display != BASE_NONE) {
6897 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6898 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6899 hfinfo->name, hfinfo->abbrev,
6900 ftype_name(hfinfo->type),
6902 wmem_free(NULL, tmp_str);
6904 if (hfinfo->bitmask != 0)
6905 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6906 hfinfo->name, hfinfo->abbrev,
6907 ftype_name(hfinfo->type));
6908 if (hfinfo->strings != NULL)
6909 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6910 hfinfo->name, hfinfo->abbrev,
6911 ftype_name(hfinfo->type));
6916 #ifdef ENABLE_CHECK_FILTER
6918 _ftype_common(enum ftenum type)
6942 case FT_UINT_STRING:
6955 case FT_ABSOLUTE_TIME:
6956 case FT_RELATIVE_TIME:
6957 return FT_ABSOLUTE_TIME;
6966 register_type_length_mismatch(void)
6968 static ei_register_info ei[] = {
6969 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
6970 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
6973 expert_module_t* expert_type_length_mismatch;
6975 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
6977 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
6978 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
6980 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
6981 disabling them makes no sense. */
6982 proto_set_cant_toggle(proto_type_length_mismatch);
6986 register_number_string_decoding_error(void)
6988 static ei_register_info ei[] = {
6989 { &ei_number_string_decoding_failed_error,
6990 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
6991 "Failed to decode number from string", EXPFILL
6994 { &ei_number_string_decoding_erange_error,
6995 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
6996 "Decoded number from string is out of valid range", EXPFILL
7001 expert_module_t* expert_number_string_decoding_error;
7003 proto_number_string_decoding_error =
7004 proto_register_protocol("Number-String Decoding Error",
7005 "Number-string decoding error",
7006 "_ws.number_string.decoding_error");
7008 expert_number_string_decoding_error =
7009 expert_register_protocol(proto_number_string_decoding_error);
7010 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
7012 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
7013 disabling them makes no sense. */
7014 proto_set_cant_toggle(proto_number_string_decoding_error);
7017 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (183000+PRE_ALLOC_EXPERT_FIELDS_MEM)
7019 proto_register_field_init(header_field_info *hfinfo, const int parent)
7022 tmp_fld_check_assert(hfinfo);
7024 hfinfo->parent = parent;
7025 hfinfo->same_name_next = NULL;
7026 hfinfo->same_name_prev_id = -1;
7028 /* if we always add and never delete, then id == len - 1 is correct */
7029 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
7030 if (!gpa_hfinfo.hfi) {
7031 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
7032 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
7034 gpa_hfinfo.allocated_len += 1000;
7035 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
7036 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
7037 /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
7040 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
7042 hfinfo->id = gpa_hfinfo.len - 1;
7044 /* if we have real names, enter this field in the name tree */
7045 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
7047 header_field_info *same_name_next_hfinfo;
7050 /* Check that the filter name (abbreviation) is legal;
7051 * it must contain only alphanumerics, '-', "_", and ".". */
7052 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
7054 if (g_ascii_isprint(c))
7055 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
7057 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
7058 DISSECTOR_ASSERT_NOT_REACHED();
7061 /* We allow multiple hfinfo's to be registered under the same
7062 * abbreviation. This was done for X.25, as, depending
7063 * on whether it's modulo-8 or modulo-128 operation,
7064 * some bitfield fields may be in different bits of
7065 * a byte, and we want to be able to refer to that field
7066 * with one name regardless of whether the packets
7067 * are modulo-8 or modulo-128 packets. */
7069 same_name_hfinfo = NULL;
7071 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
7072 /* GLIB 2.x - if it is already present
7073 * the previous hfinfo with the same name is saved
7074 * to same_name_hfinfo by value destroy callback */
7075 if (same_name_hfinfo) {
7076 /* There's already a field with this name.
7077 * Put the current field *before* that field
7078 * in the list of fields with this name, Thus,
7079 * we end up with an effectively
7080 * doubly-linked-list of same-named hfinfo's,
7081 * with the head of the list (stored in the
7082 * hash) being the last seen hfinfo.
7084 same_name_next_hfinfo =
7085 same_name_hfinfo->same_name_next;
7087 hfinfo->same_name_next = same_name_next_hfinfo;
7088 if (same_name_next_hfinfo)
7089 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
7091 same_name_hfinfo->same_name_next = hfinfo;
7092 hfinfo->same_name_prev_id = same_name_hfinfo->id;
7093 #ifdef ENABLE_CHECK_FILTER
7094 while (same_name_hfinfo) {
7095 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
7096 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));
7097 same_name_hfinfo = same_name_hfinfo->same_name_next;
7107 proto_register_subtree_array(gint *const *indices, const int num_indices)
7110 gint *const *ptr = indices;
7113 * If we've already allocated the array of tree types, expand
7114 * it; this lets plugins such as mate add tree types after
7115 * the initial startup. (If we haven't already allocated it,
7116 * we don't allocate it; on the first pass, we just assign
7117 * ett values and keep track of how many we've assigned, and
7118 * when we're finished registering all dissectors we allocate
7119 * the array, so that we do only one allocation rather than
7120 * wasting CPU time and memory by growing the array for each
7121 * dissector that registers ett values.)
7123 if (tree_is_expanded != NULL) {
7124 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
7126 /* set new items to 0 */
7127 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
7128 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
7129 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
7133 * Assign "num_indices" subtree numbers starting at "num_tree_types",
7134 * returning the indices through the pointers in the array whose
7135 * first element is pointed to by "indices", and update
7136 * "num_tree_types" appropriately.
7138 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
7140 /* g_error will terminate the program */
7141 g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
7142 " This is a development error:"
7143 " Either the subtree item type has already been assigned or"
7144 " was not initialized to -1.");
7146 **ptr = num_tree_types;
7151 label_concat(char *label_str, gsize pos, const char *str)
7153 if (pos < ITEM_LABEL_LENGTH)
7154 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
7160 label_mark_truncated(char *label_str, gsize name_pos)
7162 static const char trunc_str[] = " [truncated]";
7163 const size_t trunc_len = sizeof(trunc_str)-1;
7166 /* ..... field_name: dataaaaaaaaaaaaa
7170 * ..... field_name [truncated]: dataaaaaaaaaaaaa
7172 * name_pos==0 means that we have only data or only a field_name
7175 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
7176 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
7177 memcpy(label_str + name_pos, trunc_str, trunc_len);
7179 /* in general, label_str is UTF-8
7180 we can truncate it only at the beginning of a new character
7181 we go backwards from the byte right after our buffer and
7182 find the next starting byte of a UTF-8 character, this is
7184 there's no need to use g_utf8_find_prev_char(), the search
7185 will always succeed since we copied trunc_str into the
7187 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH]);
7190 } else if (name_pos < ITEM_LABEL_LENGTH)
7191 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
7195 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
7199 /* "%s: %s", hfinfo->name, text */
7200 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
7201 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
7202 pos = label_concat(label_str, pos, ": ");
7203 pos = label_concat(label_str, pos, text ? text : "(null)");
7206 if (pos >= ITEM_LABEL_LENGTH) {
7207 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7208 label_mark_truncated(label_str, name_pos);
7215 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
7219 /* "%s: %s (%s)", hfinfo->name, text, descr */
7220 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
7221 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
7222 pos = label_concat(label_str, pos, ": ");
7223 if (hfinfo->display & BASE_UNIT_STRING) {
7224 pos = label_concat(label_str, pos, descr ? descr : "(null)");
7225 pos = label_concat(label_str, pos, text ? text : "(null)");
7227 pos = label_concat(label_str, pos, text ? text : "(null)");
7228 pos = label_concat(label_str, pos, " (");
7229 pos = label_concat(label_str, pos, descr ? descr : "(null)");
7230 pos = label_concat(label_str, pos, ")");
7234 if (pos >= ITEM_LABEL_LENGTH) {
7235 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7236 label_mark_truncated(label_str, name_pos);
7243 proto_item_fill_label(field_info *fi, gchar *label_str)
7245 header_field_info *hfinfo;
7249 ipv4_addr_and_mask *ipv4;
7251 guint32 n_addr; /* network-order IPv4 address */
7260 /* XXX: Check validity of hfinfo->type */
7264 hfinfo = fi->hfinfo;
7266 switch (hfinfo->type) {
7269 g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
7273 fill_label_boolean(fi, label_str);
7278 bytes = (guint8 *)fvalue_get(&fi->value);
7281 switch(hfinfo->display)
7284 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
7287 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
7290 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
7293 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7297 if (prefs.display_byte_fields_with_spaces)
7299 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7303 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
7307 label_fill(label_str, 0, hfinfo, str);
7308 wmem_free(NULL, str);
7310 if (hfinfo->display & BASE_ALLOW_ZERO) {
7311 label_fill(label_str, 0, hfinfo, "<none>");
7313 label_fill(label_str, 0, hfinfo, "<MISSING>");
7319 if (hfinfo->bitmask) {
7320 fill_label_bitfield_char(fi, label_str);
7322 fill_label_char(fi, label_str);
7326 /* Four types of integers to take care of:
7327 * Bitfield, with val_string
7328 * Bitfield, w/o val_string
7329 * Non-bitfield, with val_string
7330 * Non-bitfield, w/o val_string
7336 if (hfinfo->bitmask) {
7337 fill_label_bitfield(fi, label_str, FALSE);
7339 fill_label_number(fi, label_str, FALSE);
7344 fill_label_number(fi, label_str, FALSE);
7351 if (hfinfo->bitmask) {
7352 fill_label_bitfield64(fi, label_str, FALSE);
7354 fill_label_number64(fi, label_str, FALSE);
7362 if (hfinfo->bitmask) {
7363 fill_label_bitfield(fi, label_str, TRUE);
7365 fill_label_number(fi, label_str, TRUE);
7373 if (hfinfo->bitmask) {
7374 fill_label_bitfield64(fi, label_str, TRUE);
7376 fill_label_number64(fi, label_str, TRUE);
7381 double d_value = fvalue_get_floating(&fi->value);
7382 if (hfinfo->display & BASE_UNIT_STRING) {
7383 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7384 "%s: %." G_STRINGIFY(FLT_DIG) "g%s",
7385 hfinfo->name, d_value,
7386 unit_name_string_get_value64((guint64)d_value, (unit_name_string*)hfinfo->strings));
7388 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7389 "%s: %." G_STRINGIFY(FLT_DIG) "g",
7390 hfinfo->name, d_value);
7396 double d_value = fvalue_get_floating(&fi->value);
7397 if (hfinfo->display & BASE_UNIT_STRING) {
7398 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7399 "%s: %." G_STRINGIFY(DBL_DIG) "g%s",
7400 hfinfo->name, d_value,
7401 unit_name_string_get_value64((guint64)d_value, (unit_name_string*)hfinfo->strings));
7403 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7404 "%s: %." G_STRINGIFY(DBL_DIG) "g",
7405 hfinfo->name, d_value);
7410 case FT_ABSOLUTE_TIME:
7411 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
7412 label_fill(label_str, 0, hfinfo, tmp);
7413 wmem_free(NULL, tmp);
7416 case FT_RELATIVE_TIME:
7417 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
7418 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7419 "%s: %s seconds", hfinfo->name, tmp);
7420 wmem_free(NULL, tmp);
7424 integer = fvalue_get_uinteger(&fi->value);
7425 tmp = get_ipxnet_name(NULL, integer);
7426 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7427 "%s: %s (0x%08X)", hfinfo->name,
7429 wmem_free(NULL, tmp);
7433 addr.type = AT_AX25;
7434 addr.len = AX25_ADDR_LEN;
7435 addr.data = (guint8 *)fvalue_get(&fi->value);
7437 addr_str = (char*)address_to_str(NULL, &addr);
7438 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7439 "%s: %s", hfinfo->name, addr_str);
7440 wmem_free(NULL, addr_str);
7444 addr.type = vines_address_type;
7445 addr.len = VINES_ADDR_LEN;
7446 addr.data = (guint8 *)fvalue_get(&fi->value);
7448 addr_str = (char*)address_to_str(NULL, &addr);
7449 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7450 "%s: %s", hfinfo->name, addr_str);
7451 wmem_free(NULL, addr_str);
7455 bytes = (guint8 *)fvalue_get(&fi->value);
7457 addr.type = AT_ETHER;
7461 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7462 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7463 "%s: %s", hfinfo->name, addr_str);
7464 wmem_free(NULL, addr_str);
7468 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&fi->value);
7469 n_addr = ipv4_get_net_order_addr(ipv4);
7471 addr.type = AT_IPv4;
7473 addr.data = &n_addr;
7475 if (hfinfo->display == BASE_NETMASK)
7477 addr_str = (char*)address_to_str(NULL, &addr);
7481 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7483 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7484 "%s: %s", hfinfo->name, addr_str);
7485 wmem_free(NULL, addr_str);
7489 bytes = (guint8 *)fvalue_get(&fi->value);
7491 addr.type = AT_IPv6;
7495 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7496 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7497 "%s: %s", hfinfo->name, addr_str);
7498 wmem_free(NULL, addr_str);
7502 addr.type = AT_FCWWN;
7503 addr.len = FCWWN_ADDR_LEN;
7504 addr.data = (guint8 *)fvalue_get(&fi->value);
7506 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7507 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7508 "%s: %s", hfinfo->name, addr_str);
7509 wmem_free(NULL, addr_str);
7513 guid = (e_guid_t *)fvalue_get(&fi->value);
7514 tmp = guid_to_str(NULL, guid);
7515 label_fill(label_str, 0, hfinfo, tmp);
7516 wmem_free(NULL, tmp);
7520 bytes = (guint8 *)fvalue_get(&fi->value);
7521 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7522 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7524 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7525 wmem_free(NULL, name);
7527 label_fill(label_str, 0, hfinfo, tmp);
7529 wmem_free(NULL, tmp);
7533 bytes = (guint8 *)fvalue_get(&fi->value);
7534 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7535 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7537 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7538 wmem_free(NULL, name);
7540 label_fill(label_str, 0, hfinfo, tmp);
7542 wmem_free(NULL, tmp);
7546 bytes = (guint8 *)fvalue_get(&fi->value);
7547 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
7548 label_fill(label_str, 0, hfinfo, tmp);
7549 wmem_free(NULL, tmp);
7553 integer64 = fvalue_get_uinteger64(&fi->value);
7554 addr_str = eui64_to_str(NULL, integer64);
7555 tmp = (char*)eui64_to_display(NULL, integer64);
7556 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
7557 wmem_free(NULL, tmp);
7558 wmem_free(NULL, addr_str);
7562 case FT_UINT_STRING:
7564 bytes = (guint8 *)fvalue_get(&fi->value);
7565 label_fill(label_str, 0, hfinfo, hfinfo_format_text(hfinfo, bytes));
7568 case FT_IEEE_11073_SFLOAT:
7569 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7570 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7573 wmem_free(NULL, tmp);
7575 case FT_IEEE_11073_FLOAT:
7576 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7577 g_snprintf(label_str, ITEM_LABEL_LENGTH,
7580 wmem_free(NULL, tmp);
7584 g_error("hfinfo->type %d (%s) not handled\n",
7585 hfinfo->type, ftype_name(hfinfo->type));
7586 DISSECTOR_ASSERT_NOT_REACHED();
7592 fill_label_boolean(field_info *fi, gchar *label_str)
7594 char *p = label_str;
7595 int bitfield_byte_length = 0, bitwidth;
7596 guint64 unshifted_value;
7599 header_field_info *hfinfo = fi->hfinfo;
7600 const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
7602 if (hfinfo->strings) {
7603 tfstring = (const struct true_false_string*) hfinfo->strings;
7606 value = fvalue_get_uinteger64(&fi->value);
7607 if (hfinfo->bitmask) {
7608 /* Figure out the bit width */
7609 bitwidth = hfinfo_container_bitwidth(hfinfo);
7612 unshifted_value = value;
7613 unshifted_value <<= hfinfo_bitshift(hfinfo);
7615 /* Create the bitfield first */
7616 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7617 bitfield_byte_length = (int) (p - label_str);
7620 /* Fill in the textual info */
7621 label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
7625 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
7627 if (hfinfo->display & BASE_RANGE_STRING)
7628 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
7630 if (hfinfo->display & BASE_EXT_STRING)
7631 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
7633 if (hfinfo->display & BASE_VAL64_STRING)
7634 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7636 if (hfinfo->display & BASE_UNIT_STRING)
7637 return unit_name_string_get_value(value, (struct unit_name_string*) hfinfo->strings);
7639 return try_val_to_str(value, (const value_string *) hfinfo->strings);
7643 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
7645 if (hfinfo->display & BASE_VAL64_STRING)
7646 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7648 if (hfinfo->display & BASE_RANGE_STRING)
7649 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
7651 if (hfinfo->display & BASE_UNIT_STRING)
7652 return unit_name_string_get_value64(value, (struct unit_name_string*) hfinfo->strings);
7654 /* If this is reached somebody registered a 64-bit field with a 32-bit
7655 * value-string, which isn't right. */
7656 DISSECTOR_ASSERT_NOT_REACHED();
7658 /* This is necessary to squelch MSVC errors; is there
7659 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
7665 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
7667 const char *str = hf_try_val_to_str(value, hfinfo);
7669 return (str) ? str : unknown_str;
7673 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
7675 const char *str = hf_try_val64_to_str(value, hfinfo);
7677 return (str) ? str : unknown_str;
7680 /* Fills data for bitfield chars with val_strings */
7682 fill_label_bitfield_char(field_info *fi, gchar *label_str)
7685 int bitfield_byte_length, bitwidth;
7686 guint32 unshifted_value;
7692 header_field_info *hfinfo = fi->hfinfo;
7694 /* Figure out the bit width */
7695 bitwidth = hfinfo_container_bitwidth(hfinfo);
7698 value = fvalue_get_uinteger(&fi->value);
7700 unshifted_value = value;
7701 if (hfinfo->bitmask) {
7702 unshifted_value <<= hfinfo_bitshift(hfinfo);
7705 /* Create the bitfield first */
7706 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7707 bitfield_byte_length = (int) (p - label_str);
7709 /* Fill in the textual info using stored (shifted) value */
7710 if (hfinfo->display == BASE_CUSTOM) {
7711 gchar tmp[ITEM_LABEL_LENGTH];
7712 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7714 DISSECTOR_ASSERT(fmtfunc);
7715 fmtfunc(tmp, value);
7716 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7718 else if (hfinfo->strings) {
7719 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7721 out = hfinfo_char_vals_format(hfinfo, buf, value);
7722 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7723 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7725 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7728 out = hfinfo_char_value_format(hfinfo, buf, value);
7730 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7734 /* Fills data for bitfield ints with val_strings */
7736 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
7739 int bitfield_byte_length, bitwidth;
7740 guint32 unshifted_value;
7746 header_field_info *hfinfo = fi->hfinfo;
7748 /* Figure out the bit width */
7749 bitwidth = hfinfo_container_bitwidth(hfinfo);
7753 value = fvalue_get_sinteger(&fi->value);
7755 value = fvalue_get_uinteger(&fi->value);
7757 unshifted_value = value;
7758 if (hfinfo->bitmask) {
7759 unshifted_value <<= hfinfo_bitshift(hfinfo);
7762 /* Create the bitfield first */
7763 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7764 bitfield_byte_length = (int) (p - label_str);
7766 /* Fill in the textual info using stored (shifted) value */
7767 if (hfinfo->display == BASE_CUSTOM) {
7768 gchar tmp[ITEM_LABEL_LENGTH];
7769 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7771 DISSECTOR_ASSERT(fmtfunc);
7772 fmtfunc(tmp, value);
7773 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7775 else if (hfinfo->strings) {
7776 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7778 out = hfinfo_number_vals_format(hfinfo, buf, value);
7779 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7780 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7782 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7785 out = hfinfo_number_value_format(hfinfo, buf, value);
7787 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7792 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
7795 int bitfield_byte_length, bitwidth;
7796 guint64 unshifted_value;
7802 header_field_info *hfinfo = fi->hfinfo;
7804 /* Figure out the bit width */
7805 bitwidth = hfinfo_container_bitwidth(hfinfo);
7809 value = fvalue_get_sinteger64(&fi->value);
7811 value = fvalue_get_uinteger64(&fi->value);
7813 unshifted_value = value;
7814 if (hfinfo->bitmask) {
7815 unshifted_value <<= hfinfo_bitshift(hfinfo);
7818 /* Create the bitfield first */
7819 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7820 bitfield_byte_length = (int) (p - label_str);
7822 /* Fill in the textual info using stored (shifted) value */
7823 if (hfinfo->display == BASE_CUSTOM) {
7824 gchar tmp[ITEM_LABEL_LENGTH];
7825 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7827 DISSECTOR_ASSERT(fmtfunc64);
7828 fmtfunc64(tmp, value);
7829 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7831 else if (hfinfo->strings) {
7832 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7834 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7835 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7836 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7838 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7841 out = hfinfo_number_value_format64(hfinfo, buf, value);
7843 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7848 fill_label_char(field_info *fi, gchar *label_str)
7850 header_field_info *hfinfo = fi->hfinfo;
7856 value = fvalue_get_uinteger(&fi->value);
7858 /* Fill in the textual info */
7859 if (hfinfo->display == BASE_CUSTOM) {
7860 gchar tmp[ITEM_LABEL_LENGTH];
7861 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7863 DISSECTOR_ASSERT(fmtfunc);
7864 fmtfunc(tmp, value);
7865 label_fill(label_str, 0, hfinfo, tmp);
7867 else if (hfinfo->strings) {
7868 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7870 out = hfinfo_char_vals_format(hfinfo, buf, value);
7871 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7874 out = hfinfo_char_value_format(hfinfo, buf, value);
7876 label_fill(label_str, 0, hfinfo, out);
7881 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
7883 header_field_info *hfinfo = fi->hfinfo;
7890 value = fvalue_get_sinteger(&fi->value);
7892 value = fvalue_get_uinteger(&fi->value);
7894 /* Fill in the textual info */
7895 if (hfinfo->display == BASE_CUSTOM) {
7896 gchar tmp[ITEM_LABEL_LENGTH];
7897 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7899 DISSECTOR_ASSERT(fmtfunc);
7900 fmtfunc(tmp, value);
7901 label_fill(label_str, 0, hfinfo, tmp);
7903 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7905 * It makes no sense to have a value-string table for a
7906 * frame-number field - they're just integers giving
7907 * the ordinal frame number.
7909 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7911 out = hfinfo_number_vals_format(hfinfo, buf, value);
7912 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7913 label_fill(label_str, 0, hfinfo, val_str);
7915 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7917 else if (IS_BASE_PORT(hfinfo->display)) {
7918 gchar tmp[ITEM_LABEL_LENGTH];
7920 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
7921 display_to_port_type((field_display_e)hfinfo->display), value);
7922 label_fill(label_str, 0, hfinfo, tmp);
7925 out = hfinfo_number_value_format(hfinfo, buf, value);
7927 label_fill(label_str, 0, hfinfo, out);
7932 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
7934 header_field_info *hfinfo = fi->hfinfo;
7941 value = fvalue_get_sinteger64(&fi->value);
7943 value = fvalue_get_uinteger64(&fi->value);
7945 /* Fill in the textual info */
7946 if (hfinfo->display == BASE_CUSTOM) {
7947 gchar tmp[ITEM_LABEL_LENGTH];
7948 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7950 DISSECTOR_ASSERT(fmtfunc64);
7951 fmtfunc64(tmp, value);
7952 label_fill(label_str, 0, hfinfo, tmp);
7954 else if (hfinfo->strings) {
7955 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7957 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7958 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7959 label_fill(label_str, 0, hfinfo, val_str);
7961 label_fill_descr(label_str, 0, hfinfo, val_str, out);
7964 out = hfinfo_number_value_format64(hfinfo, buf, value);
7966 label_fill(label_str, 0, hfinfo, out);
7971 hfinfo_bitshift(const header_field_info *hfinfo)
7973 return ws_ctz(hfinfo->bitmask);
7977 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
7979 if (!hfinfo->bitmask) {
7983 /* ilog2 = first set bit, ctz = last set bit */
7984 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
7988 hfinfo_type_bitwidth(enum ftenum type)
8027 DISSECTOR_ASSERT_NOT_REACHED();
8035 hfinfo_container_bitwidth(const header_field_info *hfinfo)
8037 if (!hfinfo->bitmask) {
8041 if (hfinfo->type == FT_BOOLEAN) {
8042 return hfinfo->display; /* hacky? :) */
8045 return hfinfo_type_bitwidth(hfinfo->type);
8049 hfinfo_hex_digits(const header_field_info *hfinfo)
8053 /* If we have a bitmask, hfinfo->type is the width of the container, so not
8054 * appropriate to determine the number of hex digits for the field.
8055 * So instead, we compute it from the bitmask.
8057 if (hfinfo->bitmask != 0) {
8058 bitwidth = hfinfo_mask_bitwidth(hfinfo);
8060 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
8063 /* Divide by 4, rounding up, to get number of hex digits. */
8064 return (bitwidth + 3) / 4;
8068 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
8070 char *ptr = &buf[6];
8071 static const gchar hex_digits[16] =
8072 { '0', '1', '2', '3', '4', '5', '6', '7',
8073 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
8077 /* Properly format value */
8078 if (g_ascii_isprint(value)) {
8080 * Printable, so just show the character, and, if it needs
8081 * to be escaped, escape it.
8084 if (value == '\\' || value == '\'')
8088 * Non-printable; show it as an escape sequence.
8094 * Show a NUL with only one digit.
8128 switch (display & FIELD_DISPLAY_E_MASK) {
8131 *(--ptr) = (value & 0x7) + '0';
8133 *(--ptr) = (value & 0x7) + '0';
8135 *(--ptr) = (value & 0x7) + '0';
8139 *(--ptr) = hex_digits[value & 0x0F];
8141 *(--ptr) = hex_digits[value & 0x0F];
8146 g_assert_not_reached();
8156 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
8158 char *ptr = &buf[31];
8159 gboolean isint = IS_FT_INT(hfinfo->type);
8162 /* Properly format value */
8163 switch (display & FIELD_DISPLAY_E_MASK) {
8165 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8169 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8172 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8176 return oct_to_str_back(ptr, value);
8179 return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8183 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
8186 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8193 port_with_resolution_to_str_buf(buf, 32,
8194 display_to_port_type((field_display_e)display), value);
8198 g_assert_not_reached();
8204 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
8206 char *ptr = &buf[47];
8207 gboolean isint = IS_FT_INT(hfinfo->type);
8210 /* Properly format value */
8213 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8217 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8220 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8224 return oct64_to_str_back(ptr, value);
8227 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8231 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
8234 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
8238 g_assert_not_reached();
8244 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8246 int display = hfinfo->display;
8248 if (hfinfo->type == FT_FRAMENUM) {
8250 * Frame numbers are always displayed in decimal.
8255 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8259 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8261 int display = hfinfo->display;
8263 if (hfinfo->type == FT_FRAMENUM) {
8265 * Frame numbers are always displayed in decimal.
8270 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8274 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8276 /* Get the underlying BASE_ value */
8277 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8279 return hfinfo_char_value_format_display(display, buf, value);
8283 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8285 /* Get the underlying BASE_ value */
8286 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8288 if (hfinfo->type == FT_FRAMENUM) {
8290 * Frame numbers are always displayed in decimal.
8295 if (IS_BASE_PORT(display)) {
8301 /* case BASE_DEC: */
8303 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
8308 /* case BASE_HEX: */
8314 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8318 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8320 /* Get the underlying BASE_ value */
8321 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8323 if (hfinfo->type == FT_FRAMENUM) {
8325 * Frame numbers are always displayed in decimal.
8332 /* case BASE_DEC: */
8334 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
8339 /* case BASE_HEX: */
8345 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8349 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8351 /* Get the underlying BASE_ value */
8352 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8354 return hfinfo_char_value_format_display(display, buf, value);
8358 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
8360 /* Get the underlying BASE_ value */
8361 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8363 if (display == BASE_NONE)
8366 if (display == BASE_DEC_HEX)
8368 if (display == BASE_HEX_DEC)
8371 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
8375 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
8377 /* Get the underlying BASE_ value */
8378 int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
8380 if (display == BASE_NONE)
8383 if (display == BASE_DEC_HEX)
8385 if (display == BASE_HEX_DEC)
8388 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
8392 proto_registrar_get_name(const int n)
8394 header_field_info *hfinfo;
8396 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8397 return hfinfo->name;
8401 proto_registrar_get_abbrev(const int n)
8403 header_field_info *hfinfo;
8405 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8406 return hfinfo->abbrev;
8410 proto_registrar_get_ftype(const int n)
8412 header_field_info *hfinfo;
8414 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8415 return hfinfo->type;
8419 proto_registrar_get_parent(const int n)
8421 header_field_info *hfinfo;
8423 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8424 return hfinfo->parent;
8428 proto_registrar_is_protocol(const int n)
8430 header_field_info *hfinfo;
8432 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8433 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
8436 /* Returns length of field in packet (not necessarily the length
8437 * in our internal representation, as in the case of IPv4).
8438 * 0 means undeterminable at time of registration
8439 * -1 means the field is not registered. */
8441 proto_registrar_get_length(const int n)
8443 header_field_info *hfinfo;
8445 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
8446 return ftype_length(hfinfo->type);
8449 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
8450 * it exists anywhere, or FALSE if it exists nowhere. */
8452 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
8454 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
8456 if (g_ptr_array_len(ptrs) > 0) {
8464 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
8465 * This only works if the hfindex was "primed" before the dissection
8466 * took place, as we just pass back the already-created GPtrArray*.
8467 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
8470 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
8475 if (PTREE_DATA(tree)->interesting_hfids != NULL)
8476 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
8477 GINT_TO_POINTER(id));
8483 proto_tracking_interesting_fields(const proto_tree *tree)
8485 GHashTable *interesting_hfids;
8490 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
8492 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
8495 /* Helper struct for proto_find_info() and proto_all_finfos() */
8501 /* Helper function for proto_find_info() */
8503 find_finfo(proto_node *node, gpointer data)
8505 field_info *fi = PNODE_FINFO(node);
8506 if (fi && fi->hfinfo) {
8507 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8508 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8512 /* Don't stop traversing. */
8516 /* Helper function for proto_find_first_info() */
8518 find_first_finfo(proto_node *node, gpointer data)
8520 field_info *fi = PNODE_FINFO(node);
8521 if (fi && fi->hfinfo) {
8522 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8523 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8527 /* Stop traversing. */
8531 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
8532 * This works on any proto_tree, primed or unprimed, but actually searches
8533 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8534 * The caller does need to free the returned GPtrArray with
8535 * g_ptr_array_free(<array>, TRUE).
8538 proto_find_finfo(proto_tree *tree, const int id)
8542 ffdata.array = g_ptr_array_new();
8545 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
8547 return ffdata.array;
8550 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
8551 * This works on any proto_tree, primed or unprimed, but actually searches
8552 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8553 * The caller does need to free the returned GPtrArray with
8554 * g_ptr_array_free(<array>, TRUE).
8557 proto_find_first_finfo(proto_tree *tree, const int id)
8561 ffdata.array = g_ptr_array_new();
8564 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
8566 return ffdata.array;
8569 /* Helper function for proto_all_finfos() */
8571 every_finfo(proto_node *node, gpointer data)
8573 field_info *fi = PNODE_FINFO(node);
8574 if (fi && fi->hfinfo) {
8575 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8578 /* Don't stop traversing. */
8582 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
8584 proto_all_finfos(proto_tree *tree)
8588 /* Pre allocate enough space to hold all fields in most cases */
8589 ffdata.array = g_ptr_array_sized_new(512);
8592 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
8594 return ffdata.array;
8605 check_for_offset(proto_node *node, gpointer data)
8607 field_info *fi = PNODE_FINFO(node);
8608 offset_search_t *offsearch = (offset_search_t *)data;
8610 /* !fi == the top most container node which holds nothing */
8611 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
8612 if (offsearch->offset >= (guint) fi->start &&
8613 offsearch->offset < (guint) (fi->start + fi->length)) {
8615 offsearch->finfo = fi;
8616 return FALSE; /* keep traversing */
8619 return FALSE; /* keep traversing */
8622 /* Search a proto_tree backwards (from leaves to root) looking for the field
8623 * whose start/length occupies 'offset' */
8624 /* XXX - I couldn't find an easy way to search backwards, so I search
8625 * forwards, w/o stopping. Therefore, the last finfo I find will the be
8626 * the one I want to return to the user. This algorithm is inefficient
8627 * and could be re-done, but I'd have to handle all the children and
8628 * siblings of each node myself. When I have more time I'll do that.
8631 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
8633 offset_search_t offsearch;
8635 offsearch.offset = offset;
8636 offsearch.finfo = NULL;
8637 offsearch.tvb = tvb;
8639 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
8641 return offsearch.finfo;
8646 check_for_undecoded(proto_node *node, gpointer data)
8648 field_info *fi = PNODE_FINFO(node);
8649 gchar* decoded = (gchar*)data;
8654 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
8655 for (i = fi->start; i < fi->start + fi->length; i++) {
8658 decoded[byte] |= (1 << bit);
8666 proto_find_undecoded_data(proto_tree *tree, guint length)
8668 gchar* decoded = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
8670 proto_tree_traverse_pre_order(tree, check_for_undecoded, decoded);
8674 /* Dumps the protocols in the registration database to stdout. An independent
8675 * program can take this output and format it into nice tables or HTML or
8678 * There is one record per line. The fields are tab-delimited.
8680 * Field 1 = protocol name
8681 * Field 2 = protocol short name
8682 * Field 3 = protocol filter name
8685 proto_registrar_dump_protocols(void)
8687 protocol_t *protocol;
8689 void *cookie = NULL;
8692 i = proto_get_first_protocol(&cookie);
8694 protocol = find_protocol_by_id(i);
8695 ws_debug_printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
8696 protocol->filter_name);
8697 i = proto_get_next_protocol(&cookie);
8701 /* Dumps the value_strings, extended value string headers, range_strings
8702 * or true/false strings for fields that have them.
8703 * There is one record per line. Fields are tab-delimited.
8704 * There are four types of records: Value String, Extended Value String Header,
8705 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
8706 * the type of record.
8708 * Note that a record will be generated only if the value_string,... is referenced
8709 * in a registered hfinfo entry.
8715 * Field 2 = Field abbreviation to which this value string corresponds
8716 * Field 3 = Integer value
8719 * Extended Value String Headers
8720 * -----------------------------
8722 * Field 2 = Field abbreviation to which this extended value string header corresponds
8723 * Field 3 = Extended Value String "Name"
8724 * Field 4 = Number of entries in the associated value_string array
8725 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
8730 * Field 2 = Field abbreviation to which this range string corresponds
8731 * Field 3 = Integer value: lower bound
8732 * Field 4 = Integer value: upper bound
8735 * True/False Strings
8736 * ------------------
8738 * Field 2 = Field abbreviation to which this true/false string corresponds
8739 * Field 3 = True String
8740 * Field 4 = False String
8743 proto_registrar_dump_values(void)
8745 header_field_info *hfinfo;
8747 const value_string *vals;
8748 const val64_string *vals64;
8749 const range_string *range;
8750 const true_false_string *tfs;
8751 const unit_name_string *units;
8753 len = gpa_hfinfo.len;
8754 for (i = 0; i < len ; i++) {
8755 if (gpa_hfinfo.hfi[i] == NULL)
8756 continue; /* This is a deregistered protocol or field */
8758 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8760 if (hfinfo->id == hf_text_only) {
8764 /* ignore protocols */
8765 if (proto_registrar_is_protocol(i)) {
8768 /* process header fields */
8769 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
8771 * If this field isn't at the head of the list of
8772 * fields with this name, skip this field - all
8773 * fields with the same name are really just versions
8774 * of the same field stored in different bits, and
8775 * should have the same type/radix/value list, and
8776 * just differ in their bit masks. (If a field isn't
8777 * a bitfield, but can be, say, 1 or 2 bytes long,
8778 * it can just be made FT_UINT16, meaning the
8779 * *maximum* length is 2 bytes, and be used
8782 if (hfinfo->same_name_prev_id != -1)
8791 if (hfinfo->strings != NULL) {
8792 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) != BASE_CUSTOM &&
8793 (hfinfo->type == FT_CHAR ||
8794 hfinfo->type == FT_UINT8 ||
8795 hfinfo->type == FT_UINT16 ||
8796 hfinfo->type == FT_UINT24 ||
8797 hfinfo->type == FT_UINT32 ||
8798 hfinfo->type == FT_UINT40 ||
8799 hfinfo->type == FT_UINT48 ||
8800 hfinfo->type == FT_UINT56 ||
8801 hfinfo->type == FT_UINT64 ||
8802 hfinfo->type == FT_INT8 ||
8803 hfinfo->type == FT_INT16 ||
8804 hfinfo->type == FT_INT24 ||
8805 hfinfo->type == FT_INT32 ||
8806 hfinfo->type == FT_INT40 ||
8807 hfinfo->type == FT_INT48 ||
8808 hfinfo->type == FT_INT56 ||
8809 hfinfo->type == FT_INT64)) {
8811 if (hfinfo->display & BASE_RANGE_STRING) {
8812 range = (const range_string *)hfinfo->strings;
8813 } else if (hfinfo->display & BASE_EXT_STRING) {
8814 vals = VALUE_STRING_EXT_VS_P((value_string_ext *)hfinfo->strings);
8815 } else if (hfinfo->display & BASE_VAL64_STRING) {
8816 vals64 = (const val64_string *)hfinfo->strings;
8817 } else if (hfinfo->display & BASE_UNIT_STRING) {
8818 units = (const unit_name_string *)hfinfo->strings;
8820 vals = (const value_string *)hfinfo->strings;
8823 else if (hfinfo->type == FT_BOOLEAN) {
8824 tfs = (const struct true_false_string *)hfinfo->strings;
8828 /* Print value strings? */
8830 if (hfinfo->display & BASE_EXT_STRING) {
8831 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
8832 if (!value_string_ext_validate(vse_p)) {
8833 ws_g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
8836 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
8837 ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
8839 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
8840 VALUE_STRING_EXT_VS_NAME(vse_p),
8841 value_string_ext_match_type_str(vse_p));
8844 while (vals[vi].strptr) {
8845 /* Print in the proper base */
8846 if (hfinfo->type == FT_CHAR) {
8847 if (g_ascii_isprint(vals[vi].value)) {
8848 ws_debug_printf("V\t%s\t'%c'\t%s\n",
8853 if (hfinfo->display == BASE_HEX) {
8854 ws_debug_printf("V\t%s\t'\\x%02x'\t%s\n",
8860 ws_debug_printf("V\t%s\t'\\%03o'\t%s\n",
8867 if (hfinfo->display == BASE_HEX) {
8868 ws_debug_printf("V\t%s\t0x%x\t%s\n",
8874 ws_debug_printf("V\t%s\t%u\t%s\n",
8885 while (vals64[vi].strptr) {
8886 ws_debug_printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
8894 /* print range strings? */
8897 while (range[vi].strptr) {
8898 /* Print in the proper base */
8899 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_HEX) {
8900 ws_debug_printf("R\t%s\t0x%x\t0x%x\t%s\n",
8902 range[vi].value_min,
8903 range[vi].value_max,
8907 ws_debug_printf("R\t%s\t%u\t%u\t%s\n",
8909 range[vi].value_min,
8910 range[vi].value_max,
8917 /* Print true/false strings? */
8919 ws_debug_printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
8920 tfs->true_string, tfs->false_string);
8922 /* Print unit strings? */
8924 ws_debug_printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
8925 units->singular, units->plural ? units->plural : "(no plural)");
8930 /* Prints the number of registered fields.
8931 * Useful for determining an appropriate value for
8932 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
8934 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
8935 * the number of fields, TRUE otherwise.
8938 proto_registrar_dump_fieldcount(void)
8941 header_field_info *hfinfo;
8942 guint32 deregistered_count = 0;
8943 guint32 same_name_count = 0;
8944 guint32 protocol_count = 0;
8946 for (i = 0; i < gpa_hfinfo.len; i++) {
8947 if (gpa_hfinfo.hfi[i] == NULL) {
8948 deregistered_count++;
8949 continue; /* This is a deregistered protocol or header field */
8952 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8954 if (proto_registrar_is_protocol(i))
8957 if (hfinfo->same_name_prev_id != -1)
8961 ws_debug_printf("There are %u header fields registered, of which:\n"
8962 "\t%u are deregistered\n"
8963 "\t%u are protocols\n"
8964 "\t%u have the same name as another field\n\n",
8965 gpa_hfinfo.len, deregistered_count, protocol_count,
8968 ws_debug_printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
8969 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
8970 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
8973 ws_debug_printf("The header field table consumes %u KiB of memory.\n",
8974 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
8975 ws_debug_printf("The fields themselves consume %u KiB of memory.\n",
8976 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
8978 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8982 /* Dumps the contents of the registration database to stdout. An independent
8983 * program can take this output and format it into nice tables or HTML or
8986 * There is one record per line. Each record is either a protocol or a header
8987 * field, differentiated by the first field. The fields are tab-delimited.
8992 * Field 2 = descriptive protocol name
8993 * Field 3 = protocol abbreviation
8998 * Field 2 = descriptive field name
8999 * Field 3 = field abbreviation
9000 * Field 4 = type ( textual representation of the the ftenum type )
9001 * Field 5 = parent protocol abbreviation
9002 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
9003 * Field 7 = bitmask: format: hex: 0x....
9004 * Field 8 = blurb describing field
9007 proto_registrar_dump_fields(void)
9009 header_field_info *hfinfo, *parent_hfinfo;
9011 const char *enum_name;
9012 const char *base_name;
9016 len = gpa_hfinfo.len;
9017 for (i = 0; i < len ; i++) {
9018 if (gpa_hfinfo.hfi[i] == NULL)
9019 continue; /* This is a deregistered protocol or header field */
9021 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
9024 * Skip the pseudo-field for "proto_tree_add_text()" since
9025 * we don't want it in the list of filterable fields.
9027 if (hfinfo->id == hf_text_only)
9030 /* format for protocols */
9031 if (proto_registrar_is_protocol(i)) {
9032 ws_debug_printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
9034 /* format for header fields */
9037 * If this field isn't at the head of the list of
9038 * fields with this name, skip this field - all
9039 * fields with the same name are really just versions
9040 * of the same field stored in different bits, and
9041 * should have the same type/radix/value list, and
9042 * just differ in their bit masks. (If a field isn't
9043 * a bitfield, but can be, say, 1 or 2 bytes long,
9044 * it can just be made FT_UINT16, meaning the
9045 * *maximum* length is 2 bytes, and be used
9048 if (hfinfo->same_name_prev_id != -1)
9051 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
9053 enum_name = ftype_name(hfinfo->type);
9056 if (hfinfo->type == FT_CHAR ||
9057 hfinfo->type == FT_UINT8 ||
9058 hfinfo->type == FT_UINT16 ||
9059 hfinfo->type == FT_UINT24 ||
9060 hfinfo->type == FT_UINT32 ||
9061 hfinfo->type == FT_UINT40 ||
9062 hfinfo->type == FT_UINT48 ||
9063 hfinfo->type == FT_UINT56 ||
9064 hfinfo->type == FT_UINT64 ||
9065 hfinfo->type == FT_INT8 ||
9066 hfinfo->type == FT_INT16 ||
9067 hfinfo->type == FT_INT24 ||
9068 hfinfo->type == FT_INT32 ||
9069 hfinfo->type == FT_INT40 ||
9070 hfinfo->type == FT_INT48 ||
9071 hfinfo->type == FT_INT56 ||
9072 hfinfo->type == FT_INT64) {
9074 switch (FIELD_DISPLAY(hfinfo->display)) {
9086 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
9092 } else if (hfinfo->type == FT_BOOLEAN) {
9093 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
9094 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
9098 blurb = hfinfo->blurb;
9101 else if (strlen(blurb) == 0)
9104 ws_debug_printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
9105 hfinfo->name, hfinfo->abbrev, enum_name,
9106 parent_hfinfo->abbrev, base_name,
9107 hfinfo->bitmask, blurb);
9112 /* Dumps field types and descriptive names to stdout. An independent
9113 * program can take this output and format it into nice tables or HTML or
9116 * There is one record per line. The fields are tab-delimited.
9118 * Field 1 = field type name, e.g. FT_UINT8
9119 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
9122 proto_registrar_dump_ftypes(void)
9126 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
9127 ws_debug_printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
9131 /* This function indicates whether it's possible to construct a
9132 * "match selected" display filter string for the specified field,
9133 * returns an indication of whether it's possible, and, if it's
9134 * possible and "filter" is non-null, constructs the filter and
9135 * sets "*filter" to point to it.
9136 * You do not need to [g_]free() this string since it will be automatically
9137 * freed once the next packet is dissected.
9140 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
9143 header_field_info *hfinfo;
9148 gint start, length, length_remaining;
9150 gchar is_signed_num = FALSE;
9155 hfinfo = finfo->hfinfo;
9156 DISSECTOR_ASSERT(hfinfo);
9157 abbrev_len = (int) strlen(hfinfo->abbrev);
9159 if (hfinfo->strings && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
9160 const gchar *str = NULL;
9162 switch (hfinfo->type) {
9168 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
9176 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
9183 if (str != NULL && filter != NULL) {
9184 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
9190 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
9191 * functions for FT_UINT and FT_INT types, as we choose the base in
9192 * the string expression based on the display base of the field.
9194 * Note that the base does matter, as this is also used for
9195 * the protocolinfo tap.
9197 * It might be nice to use them in "proto_item_fill_label()"
9198 * as well, although, there, you'd have to deal with the base
9199 * *and* with resolved values for addresses.
9201 * Perhaps we need two different val_to_string routines, one
9202 * to generate items for display filters and one to generate
9203 * strings for display, and pass to both of them the
9204 * "display" and "strings" values in the header_field_info
9205 * structure for the field, so they can get the base and,
9206 * if the field is Boolean or an enumerated integer type,
9207 * the tables used to generate human-readable values.
9209 switch (hfinfo->type) {
9212 if (filter != NULL) {
9218 number = fvalue_get_uinteger(&finfo->value);
9220 out = hfinfo_char_value_format(hfinfo, buf, number);
9222 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9230 is_signed_num = TRUE;
9237 if (filter != NULL) {
9244 number = fvalue_get_sinteger(&finfo->value);
9246 number = fvalue_get_uinteger(&finfo->value);
9248 out = hfinfo_numeric_value_format(hfinfo, buf, number);
9250 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9258 is_signed_num = TRUE;
9264 if (filter != NULL) {
9271 number = fvalue_get_sinteger64(&finfo->value);
9273 number = fvalue_get_uinteger64(&finfo->value);
9275 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
9277 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
9283 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
9288 * If the length is 0, just match the name of the
9291 * (Also check for negative values, just in case,
9292 * as we'll cast it to an unsigned value later.)
9294 length = finfo->length;
9297 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
9304 * This doesn't have a value, so we'd match
9305 * on the raw bytes at this address.
9307 * Should we be allowed to access to the raw bytes?
9308 * If "edt" is NULL, the answer is "no".
9314 * Is this field part of the raw frame tvbuff?
9315 * If not, we can't use "frame[N:M]" to match
9318 * XXX - should this be frame-relative, or
9319 * protocol-relative?
9321 * XXX - does this fallback for non-registered
9322 * fields even make sense?
9324 if (finfo->ds_tvb != edt->tvb)
9325 return FALSE; /* you lose */
9328 * Don't go past the end of that tvbuff.
9330 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
9331 if (length > length_remaining)
9332 length = length_remaining;
9336 if (filter != NULL) {
9337 start = finfo->start;
9338 buf_len = 32 + length * 3;
9339 *filter = (char *)wmem_alloc0(NULL, buf_len);
9342 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
9343 "frame[%d:%d] == ", finfo->start, length);
9344 for (i=0; i<length; i++) {
9345 c = tvb_get_guint8(finfo->ds_tvb, start);
9348 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
9351 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
9358 /* FT_PCRE never appears as a type for a registered field. It is
9359 * only used internally. */
9360 DISSECTOR_ASSERT_NOT_REACHED();
9363 /* By default, use the fvalue's "to_string_repr" method. */
9365 /* Figure out the string length needed.
9366 * The ft_repr length.
9367 * 4 bytes for " == ".
9368 * 1 byte for trailing NUL.
9370 if (filter != NULL) {
9372 dfilter_len = fvalue_string_repr_len(&finfo->value,
9373 FTREPR_DFILTER, finfo->hfinfo->display);
9374 dfilter_len += abbrev_len + 4 + 1;
9375 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
9377 /* Create the string */
9378 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
9379 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
9380 wmem_free(NULL, str);
9389 * Returns TRUE if we can do a "match selected" on the field, FALSE
9393 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
9395 return construct_match_selected_string(finfo, edt, NULL);
9398 /* This function attempts to construct a "match selected" display filter
9399 * string for the specified field; if it can do so, it returns a pointer
9400 * to the string, otherwise it returns NULL.
9402 * The string is allocated with packet lifetime scope.
9403 * You do not need to [g_]free() this string since it will be automatically
9404 * freed once the next packet is dissected.
9407 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
9409 char *filter = NULL;
9411 if (!construct_match_selected_string(finfo, edt, &filter))
9413 wmem_free(NULL, filter);
9419 /* This function is common code for all proto_tree_add_bitmask... functions.
9423 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
9424 const int len, const gint ett, const int **fields,
9425 const int flags, gboolean first,
9426 gboolean use_parent_tree,
9427 proto_tree* tree, guint64 value)
9430 guint64 available_bits = 0;
9432 header_field_info *hf;
9436 if (len < 0 || len > 8)
9437 g_assert_not_reached();
9438 bitshift = (8 - (guint)len)*8;
9439 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
9441 if (use_parent_tree == FALSE)
9442 tree = proto_item_add_subtree(item, ett);
9445 guint64 present_bits;
9446 PROTO_REGISTRAR_GET_NTH(**fields,hf);
9447 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
9449 /* Skip fields that aren't fully present */
9450 present_bits = available_bits & hf->bitmask;
9451 if (present_bits != hf->bitmask) {
9462 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
9469 proto_tree_add_int(tree, **fields, tvb, offset, len, (gint32)value);
9476 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
9483 proto_tree_add_int64(tree, **fields, tvb, offset, len, (gint64)value);
9487 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
9491 DISSECTOR_ASSERT_NOT_REACHED();
9494 if (flags & BMT_NO_APPEND) {
9498 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
9502 if (hf->display == BASE_CUSTOM) {
9503 gchar lbl[ITEM_LABEL_LENGTH];
9504 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9506 DISSECTOR_ASSERT(fmtfunc);
9507 fmtfunc(lbl, (guint32) tmpval);
9508 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9512 else if (hf->strings) {
9513 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9514 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
9517 else if (!(flags & BMT_NO_INT)) {
9522 proto_item_append_text(item, ", ");
9525 out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
9526 proto_item_append_text(item, "%s: %s", hf->name, out);
9536 if (hf->display == BASE_CUSTOM) {
9537 gchar lbl[ITEM_LABEL_LENGTH];
9538 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9540 DISSECTOR_ASSERT(fmtfunc);
9541 fmtfunc(lbl, (guint32) tmpval);
9542 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9546 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
9547 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9548 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
9551 else if (!(flags & BMT_NO_INT)) {
9556 proto_item_append_text(item, ", ");
9559 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
9560 if (hf->display & BASE_UNIT_STRING) {
9561 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (unit_name_string*)hf->strings));
9563 proto_item_append_text(item, "%s: %s", hf->name, out);
9574 integer32 = (guint32) tmpval;
9576 no_of_bits = ws_count_ones(hf->bitmask);
9577 integer32 = ws_sign_ext32(integer32, no_of_bits);
9579 if (hf->display == BASE_CUSTOM) {
9580 gchar lbl[ITEM_LABEL_LENGTH];
9581 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
9583 DISSECTOR_ASSERT(fmtfunc);
9584 fmtfunc(lbl, (gint32) integer32);
9585 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9589 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
9590 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9591 hf->name, hf_try_val_to_str_const((gint32) integer32, hf, "Unknown"));
9594 else if (!(flags & BMT_NO_INT)) {
9599 proto_item_append_text(item, ", ");
9602 out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
9603 if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
9604 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (unit_name_string*)hf->strings));
9606 proto_item_append_text(item, "%s: %s", hf->name, out);
9617 if (hf->display == BASE_CUSTOM) {
9618 gchar lbl[ITEM_LABEL_LENGTH];
9619 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
9621 DISSECTOR_ASSERT(fmtfunc);
9622 fmtfunc(lbl, tmpval);
9623 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9627 else if (hf->strings) {
9628 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9629 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
9632 else if (!(flags & BMT_NO_INT)) {
9637 proto_item_append_text(item, ", ");
9640 out = hfinfo_number_value_format64(hf, buf, tmpval);
9641 proto_item_append_text(item, "%s: %s", hf->name, out);
9652 no_of_bits = ws_count_ones(hf->bitmask);
9653 tmpval = ws_sign_ext64(tmpval, no_of_bits);
9655 if (hf->display == BASE_CUSTOM) {
9656 gchar lbl[ITEM_LABEL_LENGTH];
9657 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
9659 DISSECTOR_ASSERT(fmtfunc);
9660 fmtfunc(lbl, (gint64) tmpval);
9661 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9665 else if (hf->strings) {
9666 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9667 hf->name, hf_try_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
9670 else if (!(flags & BMT_NO_INT)) {
9675 proto_item_append_text(item, ", ");
9678 out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
9679 proto_item_append_text(item, "%s: %s", hf->name, out);
9686 if (hf->strings && !(flags & BMT_NO_TFS)) {
9687 /* If we have true/false strings, emit full - otherwise messages
9689 const struct true_false_string *tfs =
9690 (const struct true_false_string *)hf->strings;
9693 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9694 hf->name, tfs->true_string);
9696 } else if (!(flags & BMT_NO_FALSE)) {
9697 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
9698 hf->name, tfs->false_string);
9701 } else if (hf->bitmask & value) {
9702 /* If the flag is set, show the name */
9703 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
9708 DISSECTOR_ASSERT_NOT_REACHED();
9718 /* This function will dissect a sequence of bytes that describe a
9719 * bitmask and supply the value of that sequence through a pointer.
9720 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9722 * This field will form an expansion under which the individual fields of the
9723 * bitmask is dissected and displayed.
9724 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9726 * fields is an array of pointers to int that lists all the fields of the
9727 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9728 * or another integer of the same type/size as hf_hdr with a mask specified.
9729 * This array is terminated by a NULL entry.
9731 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9732 * FT_integer fields that have a value_string attached will have the
9733 * matched string displayed on the expansion line.
9736 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
9737 const guint offset, const int hf_hdr,
9738 const gint ett, const int **fields,
9739 const guint encoding, guint64 *retval)
9741 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);
9744 /* This function will dissect a sequence of bytes that describe a
9746 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9748 * This field will form an expansion under which the individual fields of the
9749 * bitmask is dissected and displayed.
9750 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9752 * fields is an array of pointers to int that lists all the fields of the
9753 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9754 * or another integer of the same type/size as hf_hdr with a mask specified.
9755 * This array is terminated by a NULL entry.
9757 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9758 * FT_integer fields that have a value_string attached will have the
9759 * matched string displayed on the expansion line.
9762 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
9763 const guint offset, const int hf_hdr,
9764 const gint ett, const int **fields,
9765 const guint encoding)
9767 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
9770 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9771 * what data is appended to the header.
9774 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9775 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
9778 proto_item *item = NULL;
9779 header_field_info *hf;
9783 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9784 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9785 len = ftype_length(hf->type);
9786 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9789 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9790 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9791 flags, FALSE, FALSE, NULL, value);
9796 /* Mask out irrelevant portions */
9797 *retval &= hf->bitmask;
9799 *retval >>= hfinfo_bitshift(hf);
9805 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9806 * what data is appended to the header.
9809 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9810 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
9812 proto_item *item = NULL;
9813 header_field_info *hf;
9817 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9818 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9821 len = ftype_length(hf->type);
9822 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9823 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9824 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9825 flags, FALSE, FALSE, NULL, value);
9831 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
9832 can't be retrieved directly from tvb) */
9834 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9835 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
9837 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
9838 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
9841 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
9842 WS_DLL_PUBLIC proto_item *
9843 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9844 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
9846 proto_item *item = NULL;
9847 header_field_info *hf;
9850 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9851 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9852 /* the proto_tree_add_uint/_uint64() calls below
9853 will fail if tvb==NULL and len!=0 */
9854 len = tvb ? ftype_length(hf->type) : 0;
9858 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
9860 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
9862 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9863 flags, FALSE, FALSE, NULL, value);
9869 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
9871 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9872 const int len, const int **fields, const guint encoding)
9877 value = get_uint64_value(tree, tvb, offset, len, encoding);
9878 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9879 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9884 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9885 const int len, const int **fields, const guint64 value)
9888 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9889 BMT_NO_APPEND, FALSE, TRUE, tree, value);
9894 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
9895 * This is intended to support bitmask fields whose lengths can vary, perhaps
9896 * as the underlying standard evolves over time.
9897 * With this API there is the possibility of being called to display more or
9898 * less data than the dissector was coded to support.
9899 * In such cases, it is assumed that bitmasks are extended on the MSb end.
9900 * Thus when presented with "too much" or "too little" data, MSbits will be
9901 * ignored or MSfields sacrificed.
9903 * Only fields for which all defined bits are available are displayed.
9906 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
9907 const guint offset, const guint len, const int hf_hdr,
9908 const gint ett, const int **fields, struct expert_field* exp,
9909 const guint encoding)
9911 proto_item *item = NULL;
9912 header_field_info *hf;
9913 guint decodable_len;
9914 guint decodable_offset;
9915 guint32 decodable_value;
9918 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
9919 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9921 decodable_offset = offset;
9922 decodable_len = MIN(len, (guint) ftype_length(hf->type));
9924 /* If we are ftype_length-limited,
9925 * make sure we decode as many LSBs as possible.
9927 if (encoding == ENC_BIG_ENDIAN) {
9928 decodable_offset += (len - decodable_len);
9932 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
9933 decodable_len, encoding);
9935 /* The root item covers all the bytes even if we can't decode them all */
9936 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
9940 if (decodable_len < len) {
9941 /* Dissector likely requires updating for new protocol revision */
9942 expert_add_info_format(NULL, item, exp,
9943 "Only least-significant %d of %d bytes decoded",
9944 decodable_len, len);
9948 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
9949 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
9950 ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
9956 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
9958 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
9959 const guint offset, const guint len,
9960 const char *name, const char *fallback,
9961 const gint ett, const int **fields,
9962 const guint encoding, const int flags)
9964 proto_item *item = NULL;
9968 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
9969 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9970 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9971 flags, TRUE, FALSE, NULL, value) && fallback) {
9972 /* Still at first item - append 'fallback' text if any */
9973 proto_item_append_text(item, "%s", fallback);
9981 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9982 const guint bit_offset, const gint no_of_bits,
9983 const guint encoding)
9985 header_field_info *hfinfo;
9989 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9991 octet_length = (no_of_bits + 7) >> 3;
9992 octet_offset = bit_offset >> 3;
9993 test_length(hfinfo, tvb, octet_offset, octet_length);
9995 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
9996 * but only after doing a bunch more work (which we can, in the common
9997 * case, shortcut here).
9999 CHECK_FOR_NULL_TREE(tree);
10000 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10002 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
10006 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
10007 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
10008 * Offset should be given in bits from the start of the tvb.
10011 static proto_item *
10012 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10013 const guint bit_offset, const gint no_of_bits,
10014 guint64 *return_value, const guint encoding)
10018 guint8 tot_no_bits;
10020 char lbl_str[ITEM_LABEL_LENGTH];
10024 header_field_info *hf_field;
10026 const true_false_string *tfstring;
10028 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
10029 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
10031 if (hf_field->bitmask != 0) {
10032 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10033 "Incompatible use of proto_tree_add_bits_ret_val"
10034 " with field '%s' (%s) with bitmask != 0",
10035 hf_field->abbrev, hf_field->name));
10038 DISSECTOR_ASSERT(no_of_bits > 0);
10040 /* Byte align offset */
10041 offset = bit_offset>>3;
10044 * Calculate the number of octets used to hold the bits
10046 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
10047 length = (tot_no_bits + 7) >> 3;
10049 if (no_of_bits < 65) {
10050 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
10052 DISSECTOR_ASSERT_NOT_REACHED();
10056 /* Sign extend for signed types */
10057 switch (hf_field->type) {
10066 value = ws_sign_ext64(value, no_of_bits);
10073 if (return_value) {
10074 *return_value = value;
10077 /* Coast clear. Try and fake it */
10078 CHECK_FOR_NULL_TREE(tree);
10079 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10081 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
10083 switch (hf_field->type) {
10085 /* Boolean field */
10086 tfstring = (const true_false_string *) &tfs_true_false;
10087 if (hf_field->strings)
10088 tfstring = (const true_false_string *)hf_field->strings;
10089 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
10091 bf_str, hf_field->name,
10092 (guint64)value ? tfstring->true_string : tfstring->false_string);
10096 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
10097 fill_label_char(PITEM_FINFO(pi), lbl_str);
10104 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
10105 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
10112 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
10113 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
10120 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
10121 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
10128 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
10129 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
10133 DISSECTOR_ASSERT_NOT_REACHED();
10138 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
10143 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10144 const guint bit_offset, const crumb_spec_t *crumb_spec,
10145 guint64 *return_value)
10150 guint mask_initial_bit_offset;
10151 guint mask_greatest_bit_offset;
10152 guint octet_length;
10155 char lbl_str[ITEM_LABEL_LENGTH];
10157 guint64 composite_bitmask;
10158 guint64 composite_bitmap;
10160 header_field_info *hf_field;
10161 const true_false_string *tfstring;
10163 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
10164 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
10166 if (hf_field->bitmask != 0) {
10167 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10168 "Incompatible use of proto_tree_add_split_bits_item_ret_val"
10169 " with field '%s' (%s) with bitmask != 0",
10170 hf_field->abbrev, hf_field->name));
10173 mask_initial_bit_offset = bit_offset % 8;
10178 mask_greatest_bit_offset = 0;
10179 composite_bitmask = 0;
10180 composite_bitmap = 0;
10182 while (crumb_spec[i].crumb_bit_length != 0) {
10183 guint64 crumb_mask, crumb_value;
10184 guint8 crumb_end_bit_offset;
10186 DISSECTOR_ASSERT(i < 64);
10187 crumb_value = tvb_get_bits64(tvb,
10188 bit_offset + crumb_spec[i].crumb_bit_offset,
10189 crumb_spec[i].crumb_bit_length,
10191 value += crumb_value;
10192 no_of_bits += crumb_spec[i].crumb_bit_length;
10194 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
10195 octet containing the initial offset.
10196 If the mask is beyond 32 bits, then give up on bit map display.
10197 This could be improved in future, probably showing a table
10198 of 32 or 64 bits per row */
10199 if (mask_greatest_bit_offset < 32) {
10200 crumb_end_bit_offset = mask_initial_bit_offset
10201 + crumb_spec[i].crumb_bit_offset
10202 + crumb_spec[i].crumb_bit_length;
10203 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
10205 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
10206 mask_greatest_bit_offset = crumb_end_bit_offset;
10208 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
10209 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
10211 /* Shift left for the next segment */
10212 value <<= crumb_spec[++i].crumb_bit_length;
10215 /* Sign extend for signed types */
10216 switch (hf_field->type) {
10225 value = ws_sign_ext64(value, no_of_bits);
10231 if (return_value) {
10232 *return_value = value;
10235 /* Coast clear. Try and fake it */
10236 CHECK_FOR_NULL_TREE(tree);
10237 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10239 /* initialise the format string */
10242 octet_offset = bit_offset >> 3;
10244 /* Round up mask length to nearest octet */
10245 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
10246 mask_greatest_bit_offset = octet_length << 3;
10248 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
10249 It would be a useful enhancement to eliminate this restriction. */
10250 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
10251 other_decode_bitfield_value(bf_str,
10252 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
10253 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
10254 mask_greatest_bit_offset);
10257 switch (hf_field->type) {
10258 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
10259 /* Boolean field */
10260 tfstring = (const true_false_string *) &tfs_true_false;
10261 if (hf_field->strings)
10262 tfstring = (const true_false_string *) hf_field->strings;
10263 return proto_tree_add_boolean_format(tree, hfindex,
10264 tvb, octet_offset, octet_length, (guint32)value,
10266 bf_str, hf_field->name,
10267 (guint64)value ? tfstring->true_string : tfstring->false_string);
10271 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
10272 fill_label_char(PITEM_FINFO(pi), lbl_str);
10279 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
10280 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
10287 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
10288 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
10295 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
10296 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
10303 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
10304 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
10308 DISSECTOR_ASSERT_NOT_REACHED();
10312 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
10317 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
10318 const crumb_spec_t *crumb_spec, guint16 crumb_index)
10320 header_field_info *hfinfo;
10322 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
10323 proto_tree_add_text_internal(tree, tvb,
10325 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
10326 "%s crumb %d of %s (decoded above)",
10327 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
10330 crumb_spec[crumb_index].crumb_bit_length,
10337 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10338 const guint bit_offset, const gint no_of_bits,
10339 guint64 *return_value, const guint encoding)
10343 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
10344 bit_offset, no_of_bits,
10345 return_value, encoding))) {
10346 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
10347 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
10352 static proto_item *
10353 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
10354 tvbuff_t *tvb, const guint bit_offset,
10355 const gint no_of_bits, void *value_ptr,
10360 guint8 tot_no_bits;
10363 header_field_info *hf_field;
10365 /* We do not have to return a value, try to fake it as soon as possible */
10366 CHECK_FOR_NULL_TREE(tree);
10367 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10369 if (hf_field->bitmask != 0) {
10370 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
10371 "Incompatible use of proto_tree_add_bits_format_value"
10372 " with field '%s' (%s) with bitmask != 0",
10373 hf_field->abbrev, hf_field->name));
10376 DISSECTOR_ASSERT(no_of_bits > 0);
10378 /* Byte align offset */
10379 offset = bit_offset>>3;
10382 * Calculate the number of octets used to hold the bits
10384 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
10385 length = tot_no_bits>>3;
10386 /* If we are using part of the next octet, increase length by 1 */
10387 if (tot_no_bits & 0x07)
10390 if (no_of_bits < 65) {
10391 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
10393 DISSECTOR_ASSERT_NOT_REACHED();
10397 str = decode_bits_in_field(bit_offset, no_of_bits, value);
10399 g_strlcat(str, " = ", 256+64);
10400 g_strlcat(str, hf_field->name, 256+64);
10403 * This function does not receive an actual value but a dimensionless pointer to that value.
10404 * For this reason, the type of the header field is examined in order to determine
10405 * what kind of value we should read from this address.
10406 * The caller of this function must make sure that for the specific header field type the address of
10407 * a compatible value is provided.
10409 switch (hf_field->type) {
10411 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
10412 "%s: %s", str, value_str);
10420 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
10421 "%s: %s", str, value_str);
10428 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
10429 "%s: %s", str, value_str);
10436 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
10437 "%s: %s", str, value_str);
10444 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
10445 "%s: %s", str, value_str);
10449 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
10450 "%s: %s", str, value_str);
10454 DISSECTOR_ASSERT_NOT_REACHED();
10460 static proto_item *
10461 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
10462 tvbuff_t *tvb, const guint bit_offset,
10463 const gint no_of_bits, void *value_ptr,
10468 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
10469 tvb, bit_offset, no_of_bits,
10470 value_ptr, value_str))) {
10471 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
10472 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
10477 #define CREATE_VALUE_STRING(dst,format,ap) \
10478 va_start(ap, format); \
10479 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
10483 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
10484 tvbuff_t *tvb, const guint bit_offset,
10485 const gint no_of_bits, guint32 value,
10486 const char *format, ...)
10490 header_field_info *hf_field;
10492 CHECK_FOR_NULL_TREE(tree);
10494 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10496 switch (hf_field->type) {
10504 DISSECTOR_ASSERT_NOT_REACHED();
10509 CREATE_VALUE_STRING(dst, format, ap);
10511 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10515 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
10516 tvbuff_t *tvb, const guint bit_offset,
10517 const gint no_of_bits, guint64 value,
10518 const char *format, ...)
10522 header_field_info *hf_field;
10524 CHECK_FOR_NULL_TREE(tree);
10526 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10528 switch (hf_field->type) {
10536 DISSECTOR_ASSERT_NOT_REACHED();
10541 CREATE_VALUE_STRING(dst, format, ap);
10543 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10547 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
10548 tvbuff_t *tvb, const guint bit_offset,
10549 const gint no_of_bits, float value,
10550 const char *format, ...)
10554 header_field_info *hf_field;
10556 CHECK_FOR_NULL_TREE(tree);
10558 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10560 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
10562 CREATE_VALUE_STRING(dst, format, ap);
10564 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10568 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
10569 tvbuff_t *tvb, const guint bit_offset,
10570 const gint no_of_bits, gint32 value,
10571 const char *format, ...)
10575 header_field_info *hf_field;
10577 CHECK_FOR_NULL_TREE(tree);
10579 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10581 switch (hf_field->type) {
10589 DISSECTOR_ASSERT_NOT_REACHED();
10594 CREATE_VALUE_STRING(dst, format, ap);
10596 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10600 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
10601 tvbuff_t *tvb, const guint bit_offset,
10602 const gint no_of_bits, gint64 value,
10603 const char *format, ...)
10607 header_field_info *hf_field;
10609 CHECK_FOR_NULL_TREE(tree);
10611 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10613 switch (hf_field->type) {
10621 DISSECTOR_ASSERT_NOT_REACHED();
10626 CREATE_VALUE_STRING(dst, format, ap);
10628 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10632 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
10633 tvbuff_t *tvb, const guint bit_offset,
10634 const gint no_of_bits, guint32 value,
10635 const char *format, ...)
10639 header_field_info *hf_field;
10641 CHECK_FOR_NULL_TREE(tree);
10643 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10645 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
10647 CREATE_VALUE_STRING(dst, format, ap);
10649 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10653 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
10654 tvbuff_t *tvb, const guint bit_offset,
10655 const gint no_of_bits, guint64 value,
10656 const char *format, ...)
10660 header_field_info *hf_field;
10662 CHECK_FOR_NULL_TREE(tree);
10664 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
10666 DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
10668 CREATE_VALUE_STRING(dst, format, ap);
10670 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
10674 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10675 const guint bit_offset, const gint no_of_chars)
10678 header_field_info *hfinfo;
10683 CHECK_FOR_NULL_TREE(tree);
10685 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10687 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
10689 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
10690 byte_offset = bit_offset >> 3;
10692 string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
10694 if (hfinfo->display == STR_UNICODE) {
10695 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
10698 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
10699 DISSECTOR_ASSERT(byte_length >= 0);
10700 proto_tree_set_string(PNODE_FINFO(pi), string);
10706 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10707 const guint bit_offset, const gint no_of_chars)
10710 header_field_info *hfinfo;
10715 CHECK_FOR_NULL_TREE(tree);
10717 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10719 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
10721 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
10722 byte_offset = bit_offset >> 3;
10724 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
10726 if (hfinfo->display == STR_UNICODE) {
10727 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
10730 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
10731 DISSECTOR_ASSERT(byte_length >= 0);
10732 proto_tree_set_string(PNODE_FINFO(pi), string);
10737 const value_string proto_checksum_vals[] = {
10738 { PROTO_CHECKSUM_E_BAD, "Bad" },
10739 { PROTO_CHECKSUM_E_GOOD, "Good" },
10740 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
10741 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
10747 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
10748 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
10749 packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
10751 header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
10754 proto_item* ti = NULL;
10756 gboolean incorrect_checksum = TRUE;
10758 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
10760 if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
10761 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, 0, 0, "[missing]");
10762 PROTO_ITEM_SET_GENERATED(ti);
10763 if (hf_checksum_status != -1) {
10764 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_NOT_PRESENT);
10765 PROTO_ITEM_SET_GENERATED(ti2);
10770 switch (hfinfo->type){
10784 DISSECTOR_ASSERT_NOT_REACHED();
10787 if (flags & PROTO_CHECKSUM_GENERATED) {
10788 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, 0, computed_checksum);
10789 PROTO_ITEM_SET_GENERATED(ti);
10791 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
10792 if (flags & PROTO_CHECKSUM_VERIFY) {
10793 if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
10794 if (computed_checksum == 0) {
10795 proto_item_append_text(ti, " [correct]");
10796 if (hf_checksum_status != -1) {
10797 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
10798 PROTO_ITEM_SET_GENERATED(ti2);
10800 incorrect_checksum = FALSE;
10801 } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
10802 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
10805 if (checksum == computed_checksum) {
10806 proto_item_append_text(ti, " [correct]");
10807 if (hf_checksum_status != -1) {
10808 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
10809 PROTO_ITEM_SET_GENERATED(ti2);
10811 incorrect_checksum = FALSE;
10815 if (incorrect_checksum) {
10816 if (hf_checksum_status != -1) {
10817 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
10818 PROTO_ITEM_SET_GENERATED(ti2);
10820 if (flags & PROTO_CHECKSUM_ZERO) {
10821 proto_item_append_text(ti, " [incorrect]");
10822 if (bad_checksum_expert != NULL)
10823 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum");
10825 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
10826 if (bad_checksum_expert != NULL)
10827 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum [should be 0x%0*x]", len*2, computed_checksum);
10831 if (hf_checksum_status != -1) {
10832 proto_item_append_text(ti, " [unverified]");
10833 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
10834 PROTO_ITEM_SET_GENERATED(ti2);
10843 proto_check_field_name(const gchar *field_name)
10845 return wrs_check_charset(fld_abbrev_chars, field_name);
10849 tree_expanded(int tree_type)
10851 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10852 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
10856 tree_expanded_set(int tree_type, gboolean value)
10858 g_assert(tree_type >= 0 && tree_type < num_tree_types);
10861 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
10863 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
10867 * Editor modelines - http://www.wireshark.org/tools/modelines.html
10870 * c-basic-offset: 8
10872 * indent-tabs-mode: t
10875 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
10876 * :indentSize=8:tabSize=8:noTabs=false: