2 * Routines for protocol tree
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
19 #include <wsutil/bits_ctz.h>
20 #include <wsutil/bits_count_ones.h>
21 #include <wsutil/sign_ext.h>
22 #include <wsutil/utf8_entities.h>
24 #include <ftypes/ftypes-int.h>
27 #include "exceptions.h"
28 #include "ptvcursor.h"
30 #include "addr_resolv.h"
31 #include "address_types.h"
34 #include "epan_dissect.h"
36 #include "wmem/wmem.h"
38 #include "column-utils.h"
39 #include "to_str-int.h"
41 #include "osi-utils.h"
43 #include "show_exception.h"
45 #include "register-int.h"
47 #include <wsutil/ws_printf.h> /* ws_debug_printf/ws_g_warning */
48 #include <wsutil/crash_info.h>
51 #include <json-glib/json-glib.h>
54 /* Ptvcursor limits */
55 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
56 #define SUBTREE_MAX_LEVELS 256
58 /* Throw an exception if our tree exceeds these. */
59 /* XXX - These should probably be preferences */
60 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
61 #define MAX_TREE_LEVELS (5 * 100)
63 typedef struct __subtree_lvl {
70 subtree_lvl *pushed_tree;
71 guint8 pushed_tree_index;
72 guint8 pushed_tree_max;
78 #define cVALS(x) (const value_string*)(x)
80 /** See inlined comments.
81 @param tree the tree to append this item to
82 @param free_block a code block to call to free resources if this returns
83 @return NULL if 'tree' is null */
84 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block) \
90 /** See inlined comments.
91 @param tree the tree to append this item to
92 @param free_block a code block to call to free resources if this returns
93 @return NULL if 'tree' is null */
94 #define CHECK_FOR_NULL_TREE(tree) \
95 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
97 /** See inlined comments.
98 @param tree the tree to append this item to
99 @param hfindex field index
100 @param hfinfo header_field
101 @param free_block a code block to call to free resources if this returns
102 @return the header field matching 'hfinfo' */
103 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
104 /* If this item is not referenced we don't have to do much work \
105 at all but we should still return a node so that field items \
106 below this node (think proto_item_add_subtree()) will still \
107 have somewhere to attach to or else filtering will not work \
108 (they would be ignored since tree would be NULL). \
109 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
110 since dissectors that want to do proto_item_set_len() or \
111 other operations that dereference this would crash. \
112 We fake FT_PROTOCOL unless some clients have requested us \
115 PTREE_DATA(tree)->count++; \
116 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
117 if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
119 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
120 g_error("Adding %s would put more than %d items in the tree -- possible infinite loop", \
121 hfinfo->abbrev, MAX_TREE_ITEMS); \
122 /* Let the exception handler add items to the tree */ \
123 PTREE_DATA(tree)->count = 0; \
124 THROW_MESSAGE(DissectorError, \
125 wmem_strdup_printf(wmem_packet_scope(), \
126 "Adding %s would put more than %d items in the tree -- possible infinite loop", \
127 hfinfo->abbrev, MAX_TREE_ITEMS)); \
129 if (!(PTREE_DATA(tree)->visible)) { \
130 if (PTREE_FINFO(tree)) { \
131 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
132 && (hfinfo->type != FT_PROTOCOL || \
133 PTREE_DATA(tree)->fake_protocols)) { \
135 /* just return tree back to the caller */\
141 /** See inlined comments.
142 @param tree the tree to append this item to
143 @param hfindex field index
144 @param hfinfo header_field
145 @return the header field matching 'hfinfo' */
146 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
147 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
150 /** See inlined comments.
151 @param pi the created protocol item we're about to return */
152 #define TRY_TO_FAKE_THIS_REPR(pi) \
154 if (!(PTREE_DATA(pi)->visible)) { \
155 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
156 * items string representation */ \
159 /* Same as above but returning void */
160 #define TRY_TO_FAKE_THIS_REPR_VOID(pi) \
163 if (!(PTREE_DATA(pi)->visible)) { \
164 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
165 * items string representation */ \
168 /* Similar to above, but allows a NULL tree */
169 #define TRY_TO_FAKE_THIS_REPR_NESTED(pi) \
170 if ((pi == NULL) || (!(PTREE_DATA(pi)->visible))) { \
171 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
172 * items string representation */ \
176 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
177 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
178 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
180 static void label_mark_truncated(char *label_str, gsize name_pos);
181 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
183 static void fill_label_boolean(field_info *fi, gchar *label_str);
184 static void fill_label_bitfield_char(field_info *fi, gchar *label_str);
185 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
186 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
187 static void fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed);
188 static void fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed);
189 static void fill_label_char(field_info *fi, gchar *label_str);
190 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
191 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
193 static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value);
194 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
195 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
196 static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
197 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
198 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
199 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
200 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
201 static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
202 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
203 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
205 static void proto_cleanup_base(void);
208 proto_tree_add_node(proto_tree *tree, field_info *fi);
211 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
212 gint *item_length, const guint encoding);
215 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
216 gint length, guint item_length, const gint encoding);
219 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
220 const gint start, const gint item_length);
223 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
224 gint start, gint *length);
227 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
229 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
232 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
234 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
236 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
238 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
240 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
242 proto_tree_set_string(field_info *fi, const char* value);
244 proto_tree_set_ax25(field_info *fi, const guint8* value);
246 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
248 proto_tree_set_vines(field_info *fi, const guint8* value);
250 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
252 proto_tree_set_ether(field_info *fi, const guint8* value);
254 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
256 proto_tree_set_ipxnet(field_info *fi, guint32 value);
258 proto_tree_set_ipv4(field_info *fi, guint32 value);
260 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
262 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
264 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
266 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
268 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
270 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
272 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
274 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
276 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
278 proto_tree_set_boolean(field_info *fi, guint64 value);
280 proto_tree_set_float(field_info *fi, float value);
282 proto_tree_set_double(field_info *fi, double value);
284 proto_tree_set_uint(field_info *fi, guint32 value);
286 proto_tree_set_int(field_info *fi, gint32 value);
288 proto_tree_set_uint64(field_info *fi, guint64 value);
290 proto_tree_set_int64(field_info *fi, gint64 value);
292 proto_tree_set_eui64(field_info *fi, const guint64 value);
294 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
296 /* Handle type length mismatch (now filterable) expert info */
297 static int proto_type_length_mismatch = -1;
298 static expert_field ei_type_length_mismatch_error = EI_INIT;
299 static expert_field ei_type_length_mismatch_warn = EI_INIT;
300 static void register_type_length_mismatch(void);
302 /* Handle number string decoding errors with expert info */
303 static int proto_number_string_decoding_error = -1;
304 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
305 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
306 static void register_number_string_decoding_error(void);
308 /* Handle string errors expert info */
309 static int proto_string_errors = -1;
310 static expert_field ei_string_trailing_characters = EI_INIT;
311 static void register_string_errors(void);
313 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
315 /* special-case header field used within proto.c */
316 static header_field_info hfi_text_only =
317 { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
318 int hf_text_only = -1;
320 /* Structure for information about a protocol */
322 const char *name; /* long description */
323 const char *short_name; /* short description */
324 const char *filter_name; /* name of this protocol in filters */
325 GPtrArray *fields; /* fields for this protocol */
326 int proto_id; /* field ID for this protocol */
327 gboolean is_enabled; /* TRUE if protocol is enabled */
328 gboolean enabled_by_default; /* TRUE if protocol is enabled by default */
329 gboolean can_toggle; /* TRUE if is_enabled can be changed */
330 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
331 For dissectors that need a protocol name so they
332 can be added to a dissector table, but use the
333 parent_proto_id for things like enable/disable */
334 GList *heur_list; /* Heuristic dissectors associated with this protocol */
337 /* List of all protocols */
338 static GList *protocols = NULL;
339 static GList *pino_protocols = NULL;
341 /* Deregistered fields */
342 static GPtrArray *deregistered_fields = NULL;
343 static GPtrArray *deregistered_data = NULL;
345 /* indexed by prefix, contains initializers */
346 static GHashTable* prefixes = NULL;
348 /* Contains information about a field when a dissector calls
349 * proto_tree_add_item. */
350 #define FIELD_INFO_NEW(pool, fi) fi = wmem_new(pool, field_info)
351 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
353 /* Contains the space for proto_nodes. */
354 #define PROTO_NODE_INIT(node) \
355 node->first_child = NULL; \
356 node->last_child = NULL; \
359 #define PROTO_NODE_FREE(pool, node) \
360 wmem_free(pool, node)
362 /* String space for protocol and field items for the GUI */
363 #define ITEM_LABEL_NEW(pool, il) \
364 il = wmem_new(pool, item_label_t);
365 #define ITEM_LABEL_FREE(pool, il) \
368 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
369 if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
370 g_error("Unregistered hf! index=%d", hfindex); \
371 DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
372 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
373 hfinfo = gpa_hfinfo.hfi[hfindex];
375 /* List which stores protocols and fields that have been registered */
376 typedef struct _gpa_hfinfo_t {
378 guint32 allocated_len;
379 header_field_info **hfi;
382 static gpa_hfinfo_t gpa_hfinfo;
384 /* Hash table of abbreviations and IDs */
385 static GHashTable *gpa_name_map = NULL;
386 static header_field_info *same_name_hfinfo;
388 /* Hash table protocol aliases. const char * -> const char * */
389 static GHashTable *gpa_protocol_aliases = NULL;
392 * We're called repeatedly with the same field name when sorting a column.
393 * Cache our last gpa_name_map hit for faster lookups.
395 static char *last_field_name = NULL;
396 static header_field_info *last_hfinfo;
398 static void save_same_name_hfinfo(gpointer data)
400 same_name_hfinfo = (header_field_info*)data;
403 /* Points to the first element of an array of bits, indexed by
404 a subtree item type; that array element is TRUE if subtrees of
405 an item of that type are to be expanded. */
406 static guint32 *tree_is_expanded;
408 /* Number of elements in that array. */
411 /* Name hashtables for fast detection of duplicate names */
412 static GHashTable* proto_names = NULL;
413 static GHashTable* proto_short_names = NULL;
414 static GHashTable* proto_filter_names = NULL;
417 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
419 const protocol_t *p1 = (const protocol_t *)p1_arg;
420 const protocol_t *p2 = (const protocol_t *)p2_arg;
422 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
426 static GSList *dissector_plugins = NULL;
429 proto_register_plugin(const proto_plugin *plug)
432 /* XXX print useful warning */
435 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
439 call_plugin_register_protoinfo(gpointer data, gpointer user_data _U_)
441 proto_plugin *plug = (proto_plugin *)data;
443 if (plug->register_protoinfo) {
444 plug->register_protoinfo();
449 call_plugin_register_handoff(gpointer data, gpointer user_data _U_)
451 proto_plugin *plug = (proto_plugin *)data;
453 if (plug->register_handoff) {
454 plug->register_handoff();
457 #endif /* HAVE_PLUGINS */
459 /* initialize data structures and register protocols and fields */
461 proto_init(GSList *register_all_plugin_protocols_list,
462 GSList *register_all_plugin_handoffs_list,
464 gpointer client_data)
466 proto_cleanup_base();
468 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
469 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
470 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
473 gpa_hfinfo.allocated_len = 0;
474 gpa_hfinfo.hfi = NULL;
475 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
476 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
477 deregistered_fields = g_ptr_array_new();
478 deregistered_data = g_ptr_array_new();
480 /* Initialize the ftype subsystem */
483 /* Initialize the addres type subsystem */
484 address_types_initialize();
486 /* Register one special-case FT_TEXT_ONLY field for use when
487 converting wireshark to new-style proto_tree. These fields
488 are merely strings on the GUI tree; they are not filterable */
489 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
491 /* Register the pseudo-protocols used for exceptions. */
492 register_show_exception();
493 register_type_length_mismatch();
494 register_number_string_decoding_error();
495 register_string_errors();
497 /* Have each built-in dissector register its protocols, fields,
498 dissector tables, and dissectors to be called through a
499 handle, and do whatever one-time initialization it needs to
501 register_all_protocols(cb, client_data);
503 /* Now call the registration routines for all epan plugins. */
504 for (GSList *l = register_all_plugin_protocols_list; l != NULL; l = l->next) {
505 ((void (*)(register_cb, gpointer))l->data)(cb, client_data);
509 /* Now call the registration routines for all dissector plugins. */
511 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
512 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL);
515 /* Now call the "handoff registration" routines of all built-in
516 dissectors; those routines register the dissector in other
517 dissectors' handoff tables, and fetch any dissector handles
519 register_all_protocol_handoffs(cb, client_data);
521 /* Now do the same with epan plugins. */
522 for (GSList *l = register_all_plugin_handoffs_list; l != NULL; l = l->next) {
523 ((void (*)(register_cb, gpointer))l->data)(cb, client_data);
527 /* Now do the same with dissector plugins. */
529 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
530 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL);
533 /* sort the protocols by protocol name */
534 protocols = g_list_sort(protocols, proto_compare_name);
536 /* We've assigned all the subtree type values; allocate the array
537 for them, and zero it out. */
538 tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
542 proto_cleanup_base(void)
544 protocol_t *protocol;
545 header_field_info *hfinfo;
547 /* Free the abbrev/ID hash table */
549 g_hash_table_destroy(gpa_name_map);
552 if (gpa_protocol_aliases) {
553 g_hash_table_destroy(gpa_protocol_aliases);
554 gpa_protocol_aliases = NULL;
556 g_free(last_field_name);
557 last_field_name = NULL;
560 protocol = (protocol_t *)protocols->data;
561 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
562 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
564 g_slice_free(header_field_info, hfinfo);
565 if (protocol->fields) {
566 g_ptr_array_free(protocol->fields, TRUE);
568 g_list_free(protocol->heur_list);
569 protocols = g_list_remove(protocols, protocol);
573 while (pino_protocols) {
574 protocol = (protocol_t *)pino_protocols->data;
575 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
576 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
577 DISSECTOR_ASSERT(protocol->fields == NULL); //helpers should not have any registered fields
578 g_slice_free(header_field_info, hfinfo);
579 DISSECTOR_ASSERT(protocol->heur_list == NULL); //helpers should not have a heuristic list
580 pino_protocols = g_list_remove(pino_protocols, protocol);
585 g_hash_table_destroy(proto_names);
589 if (proto_short_names) {
590 g_hash_table_destroy(proto_short_names);
591 proto_short_names = NULL;
594 if (proto_filter_names) {
595 g_hash_table_destroy(proto_filter_names);
596 proto_filter_names = NULL;
599 if (gpa_hfinfo.allocated_len) {
601 gpa_hfinfo.allocated_len = 0;
602 g_free(gpa_hfinfo.hfi);
603 gpa_hfinfo.hfi = NULL;
606 if (deregistered_fields) {
607 g_ptr_array_free(deregistered_fields, TRUE);
608 deregistered_fields = NULL;
611 if (deregistered_data) {
612 g_ptr_array_free(deregistered_data, TRUE);
613 deregistered_data = NULL;
616 g_free(tree_is_expanded);
617 tree_is_expanded = NULL;
620 g_hash_table_destroy(prefixes);
626 proto_free_deregistered_fields();
627 proto_cleanup_base();
630 g_slist_free(dissector_plugins);
631 dissector_plugins = NULL;
636 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
639 proto_node *pnode = tree;
643 if (func(pnode, data))
646 child = pnode->first_child;
647 while (child != NULL) {
649 * The routine we call might modify the child, e.g. by
650 * freeing it, so we get the child's successor before
651 * calling that routine.
654 child = current->next;
655 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
663 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
666 proto_node *pnode = tree;
670 child = pnode->first_child;
671 while (child != NULL) {
673 * The routine we call might modify the child, e.g. by
674 * freeing it, so we get the child's successor before
675 * calling that routine.
678 child = current->next;
679 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
682 if (func(pnode, data))
689 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
692 proto_node *node = tree;
698 node = node->first_child;
699 while (node != NULL) {
701 node = current->next;
702 func((proto_tree *)current, data);
707 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
709 GPtrArray *ptrs = (GPtrArray *)value;
710 gint hfid = GPOINTER_TO_UINT(key);
711 header_field_info *hfinfo;
713 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
714 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
715 /* when a field is referenced by a filter this also
716 affects the refcount for the parent protocol so we need
717 to adjust the refcount for the parent as well
719 if (hfinfo->parent != -1) {
720 header_field_info *parent_hfinfo;
721 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
722 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
724 hfinfo->ref_type = HF_REF_TYPE_NONE;
727 g_ptr_array_free(ptrs, TRUE);
731 proto_tree_free_node(proto_node *node, gpointer data _U_)
733 field_info *finfo = PNODE_FINFO(node);
735 proto_tree_children_foreach(node, proto_tree_free_node, NULL);
737 FVALUE_CLEANUP(&finfo->value);
741 proto_tree_reset(proto_tree *tree)
743 tree_data_t *tree_data = PTREE_DATA(tree);
745 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
748 if (tree_data->interesting_hfids) {
749 /* Free all the GPtrArray's in the interesting_hfids hash. */
750 g_hash_table_foreach(tree_data->interesting_hfids,
751 free_GPtrArray_value, NULL);
753 /* And then remove all values. */
754 g_hash_table_remove_all(tree_data->interesting_hfids);
757 /* Reset track of the number of children */
758 tree_data->count = 0;
760 PROTO_NODE_INIT(tree);
763 /* frees the resources that the dissection a proto_tree uses */
765 proto_tree_free(proto_tree *tree)
767 tree_data_t *tree_data = PTREE_DATA(tree);
769 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
772 if (tree_data->interesting_hfids) {
773 /* Free all the GPtrArray's in the interesting_hfids hash. */
774 g_hash_table_foreach(tree_data->interesting_hfids,
775 free_GPtrArray_value, NULL);
777 /* And then destroy the hash. */
778 g_hash_table_destroy(tree_data->interesting_hfids);
781 g_slice_free(tree_data_t, tree_data);
783 g_slice_free(proto_tree, tree);
786 /* Is the parsing being done for a visible proto_tree or an invisible one?
787 * By setting this correctly, the proto_tree creation is sped up by not
788 * having to call g_vsnprintf and copy strings around.
791 proto_tree_set_visible(proto_tree *tree, gboolean visible)
793 gboolean old_visible = PTREE_DATA(tree)->visible;
795 PTREE_DATA(tree)->visible = visible;
801 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
803 PTREE_DATA(tree)->fake_protocols = fake_protocols;
806 /* Assume dissector set only its protocol fields.
807 This function is called by dissectors and allows the speeding up of filtering
808 in wireshark; if this function returns FALSE it is safe to reset tree to NULL
809 and thus skip calling most of the expensive proto_tree_add_...()
811 If the tree is visible we implicitly assume the field is referenced.
814 proto_field_is_referenced(proto_tree *tree, int proto_id)
816 register header_field_info *hfinfo;
822 if (PTREE_DATA(tree)->visible)
825 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
826 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
829 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
836 /* Finds a record in the hfinfo array by id. */
838 proto_registrar_get_nth(guint hfindex)
840 register header_field_info *hfinfo;
842 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
847 /* Prefix initialization
848 * this allows for a dissector to register a display filter name prefix
849 * so that it can delay the initialization of the hf array as long as
853 /* compute a hash for the part before the dot of a display filter */
855 prefix_hash (gconstpointer key) {
856 /* end the string at the dot and compute its hash */
857 gchar* copy = g_strdup((const gchar *)key);
868 tmp = g_str_hash(copy);
873 /* are both strings equal up to the end or the dot? */
875 prefix_equal (gconstpointer ap, gconstpointer bp) {
876 const gchar* a = (const gchar *)ap;
877 const gchar* b = (const gchar *)bp;
883 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
885 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
886 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
888 if (ac != bc) return FALSE;
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_byalias(const char *alias_name)
972 /* Find our aliased protocol. */
973 char *an_copy = g_strdup(alias_name);
974 char *dot = strchr(an_copy, '.');
978 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
984 /* Construct our aliased field and look it up. */
985 GString *filter_name = g_string_new(proto_pfx);
987 g_string_append_printf(filter_name, ".%s", dot+1);
989 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
991 g_string_free(filter_name, TRUE);
997 proto_registrar_get_id_byname(const char *field_name)
999 header_field_info *hfinfo;
1001 hfinfo = proto_registrar_get_byname(field_name);
1011 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1013 subtree_lvl *pushed_tree;
1015 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
1016 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
1018 pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1019 DISSECTOR_ASSERT(pushed_tree != NULL);
1020 if (ptvc->pushed_tree)
1021 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
1022 ptvc->pushed_tree = pushed_tree;
1026 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1028 ptvc->pushed_tree = NULL;
1029 ptvc->pushed_tree_max = 0;
1030 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1031 ptvc->pushed_tree_index = 0;
1034 /* Allocates an initializes a ptvcursor_t with 3 variables:
1035 * proto_tree, tvbuff, and offset. */
1037 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
1041 ptvc = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
1044 ptvc->offset = offset;
1045 ptvc->pushed_tree = NULL;
1046 ptvc->pushed_tree_max = 0;
1047 ptvc->pushed_tree_index = 0;
1052 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1054 ptvcursor_free(ptvcursor_t *ptvc)
1056 ptvcursor_free_subtree_levels(ptvc);
1060 /* Returns tvbuff. */
1062 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1067 /* Returns current offset. */
1069 ptvcursor_current_offset(ptvcursor_t *ptvc)
1071 return ptvc->offset;
1075 ptvcursor_tree(ptvcursor_t *ptvc)
1084 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1089 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1091 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1093 subtree_lvl *subtree;
1094 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1095 ptvcursor_new_subtree_levels(ptvc);
1097 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1098 subtree->tree = ptvc->tree;
1100 ptvc->pushed_tree_index++;
1101 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1104 /* pops a subtree */
1106 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1108 subtree_lvl *subtree;
1110 if (ptvc->pushed_tree_index <= 0)
1113 ptvc->pushed_tree_index--;
1114 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1115 if (subtree->it != NULL)
1116 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1118 ptvc->tree = subtree->tree;
1121 /* saves the current tvb offset and the item in the current subtree level */
1123 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1125 subtree_lvl *subtree;
1127 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1129 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1131 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1134 /* Creates a subtree and adds it to the cursor as the working tree but does not
1135 * save the old working tree */
1137 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1139 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1144 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1146 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1147 if (length == SUBTREE_UNDEFINED_LENGTH)
1148 ptvcursor_subtree_set_item(ptvc, it);
1149 return ptvcursor_tree(ptvc);
1152 /* Add an item to the tree and create a subtree
1153 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1154 * In this case, when the subtree will be closed, the parent item length will
1155 * be equal to the advancement of the cursor since the creation of the subtree.
1158 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1159 const guint encoding, gint ett_subtree)
1163 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1164 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1168 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1170 /* Add a text node to the tree and create a subtree
1171 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1172 * In this case, when the subtree will be closed, the item length will be equal
1173 * to the advancement of the cursor since the creation of the subtree.
1176 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1177 gint ett_subtree, const char *format, ...)
1181 header_field_info *hfinfo;
1184 tree = ptvcursor_tree(ptvc);
1186 CHECK_FOR_NULL_TREE(tree);
1188 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1190 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1191 ptvcursor_current_offset(ptvc), length);
1193 TRY_TO_FAKE_THIS_REPR(pi);
1195 va_start(ap, format);
1196 proto_tree_set_representation(pi, format, ap);
1199 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1202 /* Add a text-only node, leaving it to our caller to fill the text in */
1204 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1211 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1216 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1218 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1219 const char *format, ...)
1223 header_field_info *hfinfo;
1226 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1228 tvb_ensure_bytes_exist(tvb, start, length);
1231 CHECK_FOR_NULL_TREE(tree);
1233 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1235 pi = proto_tree_add_text_node(tree, tvb, start, length);
1237 TRY_TO_FAKE_THIS_REPR(pi);
1239 va_start(ap, format);
1240 proto_tree_set_representation(pi, format, ap);
1246 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1248 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1249 gint length, const char *format, va_list ap)
1252 header_field_info *hfinfo;
1255 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1257 tvb_ensure_bytes_exist(tvb, start, length);
1260 CHECK_FOR_NULL_TREE(tree);
1262 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1264 pi = proto_tree_add_text_node(tree, tvb, start, length);
1266 TRY_TO_FAKE_THIS_REPR(pi);
1268 proto_tree_set_representation(pi, format, ap);
1273 /* Add a text-only node that creates a subtree underneath.
1276 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1278 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1281 /* Add a text-only node that creates a subtree underneath.
1284 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1290 va_start(ap, format);
1291 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1294 if (tree_item != NULL)
1297 pt = proto_item_add_subtree(pi, idx);
1302 /* Add a text-only node for debugging purposes. The caller doesn't need
1303 * to worry about tvbuff, start, or length. Debug message gets sent to
1306 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1311 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1314 va_start(ap, format);
1315 proto_tree_set_representation(pi, format, ap);
1318 va_start(ap, format);
1319 vprintf(format, ap);
1321 ws_debug_printf("\n");
1327 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1330 header_field_info *hfinfo;
1332 CHECK_FOR_NULL_TREE(tree);
1334 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1336 pi = proto_tree_add_text_node(tree, tvb, start, length);
1338 TRY_TO_FAKE_THIS_REPR(pi);
1340 proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1346 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1349 header_field_info *hfinfo;
1352 CHECK_FOR_NULL_TREE(tree);
1354 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1356 pi = proto_tree_add_text_node(tree, tvb, start, length);
1358 TRY_TO_FAKE_THIS_REPR(pi);
1360 str = tvb_format_text_wsp(NULL, tvb, start, length);
1361 proto_item_set_text(pi, "%s", str);
1362 wmem_free(NULL, str);
1367 void proto_report_dissector_bug(const char *format, ...)
1371 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL) {
1373 * Try to have the error message show up in the crash
1376 va_start(args, format);
1377 ws_vadd_crash_info(format, args);
1381 * Print the error message.
1383 va_start(args, format);
1384 vfprintf(stderr, format, args);
1393 va_start(args, format);
1394 VTHROW_FORMATTED(DissectorError, format, args);
1399 /* We could probably get away with changing is_error to a minimum length value. */
1401 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1404 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1406 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1410 THROW(ReportedBoundsError);
1415 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1418 gboolean length_error;
1423 value = tvb_get_guint8(tvb, offset);
1424 if (encoding & ENC_ZIGBEE) {
1425 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1432 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1433 : tvb_get_ntohs(tvb, offset);
1434 if (encoding & ENC_ZIGBEE) {
1435 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1442 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1443 : tvb_get_ntoh24(tvb, offset);
1447 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1448 : tvb_get_ntohl(tvb, offset);
1453 length_error = TRUE;
1456 length_error = FALSE;
1457 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1458 : tvb_get_ntohl(tvb, offset);
1460 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1466 static inline guint64
1467 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1470 gboolean length_error;
1475 value = tvb_get_guint8(tvb, offset);
1479 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1480 : tvb_get_ntohs(tvb, offset);
1484 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1485 : tvb_get_ntoh24(tvb, offset);
1489 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1490 : tvb_get_ntohl(tvb, offset);
1494 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1495 : tvb_get_ntoh40(tvb, offset);
1499 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1500 : tvb_get_ntoh48(tvb, offset);
1504 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1505 : tvb_get_ntoh56(tvb, offset);
1509 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1510 : tvb_get_ntoh64(tvb, offset);
1515 length_error = TRUE;
1518 length_error = FALSE;
1519 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1520 : tvb_get_ntoh64(tvb, offset);
1522 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1529 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1532 gboolean length_error;
1537 value = tvb_get_gint8(tvb, offset);
1541 value = encoding ? tvb_get_letohis(tvb, offset)
1542 : tvb_get_ntohis(tvb, offset);
1546 value = encoding ? tvb_get_letohi24(tvb, offset)
1547 : tvb_get_ntohi24(tvb, offset);
1551 value = encoding ? tvb_get_letohil(tvb, offset)
1552 : tvb_get_ntohil(tvb, offset);
1557 length_error = TRUE;
1560 length_error = FALSE;
1561 value = encoding ? tvb_get_letohil(tvb, offset)
1562 : tvb_get_ntohil(tvb, offset);
1564 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1570 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1571 * be cast-able as a gint64. This is weird, but what the code has always done.
1573 static inline guint64
1574 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1576 guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1580 value = ws_sign_ext64(value, 56);
1583 value = ws_sign_ext64(value, 48);
1586 value = ws_sign_ext64(value, 40);
1589 value = ws_sign_ext64(value, 32);
1592 value = ws_sign_ext64(value, 24);
1595 value = ws_sign_ext64(value, 16);
1598 value = ws_sign_ext64(value, 8);
1606 static inline const guint8 *
1607 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1608 gint length, gint *ret_length, const guint encoding)
1611 length = tvb_ensure_captured_length_remaining(tvb, start);
1613 *ret_length = length;
1614 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1617 /* For FT_STRINGZ */
1618 static inline const guint8 *
1619 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1620 gint start, gint length, gint *ret_length, const guint encoding)
1622 const guint8 *value;
1625 report_type_length_mismatch(tree, "a string", length, TRUE);
1628 /* This can throw an exception */
1629 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1630 } else if (length == 0) {
1633 /* In this case, length signifies the length of the string.
1635 * This could either be a null-padded string, which doesn't
1636 * necessarily have a '\0' at the end, or a null-terminated
1637 * string, with a trailing '\0'. (Yes, there are cases
1638 * where you have a string that's both counted and null-
1641 * In the first case, we must allocate a buffer of length
1642 * "length+1", to make room for a trailing '\0'.
1644 * In the second case, we don't assume that there is a
1645 * trailing '\0' there, as the packet might be malformed.
1646 * (XXX - should we throw an exception if there's no
1647 * trailing '\0'?) Therefore, we allocate a buffer of
1648 * length "length+1", and put in a trailing '\0', just to
1651 * (XXX - this would change if we made string values counted
1652 * rather than null-terminated.)
1654 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1656 *ret_length = length;
1660 /* For FT_UINT_STRING */
1661 static inline const guint8 *
1662 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1663 tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1664 const guint encoding)
1667 const guint8 *value;
1669 /* I believe it's ok if this is called with a NULL tree */
1670 if (encoding & ENC_ZIGBEE) {
1671 n = get_uint_value(tree, tvb, start, length, encoding);
1673 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1675 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1677 *ret_length = length;
1681 /* For FT_STRINGZPAD */
1682 static inline const guint8 *
1683 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1684 gint length, gint *ret_length, const guint encoding)
1687 * XXX - currently, string values are null-
1688 * terminated, so a "zero-padded" string
1689 * isn't special. If we represent string
1690 * values as something that includes a counted
1691 * array of bytes, we'll need to strip
1695 length = tvb_ensure_captured_length_remaining(tvb, start);
1697 *ret_length = length;
1698 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1702 * Epochs for various non-UN*X time stamp formats.
1704 #define NTP_TIMEDIFF1900TO1970SEC G_GINT64_CONSTANT(2208988800) /* NTP Time Diff 1900 to 1970 in sec */
1705 #define NTP_TIMEDIFF1970TO2036SEC G_GINT64_CONSTANT(2085978496) /* NTP Time Diff 1970 to 2036 in sec */
1706 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800) /* System/3x0 and z/Architecture TOD clock */
1708 /* this can be called when there is no tree, so tree may be null */
1710 get_time_value(proto_tree *tree, tvbuff_t *tvb, const gint start,
1711 const gint length, const guint encoding, nstime_t *time_stamp,
1712 const gboolean is_relative)
1719 case ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN:
1721 * If the length is 16, 8-byte seconds, followed
1722 * by 8-byte fractional time in nanoseconds,
1725 * If the length is 12, 8-byte seconds, followed
1726 * by 4-byte fractional time in nanoseconds,
1729 * If the length is 8, 4-byte seconds, followed
1730 * by 4-byte fractional time in nanoseconds,
1733 * For absolute times, the seconds are seconds
1734 * since the UN*X epoch.
1737 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1738 time_stamp->nsecs = (guint32)tvb_get_ntoh64(tvb, start+8);
1739 } else if (length == 12) {
1740 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1741 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1742 } else if (length == 8) {
1743 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1744 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1745 } else if (length == 4) {
1747 * Backwards compatibility.
1748 * ENC_TIME_SECS_NSECS is 0; using
1749 * ENC_BIG_ENDIAN by itself with a 4-byte
1750 * time-in-seconds value was done in the
1753 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1754 time_stamp->nsecs = 0;
1756 time_stamp->secs = 0;
1757 time_stamp->nsecs = 0;
1758 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1762 case ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN:
1764 * If the length is 16, 8-byte seconds, followed
1765 * by 8-byte fractional time in nanoseconds,
1766 * both little-endian.
1768 * If the length is 12, 8-byte seconds, followed
1769 * by 4-byte fractional time in nanoseconds,
1770 * both little-endian.
1772 * If the length is 8, 4-byte seconds, followed
1773 * by 4-byte fractional time in nanoseconds,
1774 * both little-endian.
1776 * For absolute times, the seconds are seconds
1777 * since the UN*X epoch.
1780 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1781 time_stamp->nsecs = (guint32)tvb_get_letoh64(tvb, start+8);
1782 } else if (length == 12) {
1783 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1784 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1785 } else if (length == 8) {
1786 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1787 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1788 } else if (length == 4) {
1790 * Backwards compatibility.
1791 * ENC_TIME_SECS_NSECS is 0; using
1792 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1793 * time-in-seconds value was done in the
1796 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1797 time_stamp->nsecs = 0;
1799 time_stamp->secs = 0;
1800 time_stamp->nsecs = 0;
1801 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1805 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1807 * NTP time stamp, big-endian.
1808 * Only supported for absolute times.
1810 DISSECTOR_ASSERT(!is_relative);
1812 /* We need a temporary variable here so the unsigned math
1813 * works correctly (for years > 2036 according to RFC 2030
1816 * If bit 0 is set, the UTC time is in the range 1968-2036 and
1817 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
1818 * If bit 0 is not set, the time is in the range 2036-2104 and
1819 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
1821 tmpsecs = tvb_get_ntohl(tvb, start);
1822 if ((tmpsecs & 0x80000000) != 0)
1823 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
1825 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
1829 * Convert 1/2^32s of a second to nanoseconds.
1831 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1832 } else if (length == 4) {
1834 * Backwards compatibility.
1836 time_stamp->nsecs = 0;
1838 time_stamp->secs = 0;
1839 time_stamp->nsecs = 0;
1840 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
1844 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1846 * NTP time stamp, little-endian.
1847 * Only supported for absolute times.
1849 DISSECTOR_ASSERT(!is_relative);
1851 /* We need a temporary variable here so the unsigned math
1852 * works correctly (for years > 2036 according to RFC 2030
1855 * If bit 0 is set, the UTC time is in the range 1968-2036 and
1856 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
1857 * If bit 0 is not set, the time is in the range 2036-2104 and
1858 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
1860 tmpsecs = tvb_get_letohl(tvb, start);
1861 if ((tmpsecs & 0x80000000) != 0)
1862 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
1864 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
1868 * Convert 1/2^32s of a second to nanoseconds.
1870 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1871 } else if (length == 4) {
1873 * Backwards compatibility.
1875 time_stamp->nsecs = 0;
1877 time_stamp->secs = 0;
1878 time_stamp->nsecs = 0;
1879 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
1883 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1885 * S/3x0 and z/Architecture TOD clock time stamp,
1887 * Only supported for absolute times.
1889 DISSECTOR_ASSERT(!is_relative);
1890 DISSECTOR_ASSERT(length == 8);
1893 todsecs = tvb_get_ntoh64(tvb, start) >> 12;
1894 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1895 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1897 time_stamp->secs = 0;
1898 time_stamp->nsecs = 0;
1899 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
1903 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1905 * S/3x0 and z/Architecture TOD clock time stamp,
1907 * Only supported for absolute times.
1909 DISSECTOR_ASSERT(!is_relative);
1912 todsecs = tvb_get_letoh64(tvb, start) >> 12 ;
1913 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1914 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1916 time_stamp->secs = 0;
1917 time_stamp->nsecs = 0;
1918 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
1922 case ENC_TIME_RTPS|ENC_BIG_ENDIAN:
1924 * Time stamp using the same seconds/fraction format
1925 * as NTP, but with the origin of the time stamp being
1926 * the UNIX epoch rather than the NTP epoch; big-
1929 * Only supported for absolute times.
1931 DISSECTOR_ASSERT(!is_relative);
1934 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1936 * Convert 1/2^32s of a second to nanoseconds.
1938 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1940 time_stamp->secs = 0;
1941 time_stamp->nsecs = 0;
1942 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
1946 case ENC_TIME_RTPS|ENC_LITTLE_ENDIAN:
1948 * Time stamp using the same seconds/fraction format
1949 * as NTP, but with the origin of the time stamp being
1950 * the UNIX epoch rather than the NTP epoch; little-
1953 * Only supported for absolute times.
1955 DISSECTOR_ASSERT(!is_relative);
1958 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1960 * Convert 1/2^32s of a second to nanoseconds.
1962 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1964 time_stamp->secs = 0;
1965 time_stamp->nsecs = 0;
1966 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
1970 case ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN:
1972 * 4-byte seconds, followed by 4-byte fractional
1973 * time in microseconds, both big-endian.
1974 * For absolute times, the seconds are seconds
1975 * since the UN*X epoch.
1978 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1979 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
1981 time_stamp->secs = 0;
1982 time_stamp->nsecs = 0;
1983 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
1987 case ENC_TIME_SECS_USECS|ENC_LITTLE_ENDIAN:
1989 * 4-byte seconds, followed by 4-byte fractional
1990 * time in microseconds, both little-endian.
1991 * For absolute times, the seconds are seconds
1992 * since the UN*X epoch.
1995 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1996 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
1998 time_stamp->secs = 0;
1999 time_stamp->nsecs = 0;
2000 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2004 case ENC_TIME_SECS|ENC_BIG_ENDIAN:
2005 case ENC_TIME_SECS|ENC_LITTLE_ENDIAN:
2007 * Seconds, 1 to 8 bytes.
2008 * For absolute times, it's seconds since the
2011 if (length >= 1 && length <= 8) {
2012 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2013 time_stamp->nsecs = 0;
2015 time_stamp->secs = 0;
2016 time_stamp->nsecs = 0;
2017 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2021 case ENC_TIME_MSECS|ENC_BIG_ENDIAN:
2023 * Milliseconds, 1 to 8 bytes.
2024 * For absolute times, it's milliseconds since the
2027 if (length >= 1 && length <= 8) {
2030 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2031 time_stamp->secs = (time_t)(msecs / 1000);
2032 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2034 time_stamp->secs = 0;
2035 time_stamp->nsecs = 0;
2036 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2040 case ENC_TIME_RFC_3971|ENC_BIG_ENDIAN:
2042 * 1/64ths of a second since the UN*X epoch,
2045 * Only supported for absolute times.
2047 DISSECTOR_ASSERT(!is_relative);
2051 * The upper 48 bits are seconds since the
2054 time_stamp->secs = tvb_get_ntoh48(tvb, start);
2056 * The lower 16 bits are 1/2^16s of a second;
2057 * convert them to nanoseconds.
2059 * XXX - this may give the impression of higher
2060 * precision than you actually get.
2062 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2064 time_stamp->secs = 0;
2065 time_stamp->nsecs = 0;
2066 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2070 case ENC_TIME_RFC_3971|ENC_LITTLE_ENDIAN:
2072 * 1/64ths of a second since the UN*X epoch,
2075 * Only supported for absolute times.
2077 DISSECTOR_ASSERT(!is_relative);
2081 * XXX - this is assuming that, if anybody
2082 * were ever to use this format - RFC 3971
2083 * doesn't, because that's an Internet
2084 * protocol, and those use network byte
2085 * order, i.e. big-endian - they'd treat it
2086 * as a 64-bit count of 1/2^16s of a second,
2087 * putting the upper 48 bits at the end.
2089 * The lower 48 bits are seconds since the
2092 time_stamp->secs = tvb_get_letoh48(tvb, start+2);
2094 * The upper 16 bits are 1/2^16s of a second;
2095 * convert them to nanoseconds.
2097 * XXX - this may give the impression of higher
2098 * precision than you actually get.
2100 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2102 time_stamp->secs = 0;
2103 time_stamp->nsecs = 0;
2104 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2108 case ENC_TIME_SECS_NTP|ENC_BIG_ENDIAN:
2110 * NTP time stamp, with 1-second resolution (i.e.,
2111 * seconds since the NTP epoch), big-endian.
2112 * Only supported for absolute times.
2114 DISSECTOR_ASSERT(!is_relative);
2118 * We need a temporary variable here so the unsigned math
2119 * works correctly (for years > 2036 according to RFC 2030
2122 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2123 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2124 * If bit 0 is not set, the time is in the range 2036-2104 and
2125 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2127 tmpsecs = tvb_get_ntohl(tvb, start);
2128 if ((tmpsecs & 0x80000000) != 0)
2129 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2131 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2132 time_stamp->nsecs = 0;
2134 time_stamp->secs = 0;
2135 time_stamp->nsecs = 0;
2136 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2140 case ENC_TIME_SECS_NTP|ENC_LITTLE_ENDIAN:
2142 * NTP time stamp, with 1-second resolution (i.e.,
2143 * seconds since the NTP epoch), little-endian.
2144 * Only supported for absolute times.
2146 DISSECTOR_ASSERT(!is_relative);
2149 * We need a temporary variable here so the unsigned math
2150 * works correctly (for years > 2036 according to RFC 2030
2153 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2154 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2155 * If bit 0 is not set, the time is in the range 2036-2104 and
2156 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2159 tmpsecs = tvb_get_letohl(tvb, start);
2160 if ((tmpsecs & 0x80000000) != 0)
2161 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2163 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2164 time_stamp->nsecs = 0;
2166 time_stamp->secs = 0;
2167 time_stamp->nsecs = 0;
2168 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2171 case ENC_TIME_MSEC_NTP | ENC_BIG_ENDIAN:
2173 * Milliseconds, 1 to 8 bytes.
2174 * For absolute times, it's milliseconds since the
2177 if (length >= 1 && length <= 8) {
2180 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2181 tmpsecs = (guint32)(msecs / 1000);
2183 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2184 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2185 * If bit 0 is not set, the time is in the range 2036-2104 and
2186 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2188 if ((tmpsecs & 0x80000000) != 0)
2189 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2191 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2192 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2195 time_stamp->secs = 0;
2196 time_stamp->nsecs = 0;
2197 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 4));
2201 DISSECTOR_ASSERT_NOT_REACHED();
2207 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2209 const header_field_info *hfinfo = fi->hfinfo;
2211 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
2212 GPtrArray *ptrs = NULL;
2214 if (tree_data->interesting_hfids == NULL) {
2215 /* Initialize the hash because we now know that it is needed */
2216 tree_data->interesting_hfids =
2217 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
2218 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2219 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2220 GINT_TO_POINTER(hfinfo->id));
2224 /* First element triggers the creation of pointer array */
2225 ptrs = g_ptr_array_new();
2226 g_hash_table_insert(tree_data->interesting_hfids,
2227 GINT_TO_POINTER(hfinfo->id), ptrs);
2230 g_ptr_array_add(ptrs, fi);
2236 * Validates that field length bytes are available starting from
2237 * start (pos/neg). Throws an exception if they aren't.
2240 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2241 gint start, gint length, const guint encoding)
2248 if ((hfinfo->type == FT_STRINGZ) ||
2249 ((encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC)) &&
2250 (IS_FT_UINT(hfinfo->type) || IS_FT_INT(hfinfo->type)))) {
2251 /* If we're fetching until the end of the TVB, only validate
2252 * that the offset is within range.
2258 tvb_ensure_bytes_exist(tvb, start, size);
2262 detect_trailing_stray_characters(const char *string, gint length, proto_item *pi)
2264 gboolean found_stray_character = FALSE;
2266 for (gint i = (gint)strlen(string); i < length; i++) {
2267 if (string[i] != '\0') {
2268 found_stray_character = TRUE;
2273 if (found_stray_character) {
2274 expert_add_info(NULL, pi, &ei_string_trailing_characters);
2278 /* Add an item to a proto_tree, using the text label registered to that item;
2279 the item is extracted from the tvbuff handed to it. */
2281 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2282 tvbuff_t *tvb, gint start, gint length,
2290 const char *stringval = NULL;
2291 nstime_t time_stamp;
2292 gboolean length_error;
2294 switch (new_fi->hfinfo->type) {
2296 /* no value to set for FT_NONE */
2300 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
2304 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2308 n = get_uint_value(tree, tvb, start, length, encoding);
2309 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2311 /* Instead of calling proto_item_set_len(), since we don't yet
2312 * have a proto_item, we set the field_info's length ourselves. */
2313 new_fi->length = n + length;
2318 * Map all non-zero values to little-endian for
2319 * backwards compatibility.
2322 encoding = ENC_LITTLE_ENDIAN;
2323 proto_tree_set_boolean(new_fi,
2324 get_uint64_value(tree, tvb, start, length, encoding));
2328 /* XXX - make these just FT_UINT? */
2333 if (encoding & ENC_VARINT_PROTOBUF) {
2334 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2335 new_fi->flags |= FI_VARINT;
2336 value = (guint32)value64;
2337 } else if (encoding & ENC_VARINT_QUIC) {
2338 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2339 value = (guint32)value64;
2342 * Map all non-zero values to little-endian for
2343 * backwards compatibility.
2346 encoding = ENC_LITTLE_ENDIAN;
2348 value = get_uint_value(tree, tvb, start, length, encoding);
2350 proto_tree_set_uint(new_fi, value);
2358 if (encoding & ENC_VARINT_PROTOBUF) {
2359 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2360 new_fi->flags |= FI_VARINT;
2361 } else if (encoding & ENC_VARINT_QUIC) {
2362 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2365 * Map all other non-zero values to little-endian for
2366 * backwards compatibility.
2369 encoding = ENC_LITTLE_ENDIAN;
2371 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2373 proto_tree_set_uint64(new_fi, value64);
2376 /* XXX - make these just FT_INT? */
2382 * Map all non-zero values to little-endian for
2383 * backwards compatibility.
2386 encoding = ENC_LITTLE_ENDIAN;
2387 proto_tree_set_int(new_fi,
2388 get_int_value(tree, tvb, start, length, encoding));
2396 * Map all non-zero values to little-endian for
2397 * backwards compatibility.
2400 encoding = ENC_LITTLE_ENDIAN;
2401 proto_tree_set_int64(new_fi,
2402 get_int64_value(tree, tvb, start, length, encoding));
2407 * Map all non-zero values to little-endian for
2408 * backwards compatibility.
2411 encoding = ENC_LITTLE_ENDIAN;
2412 if (length != FT_IPv4_LEN) {
2413 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
2414 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2416 value = tvb_get_ipv4(tvb, start);
2418 * NOTE: to support code written when
2419 * proto_tree_add_item() took a gboolean as its
2420 * last argument, with FALSE meaning "big-endian"
2421 * and TRUE meaning "little-endian", we treat any
2422 * non-zero value of "encoding" as meaning
2425 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
2429 if (length != FT_IPXNET_LEN) {
2430 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
2431 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2433 proto_tree_set_ipxnet(new_fi,
2434 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
2438 if (length != FT_IPv6_LEN) {
2439 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
2440 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2442 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2446 if (length != FT_FCWWN_LEN) {
2447 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2448 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2450 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2455 length_error = length < 7 ? TRUE : FALSE;
2456 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2458 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2462 if (length != VINES_ADDR_LEN) {
2463 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2464 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2466 proto_tree_set_vines_tvb(new_fi, tvb, start);
2470 if (length != FT_ETHER_LEN) {
2471 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2472 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2474 proto_tree_set_ether_tvb(new_fi, tvb, start);
2479 * Map all non-zero values to little-endian for
2480 * backwards compatibility.
2483 encoding = ENC_LITTLE_ENDIAN;
2484 if (length != FT_EUI64_LEN) {
2485 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2486 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2488 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2492 * Map all non-zero values to little-endian for
2493 * backwards compatibility.
2496 encoding = ENC_LITTLE_ENDIAN;
2497 if (length != FT_GUID_LEN) {
2498 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2499 report_type_length_mismatch(tree, "a GUID", length, length_error);
2501 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2506 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2510 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2515 * NOTE: to support code written when
2516 * proto_tree_add_item() took a gboolean as its
2517 * last argument, with FALSE meaning "big-endian"
2518 * and TRUE meaning "little-endian", we treat any
2519 * non-zero value of "encoding" as meaning
2522 * At some point in the future, we might
2523 * support non-IEEE-binary floating-point
2524 * formats in the encoding as well
2525 * (IEEE decimal, System/3x0, VAX).
2528 encoding = ENC_LITTLE_ENDIAN;
2530 length_error = length < 4 ? TRUE : FALSE;
2531 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2534 floatval = tvb_get_letohieee_float(tvb, start);
2536 floatval = tvb_get_ntohieee_float(tvb, start);
2537 proto_tree_set_float(new_fi, floatval);
2542 * NOTE: to support code written when
2543 * proto_tree_add_item() took a gboolean as its
2544 * last argument, with FALSE meaning "big-endian"
2545 * and TRUE meaning "little-endian", we treat any
2546 * non-zero value of "encoding" as meaning
2549 * At some point in the future, we might
2550 * support non-IEEE-binary floating-point
2551 * formats in the encoding as well
2552 * (IEEE decimal, System/3x0, VAX).
2554 if (encoding == TRUE)
2555 encoding = ENC_LITTLE_ENDIAN;
2557 length_error = length < 8 ? TRUE : FALSE;
2558 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2561 doubleval = tvb_get_letohieee_double(tvb, start);
2563 doubleval = tvb_get_ntohieee_double(tvb, start);
2564 proto_tree_set_double(new_fi, doubleval);
2568 stringval = get_string_value(wmem_packet_scope(),
2569 tvb, start, length, &length, encoding);
2570 proto_tree_set_string(new_fi, stringval);
2572 /* Instead of calling proto_item_set_len(), since we
2573 * don't yet have a proto_item, we set the
2574 * field_info's length ourselves.
2576 * XXX - our caller can't use that length to
2577 * advance an offset unless they arrange that
2578 * there always be a protocol tree into which
2579 * we're putting this item.
2581 new_fi->length = length;
2585 stringval = get_stringz_value(wmem_packet_scope(),
2586 tree, tvb, start, length, &length, encoding);
2587 proto_tree_set_string(new_fi, stringval);
2589 /* Instead of calling proto_item_set_len(),
2590 * since we don't yet have a proto_item, we
2591 * set the field_info's length ourselves.
2593 * XXX - our caller can't use that length to
2594 * advance an offset unless they arrange that
2595 * there always be a protocol tree into which
2596 * we're putting this item.
2598 new_fi->length = length;
2601 case FT_UINT_STRING:
2603 * NOTE: to support code written when
2604 * proto_tree_add_item() took a gboolean as its
2605 * last argument, with FALSE meaning "big-endian"
2606 * and TRUE meaning "little-endian", if the
2607 * encoding value is TRUE, treat that as
2608 * ASCII with a little-endian length.
2610 * This won't work for code that passes
2611 * arbitrary non-zero values; that code
2612 * will need to be fixed.
2614 if (encoding == TRUE)
2615 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2616 stringval = get_uint_string_value(wmem_packet_scope(),
2617 tree, tvb, start, length, &length, encoding);
2618 proto_tree_set_string(new_fi, stringval);
2620 /* Instead of calling proto_item_set_len(), since we
2621 * don't yet have a proto_item, we set the
2622 * field_info's length ourselves.
2624 * XXX - our caller can't use that length to
2625 * advance an offset unless they arrange that
2626 * there always be a protocol tree into which
2627 * we're putting this item.
2629 new_fi->length = length;
2633 stringval = get_stringzpad_value(wmem_packet_scope(),
2634 tvb, start, length, &length, encoding);
2635 proto_tree_set_string(new_fi, stringval);
2637 /* Instead of calling proto_item_set_len(), since we
2638 * don't yet have a proto_item, we set the
2639 * field_info's length ourselves.
2641 * XXX - our caller can't use that length to
2642 * advance an offset unless they arrange that
2643 * there always be a protocol tree into which
2644 * we're putting this item.
2646 new_fi->length = length;
2649 case FT_ABSOLUTE_TIME:
2651 * Absolute times can be in any of a number of
2652 * formats, and they can be big-endian or
2655 * Historically FT_TIMEs were only timespecs;
2656 * the only question was whether they were stored
2657 * in big- or little-endian format.
2659 * For backwards compatibility, we interpret an
2660 * encoding of 1 as meaning "little-endian timespec",
2661 * so that passing TRUE is interpreted as that.
2663 if (encoding == TRUE)
2664 encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2666 get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
2668 proto_tree_set_time(new_fi, &time_stamp);
2671 case FT_RELATIVE_TIME:
2673 * Relative times can be in any of a number of
2674 * formats, and they can be big-endian or
2677 * Historically FT_TIMEs were only timespecs;
2678 * the only question was whether they were stored
2679 * in big- or little-endian format.
2681 * For backwards compatibility, we interpret an
2682 * encoding of 1 as meaning "little-endian timespec",
2683 * so that passing TRUE is interpreted as that.
2685 if (encoding == TRUE)
2686 encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2688 get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
2690 proto_tree_set_time(new_fi, &time_stamp);
2692 case FT_IEEE_11073_SFLOAT:
2694 encoding = ENC_LITTLE_ENDIAN;
2696 length_error = length < 2 ? TRUE : FALSE;
2697 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2700 fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2703 case FT_IEEE_11073_FLOAT:
2705 encoding = ENC_LITTLE_ENDIAN;
2707 length_error = length < 4 ? TRUE : FALSE;
2708 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2713 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2714 new_fi->hfinfo->type,
2715 ftype_name(new_fi->hfinfo->type));
2716 DISSECTOR_ASSERT_NOT_REACHED();
2719 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2721 /* Don't add new node to proto_tree until now so that any exceptions
2722 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2723 /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2724 * to know which item caused exception? */
2725 pi = proto_tree_add_node(tree, new_fi);
2728 /* Detect trailing stray characters */
2729 detect_trailing_stray_characters(stringval, length, pi);
2736 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2737 const gint start, gint length,
2738 const guint encoding, gint32 *retval)
2740 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2744 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2746 switch (hfinfo->type) {
2753 DISSECTOR_ASSERT_NOT_REACHED();
2756 /* length validation for native number encoding caught by get_uint_value() */
2757 /* length has to be -1 or > 0 regardless of encoding */
2758 if (length < -1 || length == 0)
2759 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_int",
2762 if (encoding & ENC_STRING) {
2763 REPORT_DISSECTOR_BUG("wrong encoding");
2765 /* I believe it's ok if this is called with a NULL tree */
2766 value = get_int_value(tree, tvb, start, length, encoding);
2771 if (hfinfo->bitmask) {
2772 /* Mask out irrelevant portions */
2773 *retval &= (guint32)(hfinfo->bitmask);
2775 *retval >>= hfinfo_bitshift(hfinfo);
2777 no_of_bits = ws_count_ones(hfinfo->bitmask);
2778 *retval = ws_sign_ext32(*retval, no_of_bits);
2781 CHECK_FOR_NULL_TREE(tree);
2783 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2785 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2787 proto_tree_set_int(new_fi, value);
2789 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2791 return proto_tree_add_node(tree, new_fi);
2795 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2796 const gint start, gint length,
2797 const guint encoding, guint32 *retval)
2799 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2803 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2805 switch (hfinfo->type) {
2813 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2817 /* length validation for native number encoding caught by get_uint_value() */
2818 /* length has to be -1 or > 0 regardless of encoding */
2819 if (length < -1 || length == 0)
2820 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
2823 if (encoding & ENC_STRING) {
2824 REPORT_DISSECTOR_BUG("wrong encoding");
2826 /* I believe it's ok if this is called with a NULL tree */
2827 /* XXX - modify if we ever support EBCDIC FT_CHAR */
2828 if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC)) {
2830 tvb_get_varint(tvb, start, length, &temp64, encoding);
2831 value = (guint32)temp64;
2833 value = get_uint_value(tree, tvb, start, length, encoding);
2838 if (hfinfo->bitmask) {
2839 /* Mask out irrelevant portions */
2840 *retval &= (guint32)(hfinfo->bitmask);
2842 *retval >>= hfinfo_bitshift(hfinfo);
2846 CHECK_FOR_NULL_TREE(tree);
2848 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2850 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2852 proto_tree_set_uint(new_fi, value);
2854 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2855 if (encoding & ENC_VARINT_PROTOBUF) {
2856 new_fi->flags |= FI_VARINT;
2858 return proto_tree_add_node(tree, new_fi);
2861 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2862 * and returns proto_item* and uint value retreived*/
2864 ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, gint length,
2865 const guint encoding, guint32 *retval)
2868 header_field_info *hfinfo;
2873 offset = ptvc->offset;
2874 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2876 switch (hfinfo->type) {
2884 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2888 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
2889 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
2891 /* I believe it's ok if this is called with a NULL tree */
2892 /* XXX - modify if we ever support EBCDIC FT_CHAR */
2893 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
2897 if (hfinfo->bitmask) {
2898 /* Mask out irrelevant portions */
2899 *retval &= (guint32)(hfinfo->bitmask);
2901 *retval >>= hfinfo_bitshift(hfinfo);
2905 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2906 item_length, encoding);
2908 CHECK_FOR_NULL_TREE(ptvc->tree);
2910 /* Coast clear. Try and fake it */
2911 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2913 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2915 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2916 offset, length, encoding);
2919 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2920 * and returns proto_item* and int value retreived*/
2922 ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, gint length,
2923 const guint encoding, gint32 *retval)
2926 header_field_info *hfinfo;
2931 offset = ptvc->offset;
2932 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2934 switch (hfinfo->type) {
2941 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2945 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
2946 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
2948 /* I believe it's ok if this is called with a NULL tree */
2949 /* XXX - modify if we ever support EBCDIC FT_CHAR */
2950 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
2955 if (hfinfo->bitmask) {
2956 /* Mask out irrelevant portions */
2957 *retval &= (guint32)(hfinfo->bitmask);
2959 *retval >>= hfinfo_bitshift(hfinfo);
2961 no_of_bits = ws_count_ones(hfinfo->bitmask);
2962 *retval = ws_sign_ext32(*retval, no_of_bits);
2965 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2966 item_length, encoding);
2968 CHECK_FOR_NULL_TREE(ptvc->tree);
2970 /* Coast clear. Try and fake it */
2971 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2973 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2975 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2976 offset, length, encoding);
2979 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2980 * and returns proto_item* and string value retreived */
2982 ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, wmem_allocator_t *scope, const guint8 **retval)
2984 header_field_info *hfinfo;
2986 const guint8 *value;
2990 offset = ptvc->offset;
2992 PROTO_REGISTRAR_GET_NTH(hf, hfinfo);
2994 switch (hfinfo->type) {
2996 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
2999 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3001 case FT_UINT_STRING:
3002 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3005 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3008 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, or FT_STRINGZPAD",
3015 ptvc->offset += item_length;
3017 CHECK_FOR_NULL_TREE(ptvc->tree);
3019 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3021 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3023 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3024 offset, length, encoding);
3027 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3028 * and returns proto_item* and boolean value retreived */
3030 ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, gint length, const guint encoding, gboolean *retval)
3032 header_field_info *hfinfo;
3036 guint64 value, bitval;
3038 offset = ptvc->offset;
3039 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3041 if (hfinfo->type != FT_BOOLEAN) {
3042 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3046 /* length validation for native number encoding caught by get_uint64_value() */
3047 /* length has to be -1 or > 0 regardless of encoding */
3048 if (length < -1 || length == 0)
3049 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3052 if (encoding & ENC_STRING) {
3053 REPORT_DISSECTOR_BUG("wrong encoding");
3056 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3057 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3059 /* I believe it's ok if this is called with a NULL tree */
3060 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3064 if (hfinfo->bitmask) {
3065 /* Mask out irrelevant portions */
3066 bitval &= hfinfo->bitmask;
3068 *retval = (bitval != 0);
3071 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3072 item_length, encoding);
3074 CHECK_FOR_NULL_TREE(ptvc->tree);
3076 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3078 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3080 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3081 offset, length, encoding);
3085 proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3086 const gint start, gint length, const guint encoding, guint64 *retval)
3088 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3092 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3094 switch (hfinfo->type) {
3101 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
3105 /* length validation for native number encoding caught by get_uint64_value() */
3106 /* length has to be -1 or > 0 regardless of encoding */
3107 if (length < -1 || length == 0)
3108 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3111 if (encoding & ENC_STRING) {
3112 REPORT_DISSECTOR_BUG("wrong encoding");
3114 /* I believe it's ok if this is called with a NULL tree */
3115 if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC)) {
3116 tvb_get_varint(tvb, start, length, &value, encoding);
3118 value = get_uint64_value(tree, tvb, start, length, encoding);
3123 if (hfinfo->bitmask) {
3124 /* Mask out irrelevant portions */
3125 *retval &= hfinfo->bitmask;
3127 *retval >>= hfinfo_bitshift(hfinfo);
3131 CHECK_FOR_NULL_TREE(tree);
3133 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3135 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3137 proto_tree_set_uint64(new_fi, value);
3139 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3140 if (encoding & ENC_VARINT_PROTOBUF) {
3141 new_fi->flags |= FI_VARINT;
3144 return proto_tree_add_node(tree, new_fi);
3148 proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3149 const gint start, gint length, const guint encoding, guint64 *retval, gint *lenretval)
3151 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3155 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3157 if ((!IS_FT_INT(hfinfo->type)) && (!IS_FT_UINT(hfinfo->type))) {
3158 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",
3162 /* length validation for native number encoding caught by get_uint64_value() */
3163 /* length has to be -1 or > 0 regardless of encoding */
3165 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",
3168 if (encoding & ENC_STRING) {
3169 REPORT_DISSECTOR_BUG("wrong encoding");
3172 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value, encoding);
3176 if (hfinfo->bitmask) {
3177 /* Mask out irrelevant portions */
3178 *retval &= hfinfo->bitmask;
3180 *retval >>= hfinfo_bitshift(hfinfo);
3185 *lenretval = length;
3188 CHECK_FOR_NULL_TREE(tree);
3190 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3192 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3194 proto_tree_set_uint64(new_fi, value);
3196 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3197 if (encoding & ENC_VARINT_PROTOBUF) {
3198 new_fi->flags |= FI_VARINT;
3201 return proto_tree_add_node(tree, new_fi);
3206 proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3207 const gint start, gint length,
3208 const guint encoding, gboolean *retval)
3210 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3212 guint64 value, bitval;
3214 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3216 if (hfinfo->type != FT_BOOLEAN) {
3217 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3221 /* length validation for native number encoding caught by get_uint64_value() */
3222 /* length has to be -1 or > 0 regardless of encoding */
3223 if (length < -1 || length == 0)
3224 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3227 if (encoding & ENC_STRING) {
3228 REPORT_DISSECTOR_BUG("wrong encoding");
3230 /* I believe it's ok if this is called with a NULL tree */
3231 value = get_uint64_value(tree, tvb, start, length, encoding);
3235 if (hfinfo->bitmask) {
3236 /* Mask out irrelevant portions */
3237 bitval &= hfinfo->bitmask;
3239 *retval = (bitval != 0);
3242 CHECK_FOR_NULL_TREE(tree);
3244 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3246 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3248 proto_tree_set_boolean(new_fi, value);
3250 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3252 return proto_tree_add_node(tree, new_fi);
3256 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
3258 const gint start, gint length,
3259 const guint encoding,
3260 wmem_allocator_t *scope,
3261 const guint8 **retval,
3265 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3267 const guint8 *value;
3269 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3271 switch (hfinfo->type) {
3273 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
3276 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
3278 case FT_UINT_STRING:
3279 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
3282 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
3285 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, or FT_STRINGZPAD",
3292 CHECK_FOR_NULL_TREE(tree);
3294 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3296 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
3298 proto_tree_set_string(new_fi, value);
3300 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3302 pi = proto_tree_add_node(tree, new_fi);
3305 /* Detect trailing stray characters */
3306 detect_trailing_stray_characters(value, length, pi);
3313 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3314 const gint start, gint length,
3315 const guint encoding, wmem_allocator_t *scope,
3316 const guint8 **retval)
3318 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
3319 tvb, start, length, encoding, scope, retval, &length);
3323 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3324 and returns proto_item* */
3326 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
3327 const guint encoding)
3330 header_field_info *hfinfo;
3334 offset = ptvc->offset;
3335 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3336 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3337 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3339 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3340 item_length, encoding);
3342 CHECK_FOR_NULL_TREE(ptvc->tree);
3344 /* Coast clear. Try and fake it */
3345 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3347 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3349 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3350 offset, length, encoding);
3353 /* Add an item to a proto_tree, using the text label registered to that item;
3354 the item is extracted from the tvbuff handed to it. */
3356 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
3357 const gint start, gint length, const guint encoding)
3362 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3364 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3365 test_length(hfinfo, tvb, start, item_length, encoding);
3367 CHECK_FOR_NULL_TREE(tree);
3369 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3371 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3373 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3377 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3378 const gint start, gint length, const guint encoding)
3380 register header_field_info *hfinfo;
3382 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3383 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
3386 /* Add an item to a proto_tree, using the text label registered to that item;
3387 the item is extracted from the tvbuff handed to it.
3389 Return the length of the item through the pointer. */
3391 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
3392 tvbuff_t *tvb, const gint start,
3393 gint length, const guint encoding,
3400 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3402 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3403 test_length(hfinfo, tvb, start, item_length, encoding);
3407 * We need to get the correct item length here.
3408 * That's normally done by proto_tree_new_item(),
3409 * but we won't be calling it.
3411 *lenretval = get_full_length(hfinfo, tvb, start, length,
3412 item_length, encoding);
3416 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
3418 * Even if the tree item is not referenced (and thus faked),
3419 * the caller must still be informed of the actual length.
3421 *lenretval = get_full_length(hfinfo, tvb, start, length,
3422 item_length, encoding);
3425 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3427 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3428 *lenretval = new_fi->length;
3433 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3434 const gint start, gint length,
3435 const guint encoding, gint *lenretval)
3437 register header_field_info *hfinfo;
3439 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3440 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
3443 /* which FT_ types can use proto_tree_add_bytes_item() */
3444 static inline gboolean
3445 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
3447 return (type == FT_BYTES ||
3448 type == FT_UINT_BYTES ||
3450 type == FT_REL_OID ||
3451 type == FT_SYSTEM_ID );
3454 /* Note: this does no validation that the byte array of an FT_OID or
3455 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
3456 so I think it's ok to continue not validating it?
3459 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3460 const gint start, gint length, const guint encoding,
3461 GByteArray *retval, gint *endoff, gint *err)
3464 GByteArray *bytes = retval;
3465 GByteArray *created_bytes = NULL;
3468 header_field_info *hfinfo;
3469 gboolean generate = (bytes || tree) ? TRUE : FALSE;
3471 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3473 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3475 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
3476 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
3478 /* length has to be -1 or > 0 regardless of encoding */
3479 /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
3480 if (length < -1 || length == 0) {
3481 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_bytes_item for %s",
3482 length, ftype_name(hfinfo->type));
3485 if (encoding & ENC_STR_NUM) {
3486 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
3489 if (generate && (encoding & ENC_STR_HEX)) {
3490 if (hfinfo->type == FT_UINT_BYTES) {
3491 /* can't decode FT_UINT_BYTES from strings */
3492 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
3493 "FT_UINT_BYTES type, but as ENC_STR_HEX");
3497 /* caller doesn't care about return value, but we need it to
3498 call tvb_get_string_bytes() and set the tree later */
3499 bytes = created_bytes = g_byte_array_new();
3502 /* bytes might be NULL after this, but can't add expert error until later */
3503 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
3505 /* grab the errno now before it gets overwritten */
3508 else if (generate) {
3509 tvb_ensure_bytes_exist(tvb, start, length);
3512 /* caller doesn't care about return value, but we need it to
3513 call tvb_get_string_bytes() and set the tree later */
3514 bytes = created_bytes = g_byte_array_new();
3517 if (hfinfo->type == FT_UINT_BYTES) {
3518 n = length; /* n is now the "header" length */
3519 length = get_uint_value(tree, tvb, start, n, encoding);
3520 /* length is now the value's length; only store the value in the array */
3521 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
3523 else if (length > 0) {
3524 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
3528 *endoff = start + n + length;
3531 if (err) *err = saved_err;
3533 CHECK_FOR_NULL_TREE_AND_FREE(tree,
3536 g_byte_array_free(created_bytes, TRUE);
3537 created_bytes = NULL;
3541 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
3544 g_byte_array_free(created_bytes, TRUE);
3545 created_bytes = NULL;
3549 /* n will be zero except when it's a FT_UINT_BYTES */
3550 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
3552 if (encoding & ENC_STRING) {
3553 if (saved_err == ERANGE)
3554 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
3555 else if (!bytes || saved_err != 0)
3556 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
3559 proto_tree_set_bytes_gbytearray(new_fi, bytes);
3561 proto_tree_set_bytes(new_fi, NULL, 0);
3564 g_byte_array_free(created_bytes, TRUE);
3567 /* n will be zero except when it's a FT_UINT_BYTES */
3568 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
3571 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3574 return proto_tree_add_node(tree, new_fi);
3579 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3580 const gint start, gint length, const guint encoding,
3581 nstime_t *retval, gint *endoff, gint *err)
3584 nstime_t time_stamp;
3586 header_field_info *hfinfo;
3588 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3590 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3592 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3594 /* length has to be -1 or > 0 regardless of encoding */
3595 if (length < -1 || length == 0) {
3596 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_time_item",
3600 time_stamp.secs = 0;
3601 time_stamp.nsecs = 0;
3603 if (encoding & ENC_STR_TIME_MASK) {
3604 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
3605 /* grab the errno now before it gets overwritten */
3609 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
3611 tvb_ensure_bytes_exist(tvb, start, length);
3612 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
3613 if (endoff) *endoff = length;
3616 if (err) *err = saved_err;
3619 retval->secs = time_stamp.secs;
3620 retval->nsecs = time_stamp.nsecs;
3623 CHECK_FOR_NULL_TREE(tree);
3625 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3627 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3629 proto_tree_set_time(new_fi, &time_stamp);
3631 if (encoding & ENC_STRING) {
3632 if (saved_err == ERANGE)
3633 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
3634 else if (saved_err == EDOM)
3635 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
3639 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3642 return proto_tree_add_node(tree, new_fi);
3645 /* Add a FT_NONE to a proto_tree */
3647 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
3648 const gint start, gint length, const char *format,
3653 header_field_info *hfinfo;
3655 CHECK_FOR_NULL_TREE(tree);
3657 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3659 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
3661 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3663 TRY_TO_FAKE_THIS_REPR(pi);
3665 va_start(ap, format);
3666 proto_tree_set_representation(pi, format, ap);
3669 /* no value to set for FT_NONE */
3673 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
3674 * offset, and returns proto_item* */
3676 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
3677 const guint encoding)
3681 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
3687 /* Advance the ptvcursor's offset within its tvbuff without
3688 * adding anything to the proto_tree. */
3690 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
3692 ptvc->offset += length;
3697 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
3699 fvalue_set_protocol(&fi->value, tvb, field_data);
3702 /* Add a FT_PROTOCOL to a proto_tree */
3704 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3705 gint start, gint length, const char *format, ...)
3708 tvbuff_t *protocol_tvb;
3710 header_field_info *hfinfo;
3711 gchar* protocol_rep;
3713 CHECK_FOR_NULL_TREE(tree);
3715 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3717 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
3720 * This can throw an exception, so do it before we allocate anything.
3722 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
3724 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3726 va_start(ap, format);
3727 protocol_rep = g_strdup_vprintf(format, ap);
3728 proto_tree_set_protocol_tvb(PNODE_FINFO(pi), protocol_tvb, protocol_rep);
3729 g_free(protocol_rep);
3732 TRY_TO_FAKE_THIS_REPR(pi);
3734 va_start(ap, format);
3735 proto_tree_set_representation(pi, format, ap);
3741 /* Add a FT_BYTES to a proto_tree */
3743 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3744 gint length, const guint8 *start_ptr)
3747 header_field_info *hfinfo;
3750 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3751 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
3752 test_length(hfinfo, tvb, start, item_length, ENC_NA);
3754 CHECK_FOR_NULL_TREE(tree);
3756 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3758 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
3760 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3761 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
3766 /* Add a FT_BYTES to a proto_tree */
3768 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3769 gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
3772 header_field_info *hfinfo;
3775 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3776 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA);
3777 test_length(hfinfo, tvb, start, item_length, ENC_NA);
3779 CHECK_FOR_NULL_TREE(tree);
3781 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3783 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
3785 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
3786 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
3792 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3793 gint start, gint length,
3794 const guint8 *start_ptr,
3795 const char *format, ...)
3800 if (start_ptr == NULL)
3801 start_ptr = tvb_get_ptr(tvb, start, length);
3803 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
3805 TRY_TO_FAKE_THIS_REPR_NESTED(pi);
3807 va_start(ap, format);
3808 proto_tree_set_representation_value(pi, format, ap);
3815 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3816 gint start, gint length, const guint8 *start_ptr,
3817 const char *format, ...)
3822 if (start_ptr == NULL)
3823 start_ptr = tvb_get_ptr(tvb, start, length);
3825 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
3827 TRY_TO_FAKE_THIS_REPR_NESTED(pi);
3829 va_start(ap, format);
3830 proto_tree_set_representation(pi, format, ap);
3837 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
3841 DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
3843 bytes = g_byte_array_new();
3845 g_byte_array_append(bytes, start_ptr, length);
3847 fvalue_set_byte_array(&fi->value, bytes);
3852 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
3854 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
3858 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
3862 DISSECTOR_ASSERT(value != NULL);
3864 bytes = byte_array_dup(value);
3866 fvalue_set_byte_array(&fi->value, bytes);
3869 /* Add a FT_*TIME to a proto_tree */
3871 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3872 gint length, const nstime_t *value_ptr)
3875 header_field_info *hfinfo;
3877 CHECK_FOR_NULL_TREE(tree);
3879 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3881 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3883 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3884 proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
3890 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3891 gint start, gint length, nstime_t *value_ptr,
3892 const char *format, ...)
3897 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3899 va_start(ap, format);
3900 proto_tree_set_representation_value(pi, format, ap);
3908 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3909 gint start, gint length, nstime_t *value_ptr,
3910 const char *format, ...)
3915 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3917 TRY_TO_FAKE_THIS_REPR(pi);
3919 va_start(ap, format);
3920 proto_tree_set_representation(pi, format, ap);
3927 /* Set the FT_*TIME value */
3929 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
3931 DISSECTOR_ASSERT(value_ptr != NULL);
3933 fvalue_set_time(&fi->value, value_ptr);
3936 /* Add a FT_IPXNET to a proto_tree */
3938 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3939 gint length, guint32 value)
3942 header_field_info *hfinfo;
3944 CHECK_FOR_NULL_TREE(tree);
3946 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3948 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
3950 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3951 proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
3957 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3958 gint start, gint length, guint32 value,
3959 const char *format, ...)
3964 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3966 va_start(ap, format);
3967 proto_tree_set_representation_value(pi, format, ap);
3975 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3976 gint start, gint length, guint32 value,
3977 const char *format, ...)
3982 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3984 TRY_TO_FAKE_THIS_REPR(pi);
3986 va_start(ap, format);
3987 proto_tree_set_representation(pi, format, ap);
3994 /* Set the FT_IPXNET value */
3996 proto_tree_set_ipxnet(field_info *fi, guint32 value)
3998 fvalue_set_uinteger(&fi->value, value);
4001 /* Add a FT_IPv4 to a proto_tree */
4003 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4004 gint length, guint32 value)
4007 header_field_info *hfinfo;
4009 CHECK_FOR_NULL_TREE(tree);
4011 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4013 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
4015 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4016 proto_tree_set_ipv4(PNODE_FINFO(pi), value);
4022 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4023 gint start, gint length, guint32 value,
4024 const char *format, ...)
4029 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
4031 va_start(ap, format);
4032 proto_tree_set_representation_value(pi, format, ap);
4040 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4041 gint start, gint length, guint32 value,
4042 const char *format, ...)
4047 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
4049 TRY_TO_FAKE_THIS_REPR(pi);
4051 va_start(ap, format);
4052 proto_tree_set_representation(pi, format, ap);
4059 /* Set the FT_IPv4 value */
4061 proto_tree_set_ipv4(field_info *fi, guint32 value)
4063 fvalue_set_uinteger(&fi->value, value);
4066 /* Add a FT_IPv6 to a proto_tree */
4068 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4069 gint length, const ws_in6_addr *value_ptr)
4072 header_field_info *hfinfo;
4074 CHECK_FOR_NULL_TREE(tree);
4076 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4078 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
4080 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4081 proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
4087 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4088 gint start, gint length,
4089 const ws_in6_addr *value_ptr,
4090 const char *format, ...)
4095 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
4097 va_start(ap, format);
4098 proto_tree_set_representation_value(pi, format, ap);
4106 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4107 gint start, gint length,
4108 const ws_in6_addr *value_ptr,
4109 const char *format, ...)
4114 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
4116 TRY_TO_FAKE_THIS_REPR(pi);
4118 va_start(ap, format);
4119 proto_tree_set_representation(pi, format, ap);
4126 /* Set the FT_IPv6 value */
4128 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
4130 DISSECTOR_ASSERT(value_ptr != NULL);
4131 fvalue_set_bytes(&fi->value, value_ptr);
4135 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4137 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
4140 /* Set the FT_FCWWN value */
4142 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
4144 DISSECTOR_ASSERT(value_ptr != NULL);
4145 fvalue_set_bytes(&fi->value, value_ptr);
4149 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4151 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
4154 /* Add a FT_GUID to a proto_tree */
4156 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4157 gint length, const e_guid_t *value_ptr)
4160 header_field_info *hfinfo;
4162 CHECK_FOR_NULL_TREE(tree);
4164 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4166 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
4168 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4169 proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
4175 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4176 gint start, gint length,
4177 const e_guid_t *value_ptr,
4178 const char *format, ...)
4183 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4185 va_start(ap, format);
4186 proto_tree_set_representation_value(pi, format, ap);
4194 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4195 gint start, gint length, const e_guid_t *value_ptr,
4196 const char *format, ...)
4201 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4203 TRY_TO_FAKE_THIS_REPR(pi);
4205 va_start(ap, format);
4206 proto_tree_set_representation(pi, format, ap);
4213 /* Set the FT_GUID value */
4215 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
4217 DISSECTOR_ASSERT(value_ptr != NULL);
4218 fvalue_set_guid(&fi->value, value_ptr);
4222 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
4223 const guint encoding)
4227 tvb_get_guid(tvb, start, &guid, encoding);
4228 proto_tree_set_guid(fi, &guid);
4231 /* Add a FT_OID to a proto_tree */
4233 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4234 gint length, const guint8* value_ptr)
4237 header_field_info *hfinfo;
4239 CHECK_FOR_NULL_TREE(tree);
4241 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4243 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
4245 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4246 proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
4252 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4253 gint start, gint length,
4254 const guint8* value_ptr,
4255 const char *format, ...)
4260 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4262 va_start(ap, format);
4263 proto_tree_set_representation_value(pi, format, ap);
4271 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4272 gint start, gint length, const guint8* value_ptr,
4273 const char *format, ...)
4278 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4280 TRY_TO_FAKE_THIS_REPR(pi);
4282 va_start(ap, format);
4283 proto_tree_set_representation(pi, format, ap);
4290 /* Set the FT_OID value */
4292 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
4296 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4298 bytes = g_byte_array_new();
4300 g_byte_array_append(bytes, value_ptr, length);
4302 fvalue_set_byte_array(&fi->value, bytes);
4306 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4308 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
4311 /* Set the FT_SYSTEM_ID value */
4313 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
4317 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4319 bytes = g_byte_array_new();
4321 g_byte_array_append(bytes, value_ptr, length);
4323 fvalue_set_byte_array(&fi->value, bytes);
4327 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4329 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
4332 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
4333 * own copy of string, and frees it when the proto_tree is destroyed. */
4335 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4336 gint length, const char* value)
4339 header_field_info *hfinfo;
4342 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4343 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
4345 * Special case - if the length is 0, skip the test, so that
4346 * we can have an empty string right after the end of the
4347 * packet. (This handles URL-encoded forms where the last field
4348 * has no value so the form ends right after the =.)
4350 if (item_length != 0)
4351 test_length(hfinfo, tvb, start, item_length, ENC_NA);
4353 CHECK_FOR_NULL_TREE(tree);
4355 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4357 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
4359 if (hfinfo->display == STR_UNICODE) {
4360 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
4363 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4364 DISSECTOR_ASSERT(length >= 0);
4365 proto_tree_set_string(PNODE_FINFO(pi), value);
4371 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4372 gint start, gint length, const char* value,
4379 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4381 va_start(ap, format);
4382 proto_tree_set_representation_value(pi, format, ap);
4390 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4391 gint start, gint length, const char* value,
4392 const char *format, ...)
4397 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4399 TRY_TO_FAKE_THIS_REPR(pi);
4401 va_start(ap, format);
4402 proto_tree_set_representation(pi, format, ap);
4409 /* Set the FT_STRING value */
4411 proto_tree_set_string(field_info *fi, const char* value)
4414 fvalue_set_string(&fi->value, value);
4417 * XXX - why is a null value for a string field
4420 fvalue_set_string(&fi->value, "[ Null ]");
4424 /* Set the FT_AX25 value */
4426 proto_tree_set_ax25(field_info *fi, const guint8* value)
4428 fvalue_set_bytes(&fi->value, value);
4432 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
4434 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
4437 /* Set the FT_VINES value */
4439 proto_tree_set_vines(field_info *fi, const guint8* value)
4441 fvalue_set_bytes(&fi->value, value);
4445 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
4447 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
4450 /* Add a FT_ETHER to a proto_tree */
4452 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4453 gint length, const guint8* value)
4456 header_field_info *hfinfo;
4458 CHECK_FOR_NULL_TREE(tree);
4460 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4462 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
4464 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4465 proto_tree_set_ether(PNODE_FINFO(pi), value);
4471 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4472 gint start, gint length, const guint8* value,
4473 const char *format, ...)
4478 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
4480 va_start(ap, format);
4481 proto_tree_set_representation_value(pi, format, ap);
4489 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4490 gint start, gint length, const guint8* value,
4491 const char *format, ...)
4496 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
4498 TRY_TO_FAKE_THIS_REPR(pi);
4500 va_start(ap, format);
4501 proto_tree_set_representation(pi, format, ap);
4508 /* Set the FT_ETHER value */
4510 proto_tree_set_ether(field_info *fi, const guint8* value)
4512 fvalue_set_bytes(&fi->value, value);
4516 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
4518 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
4521 /* Add a FT_BOOLEAN to a proto_tree */
4523 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4524 gint length, guint32 value)
4527 header_field_info *hfinfo;
4529 CHECK_FOR_NULL_TREE(tree);
4531 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4533 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
4535 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4536 proto_tree_set_boolean(PNODE_FINFO(pi), value);
4542 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
4543 tvbuff_t *tvb, gint start, gint length,
4544 guint32 value, const char *format, ...)
4549 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
4551 va_start(ap, format);
4552 proto_tree_set_representation_value(pi, format, ap);
4560 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4561 gint start, gint length, guint32 value,
4562 const char *format, ...)
4567 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
4569 TRY_TO_FAKE_THIS_REPR(pi);
4571 va_start(ap, format);
4572 proto_tree_set_representation(pi, format, ap);
4580 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4581 gint length, guint64 value)
4584 header_field_info *hfinfo;
4586 CHECK_FOR_NULL_TREE(tree);
4588 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4590 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
4592 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4593 proto_tree_set_boolean(PNODE_FINFO(pi), value);
4598 /* Set the FT_BOOLEAN value */
4600 proto_tree_set_boolean(field_info *fi, guint64 value)
4602 proto_tree_set_uint64(fi, value);
4605 /* Generate, into "buf", a string showing the bits of a bitfield.
4606 Return a pointer to the character after that string. */
4607 /*XXX this needs a buf_len check */
4609 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
4617 bit = G_GUINT64_CONSTANT(1) << (width - 1);
4620 /* This bit is part of the field. Show its value. */
4626 /* This bit is not part of the field. */
4641 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
4645 p = other_decode_bitfield_value(buf, val, mask, width);
4646 p = g_stpcpy(p, " = ");
4652 other_decode_bitfield_varint_value(char *buf, guint64 val, guint64 mask, const int width)
4659 bit = G_GUINT64_CONSTANT(1) << (width - 1);
4661 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
4663 /* This bit is part of the field. Show its value. */
4669 /* This bit is not part of the field. */
4685 decode_bitfield_varint_value(char *buf, const guint64 val, const guint64 mask, const int width)
4689 p = other_decode_bitfield_varint_value(buf, val, mask, width);
4690 p = g_stpcpy(p, " = ");
4695 /* Add a FT_FLOAT to a proto_tree */
4697 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4698 gint length, float value)
4701 header_field_info *hfinfo;
4703 CHECK_FOR_NULL_TREE(tree);
4705 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4707 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
4709 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4710 proto_tree_set_float(PNODE_FINFO(pi), value);
4716 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4717 gint start, gint length, float value,
4718 const char *format, ...)
4723 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
4725 va_start(ap, format);
4726 proto_tree_set_representation_value(pi, format, ap);
4734 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4735 gint start, gint length, float value,
4736 const char *format, ...)
4741 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
4743 TRY_TO_FAKE_THIS_REPR(pi);
4745 va_start(ap, format);
4746 proto_tree_set_representation(pi, format, ap);
4753 /* Set the FT_FLOAT value */
4755 proto_tree_set_float(field_info *fi, float value)
4757 fvalue_set_floating(&fi->value, value);
4760 /* Add a FT_DOUBLE to a proto_tree */
4762 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4763 gint length, double value)
4766 header_field_info *hfinfo;
4768 CHECK_FOR_NULL_TREE(tree);
4770 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4772 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
4774 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4775 proto_tree_set_double(PNODE_FINFO(pi), value);
4781 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4782 gint start, gint length, double value,
4783 const char *format, ...)
4788 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
4790 va_start(ap, format);
4791 proto_tree_set_representation_value(pi, format, ap);
4799 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4800 gint start, gint length, double value,
4801 const char *format, ...)
4806 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
4808 TRY_TO_FAKE_THIS_REPR(pi);
4810 va_start(ap, format);
4811 proto_tree_set_representation(pi, format, ap);
4818 /* Set the FT_DOUBLE value */
4820 proto_tree_set_double(field_info *fi, double value)
4822 fvalue_set_floating(&fi->value, value);
4825 /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
4827 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4828 gint length, guint32 value)
4830 proto_item *pi = NULL;
4831 header_field_info *hfinfo;
4833 CHECK_FOR_NULL_TREE(tree);
4835 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4837 switch (hfinfo->type) {
4844 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4845 proto_tree_set_uint(PNODE_FINFO(pi), value);
4849 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",
4857 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4858 gint start, gint length, guint32 value,
4859 const char *format, ...)
4864 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
4866 va_start(ap, format);
4867 proto_tree_set_representation_value(pi, format, ap);
4875 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4876 gint start, gint length, guint32 value,
4877 const char *format, ...)
4882 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
4884 TRY_TO_FAKE_THIS_REPR(pi);
4886 va_start(ap, format);
4887 proto_tree_set_representation(pi, format, ap);
4894 /* Set the FT_UINT{8,16,24,32} value */
4896 proto_tree_set_uint(field_info *fi, guint32 value)
4898 header_field_info *hfinfo;
4901 hfinfo = fi->hfinfo;
4904 if (hfinfo->bitmask) {
4905 /* Mask out irrelevant portions */
4906 integer &= (guint32)(hfinfo->bitmask);
4909 integer >>= hfinfo_bitshift(hfinfo);
4912 fvalue_set_uinteger(&fi->value, integer);
4915 /* Add FT_UINT{40,48,56,64} to a proto_tree */
4917 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4918 gint length, guint64 value)
4920 proto_item *pi = NULL;
4921 header_field_info *hfinfo;
4923 CHECK_FOR_NULL_TREE(tree);
4925 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4927 switch (hfinfo->type) {
4933 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4934 proto_tree_set_uint64(PNODE_FINFO(pi), value);
4938 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",
4946 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4947 gint start, gint length, guint64 value,
4948 const char *format, ...)
4953 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4955 va_start(ap, format);
4956 proto_tree_set_representation_value(pi, format, ap);
4964 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4965 gint start, gint length, guint64 value,
4966 const char *format, ...)
4971 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4973 TRY_TO_FAKE_THIS_REPR(pi);
4975 va_start(ap, format);
4976 proto_tree_set_representation(pi, format, ap);
4983 /* Set the FT_UINT{40,48,56,64} value */
4985 proto_tree_set_uint64(field_info *fi, guint64 value)
4987 header_field_info *hfinfo;
4990 hfinfo = fi->hfinfo;
4993 if (hfinfo->bitmask) {
4994 /* Mask out irrelevant portions */
4995 integer &= hfinfo->bitmask;
4998 integer >>= hfinfo_bitshift(hfinfo);
5001 fvalue_set_uinteger64(&fi->value, integer);
5004 /* Add FT_INT{8,16,24,32} to a proto_tree */
5006 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5007 gint length, gint32 value)
5009 proto_item *pi = NULL;
5010 header_field_info *hfinfo;
5012 CHECK_FOR_NULL_TREE(tree);
5014 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5016 switch (hfinfo->type) {
5021 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5022 proto_tree_set_int(PNODE_FINFO(pi), value);
5026 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
5034 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5035 gint start, gint length, gint32 value,
5036 const char *format, ...)
5041 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
5043 va_start(ap, format);
5044 proto_tree_set_representation_value(pi, format, ap);
5052 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5053 gint start, gint length, gint32 value,
5054 const char *format, ...)
5059 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
5061 TRY_TO_FAKE_THIS_REPR(pi);
5063 va_start(ap, format);
5064 proto_tree_set_representation(pi, format, ap);
5071 /* Set the FT_INT{8,16,24,32} value */
5073 proto_tree_set_int(field_info *fi, gint32 value)
5075 header_field_info *hfinfo;
5079 hfinfo = fi->hfinfo;
5080 integer = (guint32) value;
5082 if (hfinfo->bitmask) {
5083 /* Mask out irrelevant portions */
5084 integer &= (guint32)(hfinfo->bitmask);
5087 integer >>= hfinfo_bitshift(hfinfo);
5089 no_of_bits = ws_count_ones(hfinfo->bitmask);
5090 integer = ws_sign_ext32(integer, no_of_bits);
5093 fvalue_set_sinteger(&fi->value, integer);
5096 /* Add FT_INT{40,48,56,64} to a proto_tree */
5098 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5099 gint length, gint64 value)
5101 proto_item *pi = NULL;
5102 header_field_info *hfinfo;
5104 CHECK_FOR_NULL_TREE(tree);
5106 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5108 switch (hfinfo->type) {
5113 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5114 proto_tree_set_int64(PNODE_FINFO(pi), value);
5118 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
5126 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5127 gint start, gint length, gint64 value,
5128 const char *format, ...)
5133 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
5135 va_start(ap, format);
5136 proto_tree_set_representation_value(pi, format, ap);
5143 /* Set the FT_INT{40,48,56,64} value */
5145 proto_tree_set_int64(field_info *fi, gint64 value)
5147 header_field_info *hfinfo;
5151 hfinfo = fi->hfinfo;
5154 if (hfinfo->bitmask) {
5155 /* Mask out irrelevant portions */
5156 integer &= hfinfo->bitmask;
5159 integer >>= hfinfo_bitshift(hfinfo);
5161 no_of_bits = ws_count_ones(hfinfo->bitmask);
5162 integer = ws_sign_ext64(integer, no_of_bits);
5165 fvalue_set_sinteger64(&fi->value, integer);
5169 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5170 gint start, gint length, gint64 value,
5171 const char *format, ...)
5176 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
5178 TRY_TO_FAKE_THIS_REPR(pi);
5180 va_start(ap, format);
5181 proto_tree_set_representation(pi, format, ap);
5188 /* Add a FT_EUI64 to a proto_tree */
5190 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5191 gint length, const guint64 value)
5194 header_field_info *hfinfo;
5196 CHECK_FOR_NULL_TREE(tree);
5198 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5200 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
5202 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5203 proto_tree_set_eui64(PNODE_FINFO(pi), value);
5209 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5210 gint start, gint length, const guint64 value,
5211 const char *format, ...)
5216 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5218 va_start(ap, format);
5219 proto_tree_set_representation_value(pi, format, ap);
5227 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5228 gint start, gint length, const guint64 value,
5229 const char *format, ...)
5234 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5236 TRY_TO_FAKE_THIS_REPR(pi);
5238 va_start(ap, format);
5239 proto_tree_set_representation(pi, format, ap);
5246 /* Set the FT_EUI64 value */
5248 proto_tree_set_eui64(field_info *fi, const guint64 value)
5250 fvalue_set_uinteger64(&fi->value, value);
5253 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
5257 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
5259 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
5263 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
5265 proto_tree_add_node(proto_tree *tree, field_info *fi)
5267 proto_node *pnode, *tnode, *sibling;
5272 * Restrict our depth. proto_tree_traverse_pre_order and
5273 * proto_tree_traverse_post_order (and possibly others) are recursive
5274 * so we need to be mindful of our stack size.
5276 if (tree->first_child == NULL) {
5277 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
5279 if (G_UNLIKELY(depth > MAX_TREE_LEVELS)) {
5280 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
5281 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u)",
5283 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
5289 * Make sure "tree" is ready to have subtrees under it, by
5290 * checking whether it's been given an ett_ value.
5292 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
5293 * node of the protocol tree. That node is not displayed,
5294 * so it doesn't need an ett_ value to remember whether it
5298 tfi = PNODE_FINFO(tnode);
5299 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
5300 REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
5301 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__);
5302 /* XXX - is it safe to continue here? */
5305 pnode = wmem_new(PNODE_POOL(tree), proto_node);
5306 PROTO_NODE_INIT(pnode);
5307 pnode->parent = tnode;
5308 PNODE_FINFO(pnode) = fi;
5309 pnode->tree_data = PTREE_DATA(tree);
5311 if (tnode->last_child != NULL) {
5312 sibling = tnode->last_child;
5313 DISSECTOR_ASSERT(sibling->next == NULL);
5314 sibling->next = pnode;
5316 tnode->first_child = pnode;
5317 tnode->last_child = pnode;
5319 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
5321 return (proto_item *)pnode;
5325 /* Generic way to allocate field_info and add to proto_tree.
5326 * Sets *pfi to address of newly-allocated field_info struct */
5328 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
5335 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA);
5336 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
5337 pi = proto_tree_add_node(tree, fi);
5344 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
5345 gint *item_length, const guint encoding)
5347 gint length_remaining;
5350 * We only allow a null tvbuff if the item has a zero length,
5351 * i.e. if there's no data backing it.
5353 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
5356 * XXX - in some protocols, there are 32-bit unsigned length
5357 * fields, so lengths in protocol tree and tvbuff routines
5358 * should really be unsigned. We should have, for those
5359 * field types for which "to the end of the tvbuff" makes sense,
5360 * additional routines that take no length argument and
5361 * add fields that run to the end of the tvbuff.
5363 if (*length == -1) {
5365 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
5366 * FT_STRINGZPAD fields, a length of -1 means "set the
5367 * length to what remains in the tvbuff".
5369 * The assumption is either that
5371 * 1) the length of the item can only be determined
5372 * by dissection (typically true of items with
5373 * subitems, which are probably FT_NONE or
5378 * 2) if the tvbuff is "short" (either due to a short
5379 * snapshot length or due to lack of reassembly of
5380 * fragments/segments/whatever), we want to display
5381 * what's available in the field (probably FT_BYTES
5382 * or FT_STRING) and then throw an exception later
5386 * 3) the field is defined to be "what's left in the
5389 * so we set the length to what remains in the tvbuff so
5390 * that, if we throw an exception while dissecting, it
5391 * has what is probably the right value.
5393 * For FT_STRINGZ, it means "the string is null-terminated,
5394 * not null-padded; set the length to the actual length
5395 * of the string", and if the tvbuff if short, we just
5396 * throw an exception.
5398 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC, it means "find the end of the string",
5399 * and if the tvbuff if short, we just throw an exception.
5401 * It's not valid for any other type of field. For those
5402 * fields, we treat -1 the same way we treat other
5403 * negative values - we assume the length is a Really
5404 * Big Positive Number, and throw a ReportedBoundsError
5405 * exception, under the assumption that the Really Big
5406 * Length would run past the end of the packet.
5408 if ((IS_FT_INT(hfinfo->type)) || (IS_FT_UINT(hfinfo->type))) {
5409 if (encoding & ENC_VARINT_PROTOBUF) {
5411 * Leave the length as -1, so our caller knows
5414 *item_length = *length;
5416 } else if (encoding & ENC_VARINT_QUIC) {
5417 switch (tvb_get_guint8(tvb, start) >> 6)
5419 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
5422 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
5425 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
5428 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
5435 switch (hfinfo->type) {
5443 * We allow FT_PROTOCOLs to be zero-length -
5444 * for example, an ONC RPC NULL procedure has
5445 * neither arguments nor reply, so the
5446 * payload for that protocol is empty.
5448 * We also allow the others to be zero-length -
5449 * because that's the way the code has been for a
5452 * However, we want to ensure that the start
5453 * offset is not *past* the byte past the end
5454 * of the tvbuff: we throw an exception in that
5457 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
5458 DISSECTOR_ASSERT(*length >= 0);
5463 * Leave the length as -1, so our caller knows
5469 THROW(ReportedBoundsError);
5470 DISSECTOR_ASSERT_NOT_REACHED();
5472 *item_length = *length;
5474 *item_length = *length;
5475 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
5477 * These types are for interior nodes of the
5478 * tree, and don't have data associated with
5479 * them; if the length is negative (XXX - see
5480 * above) or goes past the end of the tvbuff,
5481 * cut it short at the end of the tvbuff.
5482 * That way, if this field is selected in
5483 * Wireshark, we don't highlight stuff past
5484 * the end of the data.
5486 /* XXX - what to do, if we don't have a tvb? */
5488 length_remaining = tvb_captured_length_remaining(tvb, start);
5489 if (*item_length < 0 ||
5490 (*item_length > 0 &&
5491 (length_remaining < *item_length)))
5492 *item_length = length_remaining;
5495 if (*item_length < 0) {
5496 THROW(ReportedBoundsError);
5502 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
5503 gint length, guint item_length, const gint encoding)
5508 * We need to get the correct item length here.
5509 * That's normally done by proto_tree_new_item(),
5510 * but we won't be calling it.
5512 switch (hfinfo->type) {
5518 * The length is the specified length.
5523 n = get_uint_value(NULL, tvb, start, length, encoding);
5527 /* XXX - make these just FT_UINT? */
5536 /* XXX - make these just FT_INT? */
5545 if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC)) {
5547 report_type_length_mismatch(NULL, "a FT_[U]INT", length, TRUE);
5551 /* This can throw an exception */
5552 /* XXX - do this without fetching the varint? */
5553 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN, &dummy, encoding);
5555 THROW(ReportedBoundsError);
5558 item_length = length;
5563 * The length is the specified length.
5585 * The length is the specified length.
5591 report_type_length_mismatch(NULL, "a string", length, TRUE);
5594 /* This can throw an exception */
5595 /* XXX - do this without fetching the string? */
5596 tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
5598 item_length = length;
5601 case FT_UINT_STRING:
5602 if (encoding & ENC_ZIGBEE) {
5603 n = get_uint_value(NULL, tvb, start, length, encoding);
5605 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
5611 case FT_ABSOLUTE_TIME:
5612 case FT_RELATIVE_TIME:
5613 case FT_IEEE_11073_SFLOAT:
5614 case FT_IEEE_11073_FLOAT:
5616 * The length is the specified length.
5621 g_error("hfinfo->type %d (%s) not handled\n",
5623 ftype_name(hfinfo->type));
5624 DISSECTOR_ASSERT_NOT_REACHED();
5631 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
5632 const gint start, const gint item_length)
5636 FIELD_INFO_NEW(PNODE_POOL(tree), fi);
5638 fi->hfinfo = hfinfo;
5640 fi->start += (tvb)?tvb_raw_offset(tvb):0;
5641 fi->length = item_length;
5644 if (!PTREE_DATA(tree)->visible)
5645 FI_SET_FLAG(fi, FI_HIDDEN);
5646 fvalue_init(&fi->value, fi->hfinfo->type);
5649 /* add the data source tvbuff */
5650 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
5652 fi->appendix_start = 0;
5653 fi->appendix_length = 0;
5658 /* If the protocol tree is to be visible, set the representation of a
5659 proto_tree entry with the name of the field for the item and with
5660 the value formatted with the supplied printf-style format and
5663 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
5667 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
5668 * items string representation */
5669 if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
5671 field_info *fi = PITEM_FINFO(pi);
5672 header_field_info *hf;
5674 DISSECTOR_ASSERT(fi);
5678 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5679 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
5683 if (IS_FT_UINT32(hf->type))
5684 val = fvalue_get_uinteger(&fi->value);
5686 val = fvalue_get_uinteger64(&fi->value);
5688 val <<= hfinfo_bitshift(hf);
5690 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
5691 ret = (int) (p - fi->rep->representation);
5694 /* put in the hf name */
5695 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
5697 /* If possible, Put in the value of the string */
5698 if (ret < ITEM_LABEL_LENGTH) {
5699 ret += g_vsnprintf(fi->rep->representation + ret,
5700 ITEM_LABEL_LENGTH - ret, format, ap);
5702 if (ret >= ITEM_LABEL_LENGTH) {
5703 /* Uh oh, we don't have enough room. Tell the user
5704 * that the field is truncated.
5706 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
5711 /* If the protocol tree is to be visible, set the representation of a
5712 proto_tree entry with the representation formatted with the supplied
5713 printf-style format and argument list. */
5715 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
5717 int ret; /*tmp return value */
5718 field_info *fi = PITEM_FINFO(pi);
5720 DISSECTOR_ASSERT(fi);
5722 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5723 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5724 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
5726 if (ret >= ITEM_LABEL_LENGTH) {
5727 /* Uh oh, we don't have enough room. Tell the user
5728 * that the field is truncated.
5730 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
5736 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
5738 switch (hfinfo->display) {
5740 return format_text(NULL, string, strlen(string));
5743 return format_text_wsp(string, strlen(string));
5746 /* XXX, format_unicode_text() */
5747 return wmem_strdup(NULL, string);
5750 return format_text(NULL, string, strlen(string));
5754 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
5756 gsize res = g_strlcpy(dest, src, dest_size);
5758 if (res > dest_size)
5763 static header_field_info *
5764 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
5766 header_field_info *dup_hfinfo;
5768 if (hfinfo->same_name_prev_id == -1)
5770 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
5775 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
5777 g_free(last_field_name);
5778 last_field_name = NULL;
5780 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
5781 /* No hfinfo with the same name */
5782 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
5786 if (hfinfo->same_name_next) {
5787 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
5790 if (hfinfo->same_name_prev_id != -1) {
5791 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
5792 same_name_prev->same_name_next = hfinfo->same_name_next;
5793 if (!hfinfo->same_name_next) {
5794 /* It's always the latest added hfinfo which is stored in gpa_name_map */
5795 g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
5800 /* -------------------------- */
5802 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
5803 gchar *result, gchar *expr, const int size)
5812 const true_false_string *tfstring;
5814 int len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
5816 field_info *finfo = NULL;
5817 header_field_info* hfinfo;
5818 const gchar *abbrev = NULL;
5820 const char *hf_str_val;
5821 char number_buf[48];
5822 const char *number_out;
5828 g_assert(field_ids != NULL);
5829 while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
5830 field_id = *field_idx;
5831 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
5833 /* do we need to rewind ? */
5837 if (occurrence < 0) {
5838 /* Search other direction */
5839 while (hfinfo->same_name_prev_id != -1) {
5840 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
5845 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
5847 if (!finfos || !(len = g_ptr_array_len(finfos))) {
5848 if (occurrence < 0) {
5849 hfinfo = hfinfo->same_name_next;
5851 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5856 /* Are there enough occurrences of the field? */
5857 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
5858 if (occurrence < 0) {
5859 hfinfo = hfinfo->same_name_next;
5861 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5867 /* Calculate single index or set outer bounderies */
5868 if (occurrence < 0) {
5869 i = occurrence + len + prev_len;
5871 } else if (occurrence > 0) {
5872 i = occurrence - 1 - prev_len;
5879 prev_len += len; /* Count handled occurrences */
5882 finfo = (field_info *)g_ptr_array_index(finfos, i);
5884 if (offset_r && (offset_r < (size - 2)))
5885 result[offset_r++] = ',';
5887 if (offset_e && (offset_e < (size - 2)))
5888 expr[offset_e++] = ',';
5890 switch (hfinfo->type) {
5894 /* prevent multiple check marks by setting result directly */
5895 g_strlcpy(result, UTF8_CHECK_MARK, size);
5900 bytes = (guint8 *)fvalue_get(&finfo->value);
5902 switch (hfinfo->display) {
5904 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
5907 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
5910 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
5913 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5917 if (prefs.display_byte_fields_with_spaces) {
5918 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5920 str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
5924 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5925 wmem_free(NULL, str);
5928 if (hfinfo->display & BASE_ALLOW_ZERO) {
5929 offset_r += protoo_strlcpy(result+offset_r, "<none>", size-offset_r);
5931 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
5936 case FT_ABSOLUTE_TIME:
5937 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
5938 offset_r += protoo_strlcpy(result+offset_r,
5941 wmem_free(NULL, tmpbuf);
5944 case FT_RELATIVE_TIME:
5945 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
5946 offset_r += protoo_strlcpy(result+offset_r,
5949 wmem_free(NULL, tmpbuf);
5953 number64 = fvalue_get_uinteger64(&finfo->value);
5954 tfstring = (const true_false_string *)&tfs_true_false;
5955 if (hfinfo->strings) {
5956 tfstring = (const struct true_false_string*) hfinfo->strings;
5958 offset_r += protoo_strlcpy(result+offset_r,
5960 tfstring->true_string :
5961 tfstring->false_string, size-offset_r);
5963 offset_e += protoo_strlcpy(expr+offset_e,
5964 number64 ? "1" : "0", size-offset_e);
5969 number = fvalue_get_uinteger(&finfo->value);
5971 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
5972 gchar tmp[ITEM_LABEL_LENGTH];
5973 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5975 DISSECTOR_ASSERT(fmtfunc);
5976 fmtfunc(tmp, number);
5978 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5980 } else if (hfinfo->strings) {
5981 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5984 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
5986 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5989 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5991 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5994 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
5995 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5997 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5999 g_strlcpy(expr+offset_e, number_out, size-offset_e);
6002 offset_e = (int)strlen(expr);
6005 /* XXX - make these just FT_NUMBER? */
6016 number = IS_FT_INT(hfinfo->type) ?
6017 (guint32) fvalue_get_sinteger(&finfo->value) :
6018 fvalue_get_uinteger(&finfo->value);
6020 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6021 gchar tmp[ITEM_LABEL_LENGTH];
6022 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
6024 DISSECTOR_ASSERT(fmtfunc);
6025 fmtfunc(tmp, number);
6027 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
6029 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
6030 if (hfinfo->display & BASE_UNIT_STRING) {
6031 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
6032 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6033 hf_str_val = hf_try_val_to_str(number, hfinfo);
6034 offset_r += protoo_strlcpy(result+offset_r, hf_str_val, size-offset_r);
6036 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
6039 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
6041 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6044 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
6046 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6049 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6050 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6052 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
6054 g_strlcpy(expr+offset_e, number_out, size-offset_e);
6057 offset_e = (int)strlen(expr);
6069 number64 = IS_FT_INT(hfinfo->type) ?
6070 (guint64) fvalue_get_sinteger64(&finfo->value) :
6071 fvalue_get_uinteger64(&finfo->value);
6073 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6074 gchar tmp[ITEM_LABEL_LENGTH];
6075 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
6077 DISSECTOR_ASSERT(fmtfunc64);
6078 fmtfunc64(tmp, number64);
6079 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
6080 } else if (hfinfo->strings) {
6081 if (hfinfo->display & BASE_UNIT_STRING) {
6082 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
6083 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6084 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6085 offset_r += protoo_strlcpy(result+offset_r, hf_str_val, size-offset_r);
6087 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6090 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
6092 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6095 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
6097 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6100 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6101 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6103 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
6105 g_strlcpy(expr+offset_e, number_out, size-offset_e);
6108 offset_e = (int)strlen(expr);
6112 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
6113 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6114 wmem_free(NULL, str);
6118 ipv4 = fvalue_get_uinteger(&finfo->value);
6119 set_address (&addr, AT_IPv4, 4, &ipv4);
6120 address_to_str_buf(&addr, result+offset_r, size-offset_r);
6121 offset_r = (int)strlen(result);
6125 ipv6 = (ws_in6_addr *)fvalue_get(&finfo->value);
6126 set_address (&addr, AT_IPv6, sizeof(ws_in6_addr), ipv6);
6127 address_to_str_buf(&addr, result+offset_r, size-offset_r);
6128 offset_r = (int)strlen(result);
6132 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
6133 address_to_str_buf(&addr, result+offset_r, size-offset_r);
6134 offset_r = (int)strlen(result);
6138 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
6139 address_to_str_buf(&addr, result+offset_r, size-offset_r);
6140 offset_r = (int)strlen(result);
6144 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
6145 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6146 wmem_free(NULL, str);
6150 bytes = (guint8 *)fvalue_get(&finfo->value);
6151 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
6152 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6153 wmem_free(NULL, str);
6155 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
6156 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6157 wmem_free(NULL, str);
6161 bytes = (guint8 *)fvalue_get(&finfo->value);
6162 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
6163 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6164 wmem_free(NULL, str);
6166 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
6167 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6168 wmem_free(NULL, str);
6172 bytes = (guint8 *)fvalue_get(&finfo->value);
6173 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
6174 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6175 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6176 wmem_free(NULL, str);
6180 if (hfinfo->display & BASE_UNIT_STRING) {
6181 double d_value = fvalue_get_floating(&finfo->value);
6182 g_snprintf(result+offset_r, size-offset_r,
6183 "%." G_STRINGIFY(FLT_DIG) "g%s", d_value,
6184 unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
6186 g_snprintf(result+offset_r, size-offset_r,
6187 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
6189 offset_r = (int)strlen(result);
6193 if (hfinfo->display & BASE_UNIT_STRING) {
6194 double d_value = fvalue_get_floating(&finfo->value);
6195 g_snprintf(result+offset_r, size-offset_r,
6196 "%." G_STRINGIFY(DBL_DIG) "g%s", d_value,
6197 unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
6199 g_snprintf(result+offset_r, size-offset_r,
6200 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
6202 offset_r = (int)strlen(result);
6207 case FT_UINT_STRING:
6209 bytes = (guint8 *)fvalue_get(&finfo->value);
6210 str = hfinfo_format_text(hfinfo, bytes);
6211 offset_r += protoo_strlcpy(result+offset_r,
6212 str, size-offset_r);
6213 wmem_free(NULL, str);
6217 /* First try ftype string representation */
6218 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
6220 /* Default to show as bytes */
6221 bytes = (guint8 *)fvalue_get(&finfo->value);
6222 str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
6224 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6225 wmem_free(NULL, str);
6231 switch (hfinfo->type) {
6255 /* for these types, "expr" is filled in the loop above */
6259 /* for all others, just copy "result" to "expr" */
6260 g_strlcpy(expr, result, size);
6265 /* Store abbrev for return value */
6266 abbrev = hfinfo->abbrev;
6269 if (occurrence == 0) {
6270 /* Fetch next hfinfo with same name (abbrev) */
6271 hfinfo = hfinfo_same_name_get_prev(hfinfo);
6278 return abbrev ? abbrev : "";
6282 /* Set text of proto_item after having already been created. */
6284 proto_item_set_text(proto_item *pi, const char *format, ...)
6286 field_info *fi = NULL;
6289 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6291 fi = PITEM_FINFO(pi);
6296 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
6300 va_start(ap, format);
6301 proto_tree_set_representation(pi, format, ap);
6305 /* Append to text of proto_item after having already been created. */
6307 proto_item_append_text(proto_item *pi, const char *format, ...)
6309 field_info *fi = NULL;
6313 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6315 fi = PITEM_FINFO(pi);
6320 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
6322 * If we don't already have a representation,
6323 * generate the default representation.
6325 if (fi->rep == NULL) {
6326 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6327 proto_item_fill_label(fi, fi->rep->representation);
6330 curlen = strlen(fi->rep->representation);
6331 if (ITEM_LABEL_LENGTH > curlen) {
6332 va_start(ap, format);
6333 g_vsnprintf(fi->rep->representation + curlen,
6334 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
6340 /* Prepend to text of proto_item after having already been created. */
6342 proto_item_prepend_text(proto_item *pi, const char *format, ...)
6344 field_info *fi = NULL;
6345 char representation[ITEM_LABEL_LENGTH];
6348 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6350 fi = PITEM_FINFO(pi);
6355 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
6357 * If we don't already have a representation,
6358 * generate the default representation.
6360 if (fi->rep == NULL) {
6361 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6362 proto_item_fill_label(fi, representation);
6364 g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
6366 va_start(ap, format);
6367 g_vsnprintf(fi->rep->representation,
6368 ITEM_LABEL_LENGTH, format, ap);
6370 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
6375 finfo_set_len(field_info *fi, const gint length)
6377 gint length_remaining;
6379 DISSECTOR_ASSERT(length >= 0);
6380 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
6381 if (length > length_remaining)
6382 fi->length = length_remaining;
6384 fi->length = length;
6387 * You cannot just make the "len" field of a GByteArray
6388 * larger, if there's no data to back that length;
6389 * you can only make it smaller.
6391 if (fi->value.ftype->ftype == FT_BYTES && fi->length <= (gint)fi->value.value.bytes->len)
6392 fi->value.value.bytes->len = fi->length;
6396 proto_item_set_len(proto_item *pi, const gint length)
6400 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6402 fi = PITEM_FINFO(pi);
6406 finfo_set_len(fi, length);
6410 * Sets the length of the item based on its start and on the specified
6411 * offset, which is the offset past the end of the item; as the start
6412 * in the item is relative to the beginning of the data source tvbuff,
6413 * we need to pass in a tvbuff - the end offset is relative to the beginning
6417 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
6422 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6424 fi = PITEM_FINFO(pi);
6428 end += tvb_raw_offset(tvb);
6429 DISSECTOR_ASSERT(end >= fi->start);
6430 length = end - fi->start;
6432 finfo_set_len(fi, length);
6436 proto_item_get_len(const proto_item *pi)
6442 fi = PITEM_FINFO(pi);
6443 return fi ? fi->length : -1;
6447 proto_tree_create_root(packet_info *pinfo)
6451 /* Initialize the proto_node */
6452 pnode = g_slice_new(proto_tree);
6453 PROTO_NODE_INIT(pnode);
6454 pnode->parent = NULL;
6455 PNODE_FINFO(pnode) = NULL;
6456 pnode->tree_data = g_slice_new(tree_data_t);
6458 /* Make sure we can access pinfo everywhere */
6459 pnode->tree_data->pinfo = pinfo;
6461 /* Don't initialize the tree_data_t. Wait until we know we need it */
6462 pnode->tree_data->interesting_hfids = NULL;
6464 /* Set the default to FALSE so it's easier to
6465 * find errors; if we expect to see the protocol tree
6466 * but for some reason the default 'visible' is not
6467 * changed, then we'll find out very quickly. */
6468 pnode->tree_data->visible = FALSE;
6470 /* Make sure that we fake protocols (if possible) */
6471 pnode->tree_data->fake_protocols = TRUE;
6473 /* Keep track of the number of children */
6474 pnode->tree_data->count = 0;
6476 return (proto_tree *)pnode;
6480 /* "prime" a proto_tree with a single hfid that a dfilter
6481 * is interested in. */
6483 proto_tree_prime_with_hfid(proto_tree *tree _U_, const gint hfid)
6485 header_field_info *hfinfo;
6487 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
6488 /* this field is referenced by a filter so increase the refcount.
6489 also increase the refcount for the parent, i.e the protocol.
6491 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
6492 /* only increase the refcount if there is a parent.
6493 if this is a protocol and not a field then parent will be -1
6494 and there is no parent to add any refcounting for.
6496 if (hfinfo->parent != -1) {
6497 header_field_info *parent_hfinfo;
6498 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
6500 /* Mark parent as indirectly referenced unless it is already directly
6501 * referenced, i.e. the user has specified the parent in a filter.
6503 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
6504 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
6509 proto_item_add_subtree(proto_item *pi, const gint idx) {
6515 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
6517 fi = PITEM_FINFO(pi);
6519 return (proto_tree *)pi;
6521 fi->tree_type = idx;
6523 return (proto_tree *)pi;
6527 proto_item_get_subtree(proto_item *pi) {
6532 fi = PITEM_FINFO(pi);
6533 if ( (!fi) || (fi->tree_type == -1) )
6535 return (proto_tree *)pi;
6539 proto_item_get_parent(const proto_item *ti) {
6546 proto_item_get_parent_nth(proto_item *ti, int gen) {
6559 proto_tree_get_parent(proto_tree *tree) {
6562 return (proto_item *)tree;
6566 proto_tree_get_parent_tree(proto_tree *tree) {
6570 /* we're the root tree, there's no parent
6571 return ourselves so the caller has at least a tree to attach to */
6575 return (proto_tree *)tree->parent;
6579 proto_tree_get_root(proto_tree *tree) {
6582 while (tree->parent) {
6583 tree = tree->parent;
6589 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
6590 proto_item *item_to_move)
6593 /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
6594 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
6596 /* This function doesn't generate any values. It only reorganizes the prococol tree
6597 * so we can bail out immediately if it isn't visible. */
6598 if (!tree || !PTREE_DATA(tree)->visible)
6601 DISSECTOR_ASSERT(item_to_move->parent == tree);
6602 DISSECTOR_ASSERT(fixed_item->parent == tree);
6604 /*** cut item_to_move out ***/
6606 /* is item_to_move the first? */
6607 if (tree->first_child == item_to_move) {
6608 /* simply change first child to next */
6609 tree->first_child = item_to_move->next;
6611 DISSECTOR_ASSERT(tree->last_child != item_to_move);
6613 proto_item *curr_item;
6614 /* find previous and change it's next */
6615 for (curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
6616 if (curr_item->next == item_to_move) {
6621 DISSECTOR_ASSERT(curr_item);
6623 curr_item->next = item_to_move->next;
6625 /* fix last_child if required */
6626 if (tree->last_child == item_to_move) {
6627 tree->last_child = curr_item;
6631 /*** insert to_move after fixed ***/
6632 item_to_move->next = fixed_item->next;
6633 fixed_item->next = item_to_move;
6634 if (tree->last_child == fixed_item) {
6635 tree->last_child = item_to_move;
6640 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
6648 fi = PTREE_FINFO(tree);
6652 start += tvb_raw_offset(tvb);
6653 DISSECTOR_ASSERT(start >= 0);
6654 DISSECTOR_ASSERT(length >= 0);
6656 fi->appendix_start = start;
6657 fi->appendix_length = length;
6661 check_valid_filter_name_or_fail(const char *filter_name)
6663 gboolean found_invalid = proto_check_field_name(filter_name);
6665 /* Additionally forbid upper case characters. */
6666 if (!found_invalid) {
6667 for (guint i = 0; filter_name[i]; i++) {
6668 if (g_ascii_isupper(filter_name[i])) {
6669 found_invalid = TRUE;
6675 if (found_invalid) {
6676 g_error("Protocol filter name \"%s\" has one or more invalid characters."
6677 " Allowed are lower characters, digits, '-', '_' and non-repeating '.'."
6678 " This might be caused by an inappropriate plugin or a development error.", filter_name);
6683 proto_register_protocol(const char *name, const char *short_name,
6684 const char *filter_name)
6686 protocol_t *protocol;
6687 header_field_info *hfinfo;
6690 * Make sure there's not already a protocol with any of those
6691 * names. Crash if there is, as that's an error in the code
6692 * or an inappropriate plugin.
6693 * This situation has to be fixed to not register more than one
6694 * protocol with the same name.
6697 if (g_hash_table_lookup(proto_names, name)) {
6698 /* g_error will terminate the program */
6699 g_error("Duplicate protocol name \"%s\"!"
6700 " This might be caused by an inappropriate plugin or a development error.", name);
6703 if (g_hash_table_lookup(proto_short_names, short_name)) {
6704 g_error("Duplicate protocol short_name \"%s\"!"
6705 " This might be caused by an inappropriate plugin or a development error.", short_name);
6708 check_valid_filter_name_or_fail(filter_name);
6710 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
6711 g_error("Duplicate protocol filter_name \"%s\"!"
6712 " This might be caused by an inappropriate plugin or a development error.", filter_name);
6716 * Add this protocol to the list of known protocols;
6717 * the list is sorted by protocol short name.
6719 protocol = g_new(protocol_t, 1);
6720 protocol->name = name;
6721 protocol->short_name = short_name;
6722 protocol->filter_name = filter_name;
6723 protocol->fields = NULL; /* Delegate until actually needed */
6724 protocol->is_enabled = TRUE; /* protocol is enabled by default */
6725 protocol->enabled_by_default = TRUE; /* see previous comment */
6726 protocol->can_toggle = TRUE;
6727 protocol->parent_proto_id = -1;
6728 protocol->heur_list = NULL;
6730 /* List will be sorted later by name, when all protocols completed registering */
6731 protocols = g_list_prepend(protocols, protocol);
6732 g_hash_table_insert(proto_names, (gpointer)name, protocol);
6733 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
6734 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
6736 /* Here we allocate a new header_field_info struct */
6737 hfinfo = g_slice_new(header_field_info);
6738 hfinfo->name = name;
6739 hfinfo->abbrev = filter_name;
6740 hfinfo->type = FT_PROTOCOL;
6741 hfinfo->display = BASE_NONE;
6742 hfinfo->strings = protocol;
6743 hfinfo->bitmask = 0;
6744 hfinfo->ref_type = HF_REF_TYPE_NONE;
6745 hfinfo->blurb = NULL;
6746 hfinfo->parent = -1; /* This field differentiates protos and fields */
6748 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
6749 return protocol->proto_id;
6753 proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
6755 protocol_t *protocol;
6756 header_field_info *hfinfo;
6759 * Helper protocols don't need the strict rules as a "regular" protocol
6760 * Just register it in a list and make a hf_ field from it
6762 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
6763 g_error("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name);
6766 if (parent_proto < 0) {
6767 g_error("Must have a valid parent protocol for helper protocol \"%s\"!"
6768 " This might be caused by an inappropriate plugin or a development error.", name);
6771 check_valid_filter_name_or_fail(filter_name);
6773 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
6774 protocol = g_new(protocol_t, 1);
6775 protocol->name = name;
6776 protocol->short_name = short_name;
6777 protocol->filter_name = filter_name;
6778 protocol->fields = NULL; /* Delegate until actually needed */
6780 /* Enabling and toggling is really determined by parent protocol,
6781 but provide default values here */
6782 protocol->is_enabled = TRUE;
6783 protocol->enabled_by_default = TRUE;
6784 protocol->can_toggle = TRUE;
6786 protocol->parent_proto_id = parent_proto;
6787 protocol->heur_list = NULL;
6789 /* List will be sorted later by name, when all protocols completed registering */
6790 pino_protocols = g_list_prepend(pino_protocols, protocol);
6792 /* Here we allocate a new header_field_info struct */
6793 hfinfo = g_slice_new(header_field_info);
6794 hfinfo->name = name;
6795 hfinfo->abbrev = filter_name;
6796 hfinfo->type = field_type;
6797 hfinfo->display = BASE_NONE;
6798 if (field_type == FT_BYTES) {
6799 hfinfo->display |= (BASE_NO_DISPLAY_VALUE|BASE_PROTOCOL_INFO);
6801 hfinfo->strings = protocol;
6802 hfinfo->bitmask = 0;
6803 hfinfo->ref_type = HF_REF_TYPE_NONE;
6804 hfinfo->blurb = NULL;
6805 hfinfo->parent = -1; /* This field differentiates protos and fields */
6807 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
6808 return protocol->proto_id;
6812 proto_deregister_protocol(const char *short_name)
6814 protocol_t *protocol;
6815 header_field_info *hfinfo;
6819 proto_id = proto_get_id_by_short_name(short_name);
6820 protocol = find_protocol_by_id(proto_id);
6821 if (protocol == NULL)
6824 g_hash_table_remove(proto_names, protocol->name);
6825 g_hash_table_remove(proto_short_names, (gpointer)short_name);
6826 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
6828 if (protocol->fields) {
6829 for (i = 0; i < protocol->fields->len; i++) {
6830 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
6831 hfinfo_remove_from_gpa_name_map(hfinfo);
6832 expert_deregister_expertinfo(hfinfo->abbrev);
6833 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
6835 g_ptr_array_free(protocol->fields, TRUE);
6836 protocol->fields = NULL;
6839 /* Remove this protocol from the list of known protocols */
6840 protocols = g_list_remove(protocols, protocol);
6842 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
6843 g_hash_table_steal(gpa_name_map, protocol->filter_name);
6845 g_free(last_field_name);
6846 last_field_name = NULL;
6852 proto_register_alias(const int proto_id, const char *alias_name)
6854 protocol_t *protocol;
6856 protocol = find_protocol_by_id(proto_id);
6857 if (alias_name && protocol) {
6858 g_hash_table_insert(gpa_protocol_aliases, (gpointer) alias_name, (gpointer)protocol->filter_name);
6863 * Routines to use to iterate over the protocols.
6864 * The argument passed to the iterator routines is an opaque cookie to
6865 * their callers; it's the GList pointer for the current element in
6867 * The ID of the protocol is returned, or -1 if there is no protocol.
6870 proto_get_first_protocol(void **cookie)
6872 protocol_t *protocol;
6874 if (protocols == NULL)
6876 *cookie = protocols;
6877 protocol = (protocol_t *)protocols->data;
6878 return protocol->proto_id;
6882 proto_get_data_protocol(void *cookie)
6884 GList *list_item = (GList *)cookie;
6886 protocol_t *protocol = (protocol_t *)list_item->data;
6887 return protocol->proto_id;
6891 proto_get_next_protocol(void **cookie)
6893 GList *list_item = (GList *)*cookie;
6894 protocol_t *protocol;
6896 list_item = g_list_next(list_item);
6897 if (list_item == NULL)
6899 *cookie = list_item;
6900 protocol = (protocol_t *)list_item->data;
6901 return protocol->proto_id;
6904 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
6905 assume that the cookie stored by
6906 proto_get_(first|next)_protocol_field() will never have a
6907 value of NULL. So, to preserve this semantic, the cookie value
6908 below is adjusted so that the cookie value stored is 1 + the
6909 current (zero-based) array index.
6912 proto_get_first_protocol_field(const int proto_id, void **cookie)
6914 protocol_t *protocol = find_protocol_by_id(proto_id);
6916 if ((protocol == NULL) || (protocol->fields == NULL) || (protocol->fields->len == 0))
6919 *cookie = GUINT_TO_POINTER(0 + 1);
6920 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
6924 proto_get_next_protocol_field(const int proto_id, void **cookie)
6926 protocol_t *protocol = find_protocol_by_id(proto_id);
6927 guint i = GPOINTER_TO_UINT(*cookie) - 1;
6931 if ((protocol->fields == NULL) || (i >= protocol->fields->len))
6934 *cookie = GUINT_TO_POINTER(i + 1);
6935 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
6939 find_protocol_by_id(const int proto_id)
6941 header_field_info *hfinfo;
6946 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
6947 if (hfinfo->type != FT_PROTOCOL) {
6948 DISSECTOR_ASSERT(hfinfo->display & BASE_PROTOCOL_INFO);
6950 return (protocol_t *)hfinfo->strings;
6954 proto_get_id(const protocol_t *protocol)
6956 return protocol->proto_id;
6960 proto_name_already_registered(const gchar *name)
6962 DISSECTOR_ASSERT_HINT(name, "No name present");
6964 if (g_hash_table_lookup(proto_names, name) != NULL)
6970 proto_get_id_by_filter_name(const gchar *filter_name)
6972 const protocol_t *protocol = NULL;
6974 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
6976 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
6978 if (protocol == NULL)
6980 return protocol->proto_id;
6984 proto_get_id_by_short_name(const gchar *short_name)
6986 const protocol_t *protocol = NULL;
6988 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
6990 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
6992 if (protocol == NULL)
6994 return protocol->proto_id;
6998 proto_get_protocol_name(const int proto_id)
7000 protocol_t *protocol;
7002 protocol = find_protocol_by_id(proto_id);
7004 if (protocol == NULL)
7006 return protocol->name;
7010 proto_get_protocol_short_name(const protocol_t *protocol)
7012 if (protocol == NULL)
7014 return protocol->short_name;
7018 proto_get_protocol_long_name(const protocol_t *protocol)
7020 if (protocol == NULL)
7022 return protocol->name;
7026 proto_get_protocol_filter_name(const int proto_id)
7028 protocol_t *protocol;
7030 protocol = find_protocol_by_id(proto_id);
7031 if (protocol == NULL)
7033 return protocol->filter_name;
7036 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
7038 heur_dtbl_entry_t* heuristic_dissector;
7040 if (protocol == NULL)
7043 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
7044 if (heuristic_dissector != NULL)
7046 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
7050 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
7052 if (protocol == NULL)
7055 g_list_foreach(protocol->heur_list, func, user_data);
7059 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
7060 gboolean *is_tcp, gboolean *is_udp,
7061 gboolean *is_sctp, gboolean *is_ssl,
7063 gboolean *is_lte_rlc)
7065 wmem_list_frame_t *protos = wmem_list_head(layers);
7067 const char *proto_name;
7069 /* Walk the list of a available protocols in the packet and
7070 find "major" ones. */
7071 /* It might make more sense to assemble and return a bitfield. */
7072 while (protos != NULL)
7074 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
7075 proto_name = proto_get_protocol_filter_name(proto_id);
7077 if (is_ip && ((!strcmp(proto_name, "ip")) ||
7078 (!strcmp(proto_name, "ipv6")))) {
7080 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
7082 } else if (is_udp && !strcmp(proto_name, "udp")) {
7084 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
7086 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
7088 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
7090 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
7094 protos = wmem_list_frame_next(protos);
7099 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
7101 wmem_list_frame_t *protos = wmem_list_head(layers);
7105 /* Walk the list of a available protocols in the packet and
7106 find "major" ones. */
7107 /* It might make more sense to assemble and return a bitfield. */
7108 while (protos != NULL)
7110 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
7111 name = proto_get_protocol_filter_name(proto_id);
7113 if (!strcmp(name, proto_name))
7118 protos = wmem_list_frame_next(protos);
7125 proto_is_pino(const protocol_t *protocol)
7127 return (protocol->parent_proto_id != -1);
7131 proto_is_protocol_enabled(const protocol_t *protocol)
7133 if (protocol == NULL)
7136 //parent protocol determines enable/disable for helper dissectors
7137 if (proto_is_pino(protocol))
7138 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
7140 return protocol->is_enabled;
7144 proto_is_protocol_enabled_by_default(const protocol_t *protocol)
7146 //parent protocol determines enable/disable for helper dissectors
7147 if (proto_is_pino(protocol))
7148 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
7150 return protocol->enabled_by_default;
7154 proto_can_toggle_protocol(const int proto_id)
7156 protocol_t *protocol;
7158 protocol = find_protocol_by_id(proto_id);
7159 //parent protocol determines toggling for helper dissectors
7160 if (proto_is_pino(protocol))
7161 return proto_can_toggle_protocol(protocol->parent_proto_id);
7163 return protocol->can_toggle;
7167 proto_disable_by_default(const int proto_id)
7169 protocol_t *protocol;
7171 protocol = find_protocol_by_id(proto_id);
7172 DISSECTOR_ASSERT(protocol->can_toggle);
7173 DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
7174 protocol->is_enabled = FALSE;
7175 protocol->enabled_by_default = FALSE;
7179 proto_set_decoding(const int proto_id, const gboolean enabled)
7181 protocol_t *protocol;
7183 protocol = find_protocol_by_id(proto_id);
7184 DISSECTOR_ASSERT(protocol->can_toggle);
7185 DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
7186 protocol->is_enabled = enabled;
7190 proto_reenable_all(void)
7192 protocol_t *protocol;
7193 GList *list_item = protocols;
7195 if (protocols == NULL)
7199 protocol = (protocol_t *)list_item->data;
7200 if (protocol->can_toggle && protocol->enabled_by_default)
7201 protocol->is_enabled = TRUE;
7202 list_item = g_list_next(list_item);
7207 proto_set_cant_toggle(const int proto_id)
7209 protocol_t *protocol;
7211 protocol = find_protocol_by_id(proto_id);
7212 protocol->can_toggle = FALSE;
7216 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
7218 if (proto != NULL) {
7219 g_ptr_array_add(proto->fields, hfi);
7222 return proto_register_field_init(hfi, parent);
7225 /* for use with static arrays only, since we don't allocate our own copies
7226 of the header_field_info struct contained within the hf_register_info struct */
7228 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
7230 hf_register_info *ptr = hf;
7234 proto = find_protocol_by_id(parent);
7236 if (proto->fields == NULL) {
7237 proto->fields = g_ptr_array_sized_new(num_records);
7240 for (i = 0; i < num_records; i++, ptr++) {
7242 * Make sure we haven't registered this yet.
7243 * Most fields have variables associated with them
7244 * that are initialized to -1; some have array elements,
7245 * or possibly uninitialized variables, so we also allow
7246 * 0 (which is unlikely to be the field ID we get back
7247 * from "proto_register_field_init()").
7249 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
7251 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
7252 ptr->hfinfo.abbrev);
7256 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
7261 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
7266 proto = find_protocol_by_id(parent);
7268 if (proto->fields == NULL) {
7269 proto->fields = g_ptr_array_sized_new(num_records);
7272 for (i = 0; i < num_records; i++) {
7274 * Make sure we haven't registered this yet.
7276 if (hfi[i].id != -1) {
7278 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7283 proto_register_field_common(proto, &hfi[i], parent);
7288 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
7293 proto = find_protocol_by_id(parent);
7295 if (proto->fields == NULL) {
7296 proto->fields = g_ptr_array_sized_new(num_records);
7300 for (i = 0; i < num_records; i++) {
7302 * Make sure we haven't registered this yet.
7304 if (hfi[i]->id != -1) {
7306 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7311 proto_register_field_common(proto, hfi[i], parent);
7315 /* deregister already registered fields */
7317 proto_deregister_field (const int parent, gint hf_id)
7319 header_field_info *hfi;
7323 g_free(last_field_name);
7324 last_field_name = NULL;
7326 if (hf_id == -1 || hf_id == 0)
7329 proto = find_protocol_by_id (parent);
7330 if (!proto || proto->fields == NULL) {
7334 for (i = 0; i < proto->fields->len; i++) {
7335 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
7336 if (hfi->id == hf_id) {
7337 /* Found the hf_id in this protocol */
7338 g_hash_table_steal(gpa_name_map, hfi->abbrev);
7339 g_ptr_array_remove_index_fast(proto->fields, i);
7340 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
7347 proto_add_deregistered_data (void *data)
7349 g_ptr_array_add(deregistered_data, data);
7353 free_deregistered_field (gpointer data, gpointer user_data _U_)
7355 header_field_info *hfi = (header_field_info *) data;
7356 gint hf_id = hfi->id;
7358 g_free((char *)hfi->name);
7359 g_free((char *)hfi->abbrev);
7360 g_free((char *)hfi->blurb);
7363 switch (hfi->type) {
7365 /* This is just an integer represented as a pointer */
7368 protocol_t *protocol = (protocol_t *)hfi->strings;
7369 g_free((gchar *)protocol->short_name);
7373 true_false_string *tf = (true_false_string *)hfi->strings;
7374 g_free ((gchar *)tf->true_string);
7375 g_free ((gchar *)tf->false_string);
7387 * XXX - if it's BASE_RANGE_STRING, or
7388 * BASE_EXT_STRING, should we free it?
7390 if (hfi->display & BASE_UNIT_STRING) {
7391 unit_name_string *unit = (unit_name_string*)hfi->strings;
7392 g_free ((gchar *)unit->singular);
7393 g_free ((gchar *)unit->plural);
7395 val64_string *vs64 = (val64_string *)hfi->strings;
7396 while (vs64->strptr) {
7397 g_free((gchar *)vs64->strptr);
7415 * XXX - if it's BASE_RANGE_STRING, or
7416 * BASE_EXT_STRING, should we free it?
7418 if (hfi->display & BASE_UNIT_STRING) {
7419 unit_name_string *unit = (unit_name_string*)hfi->strings;
7420 g_free ((gchar *)unit->singular);
7421 g_free ((gchar *)unit->plural);
7423 value_string *vs = (value_string *)hfi->strings;
7424 while (vs->strptr) {
7425 g_free((gchar *)vs->strptr);
7434 if (hfi->type != FT_FRAMENUM) {
7435 g_free((void *)hfi->strings);
7439 if (hfi->parent == -1)
7440 g_slice_free(header_field_info, hfi);
7442 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
7446 free_deregistered_data (gpointer data, gpointer user_data _U_)
7451 /* free deregistered fields and data */
7453 proto_free_deregistered_fields (void)
7455 expert_free_deregistered_expertinfos();
7457 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
7458 g_ptr_array_free(deregistered_fields, TRUE);
7459 deregistered_fields = g_ptr_array_new();
7461 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
7462 g_ptr_array_free(deregistered_data, TRUE);
7463 deregistered_data = g_ptr_array_new();
7466 /* chars allowed in field abbrev: alphanumerics, '-', "_", and ".". */
7468 const guint8 fld_abbrev_chars[256] = {
7469 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
7470 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
7471 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
7472 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
7473 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
7474 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
7475 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
7476 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
7477 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
7478 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
7479 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
7480 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
7481 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
7482 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
7483 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
7484 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
7487 static const value_string hf_display[] = {
7488 { BASE_NONE, "BASE_NONE" },
7489 { BASE_DEC, "BASE_DEC" },
7490 { BASE_HEX, "BASE_HEX" },
7491 { BASE_OCT, "BASE_OCT" },
7492 { BASE_DEC_HEX, "BASE_DEC_HEX" },
7493 { BASE_HEX_DEC, "BASE_HEX_DEC" },
7494 { BASE_CUSTOM, "BASE_CUSTOM" },
7495 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
7496 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
7497 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
7498 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
7499 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
7500 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
7501 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
7502 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
7503 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
7504 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
7505 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
7506 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
7507 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
7508 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
7509 /* Alias: BASE_NONE { BASE_FLOAT, "BASE_FLOAT" }, */
7510 /* Alias: BASE_NONE { STR_ASCII, "STR_ASCII" }, */
7511 { STR_UNICODE, "STR_UNICODE" },
7512 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
7513 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
7514 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
7515 { BASE_PT_UDP, "BASE_PT_UDP" },
7516 { BASE_PT_TCP, "BASE_PT_TCP" },
7517 { BASE_PT_DCCP, "BASE_PT_DCCP" },
7518 { BASE_PT_SCTP, "BASE_PT_SCTP" },
7519 { BASE_OUI, "BASE_OUI" },
7522 const char* proto_field_display_to_string(int field_display)
7524 return val_to_str_const(field_display, hf_display, "Unknown");
7527 static inline port_type
7528 display_to_port_type(field_display_e e)
7545 /* temporary function containing assert part for easier profiling */
7547 tmp_fld_check_assert(header_field_info *hfinfo)
7551 /* The field must have a name (with length > 0) */
7552 if (!hfinfo->name || !hfinfo->name[0]) {
7554 /* Try to identify the field */
7555 g_error("Field (abbrev='%s') does not have a name\n",
7559 g_error("Field does not have a name (nor an abbreviation)\n");
7562 /* fields with an empty string for an abbreviation aren't filterable */
7563 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
7564 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
7566 /* These types of fields are allowed to have value_strings,
7567 * true_false_strings or a protocol_t struct
7569 if (hfinfo->strings != NULL) {
7570 switch (hfinfo->type) {
7594 //allowed to support string if its a unit decsription
7595 if (hfinfo->display & BASE_UNIT_STRING)
7600 //allowed to support string if its a protocol (for pinos)
7601 if (hfinfo->display & BASE_PROTOCOL_INFO)
7606 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
7607 " (which is not allowed to have strings)\n",
7608 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
7612 /* TODO: This check may slow down startup, and output quite a few warnings.
7613 It would be good to be able to enable this (and possibly other checks?)
7614 in non-release builds. */
7615 #if ENABLE_CHECK_FILTER
7616 /* Check for duplicate value_string values.
7617 There are lots that have the same value *and* string, so for now only
7618 report those that have same value but different string. */
7619 if ((hfinfo->strings != NULL) &&
7620 !(hfinfo->display & BASE_RANGE_STRING) &&
7621 !(hfinfo->display & BASE_UNIT_STRING) &&
7622 !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
7624 (hfinfo->type == FT_CHAR) ||
7625 (hfinfo->type == FT_UINT8) ||
7626 (hfinfo->type == FT_UINT16) ||
7627 (hfinfo->type == FT_UINT24) ||
7628 (hfinfo->type == FT_UINT32) ||
7629 (hfinfo->type == FT_INT8) ||
7630 (hfinfo->type == FT_INT16) ||
7631 (hfinfo->type == FT_INT24) ||
7632 (hfinfo->type == FT_INT32) )) {
7635 const value_string *start_values;
7636 const value_string *current;
7638 if (hfinfo->display & BASE_EXT_STRING)
7639 start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
7641 start_values = (const value_string*)hfinfo->strings;
7642 current = start_values;
7644 for (n=0; current; n++, current++) {
7645 /* Drop out if we reached the end. */
7646 if ((current->value == 0) && (current->strptr == NULL)) {
7650 /* Check value against all previous */
7651 for (m=0; m < n; m++) {
7652 /* There are lots of duplicates with the same string,
7653 so only report if different... */
7654 if ((start_values[m].value == current->value) &&
7655 (strcmp(start_values[m].strptr, current->strptr) != 0)) {
7656 ws_g_warning("Field '%s' (%s) has a conflicting entry in its"
7657 " value_string: %u is at indices %u (%s) and %u (%s)\n",
7658 hfinfo->name, hfinfo->abbrev,
7659 current->value, m, start_values[m].strptr, n, current->strptr);
7667 switch (hfinfo->type) {
7670 /* Require the char type to have BASE_HEX, BASE_OCT,
7671 * BASE_CUSTOM, or BASE_NONE as its base.
7673 * If the display value is BASE_NONE and there is a
7674 * strings conversion then the dissector writer is
7675 * telling us that the field's numerical value is
7676 * meaningless; we'll avoid showing the value to the
7679 switch (FIELD_DISPLAY(hfinfo->display)) {
7682 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
7685 if (hfinfo->strings == NULL)
7686 g_error("Field '%s' (%s) is an integral value (%s)"
7687 " but is being displayed as BASE_NONE but"
7688 " without a strings conversion",
7689 hfinfo->name, hfinfo->abbrev,
7690 ftype_name(hfinfo->type));
7693 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7694 g_error("Field '%s' (%s) is a character value (%s)"
7695 " but is being displayed as %s\n",
7696 hfinfo->name, hfinfo->abbrev,
7697 ftype_name(hfinfo->type), tmp_str);
7698 wmem_free(NULL, tmp_str);
7700 if (hfinfo->display & BASE_UNIT_STRING) {
7701 g_error("Field '%s' (%s) is a character value (%s) but has a unit string\n",
7702 hfinfo->name, hfinfo->abbrev,
7703 ftype_name(hfinfo->type));
7714 /* Hexadecimal and octal are, in printf() and everywhere
7715 * else, unsigned so don't allow dissectors to register a
7716 * signed field to be displayed unsigned. (Else how would
7717 * we display negative values?)
7719 switch (FIELD_DISPLAY(hfinfo->display)) {
7724 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7725 g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
7726 hfinfo->name, hfinfo->abbrev,
7727 ftype_name(hfinfo->type), tmp_str);
7728 wmem_free(NULL, tmp_str);
7739 if (IS_BASE_PORT(hfinfo->display)) {
7740 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7741 if (hfinfo->type != FT_UINT16) {
7742 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
7743 hfinfo->name, hfinfo->abbrev,
7744 tmp_str, ftype_name(hfinfo->type));
7746 if (hfinfo->strings != NULL) {
7747 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
7748 hfinfo->name, hfinfo->abbrev,
7749 ftype_name(hfinfo->type), tmp_str);
7751 if (hfinfo->bitmask != 0) {
7752 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
7753 hfinfo->name, hfinfo->abbrev,
7754 ftype_name(hfinfo->type), tmp_str);
7756 wmem_free(NULL, tmp_str);
7760 if (hfinfo->display == BASE_OUI) {
7761 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7762 if (hfinfo->type != FT_UINT24) {
7763 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s\n",
7764 hfinfo->name, hfinfo->abbrev,
7765 tmp_str, ftype_name(hfinfo->type));
7767 if (hfinfo->strings != NULL) {
7768 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
7769 hfinfo->name, hfinfo->abbrev,
7770 ftype_name(hfinfo->type), tmp_str);
7772 if (hfinfo->bitmask != 0) {
7773 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
7774 hfinfo->name, hfinfo->abbrev,
7775 ftype_name(hfinfo->type), tmp_str);
7777 wmem_free(NULL, tmp_str);
7781 /* Require integral types (other than frame number,
7782 * which is always displayed in decimal) to have a
7785 * If the display value is BASE_NONE and there is a
7786 * strings conversion then the dissector writer is
7787 * telling us that the field's numerical value is
7788 * meaningless; we'll avoid showing the value to the
7791 switch (FIELD_DISPLAY(hfinfo->display)) {
7797 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
7800 if (hfinfo->strings == NULL) {
7801 g_error("Field '%s' (%s) is an integral value (%s)"
7802 " but is being displayed as BASE_NONE but"
7803 " without a strings conversion",
7804 hfinfo->name, hfinfo->abbrev,
7805 ftype_name(hfinfo->type));
7807 if (hfinfo->display & BASE_SPECIAL_VALS) {
7808 g_error("Field '%s' (%s) is an integral value (%s)"
7809 " that is being displayed as BASE_NONE but"
7810 " with BASE_SPECIAL_VALS",
7811 hfinfo->name, hfinfo->abbrev,
7812 ftype_name(hfinfo->type));
7817 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7818 g_error("Field '%s' (%s) is an integral value (%s)"
7819 " but is being displayed as %s\n",
7820 hfinfo->name, hfinfo->abbrev,
7821 ftype_name(hfinfo->type), tmp_str);
7822 wmem_free(NULL, tmp_str);
7827 /* Require bytes to have a "display type" that could
7828 * add a character between displayed bytes.
7830 switch (FIELD_DISPLAY(hfinfo->display)) {
7838 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7839 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",
7840 hfinfo->name, hfinfo->abbrev, tmp_str);
7841 wmem_free(NULL, tmp_str);
7843 if (hfinfo->bitmask != 0)
7844 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7845 hfinfo->name, hfinfo->abbrev,
7846 ftype_name(hfinfo->type));
7847 //allowed to support string if its a protocol (for pinos)
7848 if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_PROTOCOL_INFO)))
7849 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7850 hfinfo->name, hfinfo->abbrev,
7851 ftype_name(hfinfo->type));
7856 if (hfinfo->display != BASE_NONE) {
7857 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7858 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7859 hfinfo->name, hfinfo->abbrev,
7860 ftype_name(hfinfo->type), tmp_str);
7861 wmem_free(NULL, tmp_str);
7863 if (hfinfo->bitmask != 0)
7864 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7865 hfinfo->name, hfinfo->abbrev,
7866 ftype_name(hfinfo->type));
7872 case FT_ABSOLUTE_TIME:
7873 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
7874 hfinfo->display == ABSOLUTE_TIME_UTC ||
7875 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
7876 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7877 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
7878 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
7879 wmem_free(NULL, tmp_str);
7881 if (hfinfo->bitmask != 0)
7882 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7883 hfinfo->name, hfinfo->abbrev,
7884 ftype_name(hfinfo->type));
7889 case FT_UINT_STRING:
7891 switch (hfinfo->display) {
7897 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7898 g_error("Field '%s' (%s) is an string value (%s)"
7899 " but is being displayed as %s\n",
7900 hfinfo->name, hfinfo->abbrev,
7901 ftype_name(hfinfo->type), tmp_str);
7902 wmem_free(NULL, tmp_str);
7905 if (hfinfo->bitmask != 0)
7906 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7907 hfinfo->name, hfinfo->abbrev,
7908 ftype_name(hfinfo->type));
7909 if (hfinfo->strings != NULL)
7910 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7911 hfinfo->name, hfinfo->abbrev,
7912 ftype_name(hfinfo->type));
7916 switch (hfinfo->display) {
7922 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7923 g_error("Field '%s' (%s) is an IPv4 value (%s)"
7924 " but is being displayed as %s\n",
7925 hfinfo->name, hfinfo->abbrev,
7926 ftype_name(hfinfo->type), tmp_str);
7927 wmem_free(NULL, tmp_str);
7933 if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
7934 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7935 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7936 hfinfo->name, hfinfo->abbrev,
7937 ftype_name(hfinfo->type),
7939 wmem_free(NULL, tmp_str);
7941 if (hfinfo->bitmask != 0)
7942 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7943 hfinfo->name, hfinfo->abbrev,
7944 ftype_name(hfinfo->type));
7945 if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_UNIT_STRING)))
7946 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7947 hfinfo->name, hfinfo->abbrev,
7948 ftype_name(hfinfo->type));
7951 if (hfinfo->display != BASE_NONE) {
7952 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7953 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7954 hfinfo->name, hfinfo->abbrev,
7955 ftype_name(hfinfo->type),
7957 wmem_free(NULL, tmp_str);
7959 if (hfinfo->bitmask != 0)
7960 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7961 hfinfo->name, hfinfo->abbrev,
7962 ftype_name(hfinfo->type));
7963 if (hfinfo->strings != NULL)
7964 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7965 hfinfo->name, hfinfo->abbrev,
7966 ftype_name(hfinfo->type));
7971 #ifdef ENABLE_CHECK_FILTER
7973 _ftype_common(enum ftenum type)
7997 case FT_UINT_STRING:
8010 case FT_ABSOLUTE_TIME:
8011 case FT_RELATIVE_TIME:
8012 return FT_ABSOLUTE_TIME;
8021 register_type_length_mismatch(void)
8023 static ei_register_info ei[] = {
8024 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
8025 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
8028 expert_module_t* expert_type_length_mismatch;
8030 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
8032 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
8033 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
8035 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
8036 disabling them makes no sense. */
8037 proto_set_cant_toggle(proto_type_length_mismatch);
8041 register_number_string_decoding_error(void)
8043 static ei_register_info ei[] = {
8044 { &ei_number_string_decoding_failed_error,
8045 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
8046 "Failed to decode number from string", EXPFILL
8049 { &ei_number_string_decoding_erange_error,
8050 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
8051 "Decoded number from string is out of valid range", EXPFILL
8056 expert_module_t* expert_number_string_decoding_error;
8058 proto_number_string_decoding_error =
8059 proto_register_protocol("Number-String Decoding Error",
8060 "Number-string decoding error",
8061 "_ws.number_string.decoding_error");
8063 expert_number_string_decoding_error =
8064 expert_register_protocol(proto_number_string_decoding_error);
8065 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
8067 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
8068 disabling them makes no sense. */
8069 proto_set_cant_toggle(proto_number_string_decoding_error);
8073 register_string_errors(void)
8075 static ei_register_info ei[] = {
8076 { &ei_string_trailing_characters,
8077 { "_ws.string.trailing_stray_characters", PI_UNDECODED, PI_WARN, "Trailing stray characters", EXPFILL }
8081 expert_module_t* expert_string_errors;
8083 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
8085 expert_string_errors = expert_register_protocol(proto_string_errors);
8086 expert_register_field_array(expert_string_errors, ei, array_length(ei));
8088 /* "String Errors" isn't really a protocol, it's an error indication;
8089 disabling them makes no sense. */
8090 proto_set_cant_toggle(proto_string_errors);
8093 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (201000+PRE_ALLOC_EXPERT_FIELDS_MEM)
8095 proto_register_field_init(header_field_info *hfinfo, const int parent)
8098 tmp_fld_check_assert(hfinfo);
8100 hfinfo->parent = parent;
8101 hfinfo->same_name_next = NULL;
8102 hfinfo->same_name_prev_id = -1;
8104 /* if we always add and never delete, then id == len - 1 is correct */
8105 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
8106 if (!gpa_hfinfo.hfi) {
8107 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
8108 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8110 gpa_hfinfo.allocated_len += 1000;
8111 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
8112 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
8113 /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
8116 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
8118 hfinfo->id = gpa_hfinfo.len - 1;
8120 /* if we have real names, enter this field in the name tree */
8121 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
8123 header_field_info *same_name_next_hfinfo;
8126 /* Check that the filter name (abbreviation) is legal;
8127 * it must contain only alphanumerics, '-', "_", and ".". */
8128 c = proto_check_field_name(hfinfo->abbrev);
8131 fprintf(stderr, "Invalid leading, duplicated or trailing '.' found in filter name '%s'\n", hfinfo->abbrev);
8132 } else if (g_ascii_isprint(c)) {
8133 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
8135 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
8137 DISSECTOR_ASSERT_NOT_REACHED();
8140 /* We allow multiple hfinfo's to be registered under the same
8141 * abbreviation. This was done for X.25, as, depending
8142 * on whether it's modulo-8 or modulo-128 operation,
8143 * some bitfield fields may be in different bits of
8144 * a byte, and we want to be able to refer to that field
8145 * with one name regardless of whether the packets
8146 * are modulo-8 or modulo-128 packets. */
8148 same_name_hfinfo = NULL;
8150 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
8151 /* GLIB 2.x - if it is already present
8152 * the previous hfinfo with the same name is saved
8153 * to same_name_hfinfo by value destroy callback */
8154 if (same_name_hfinfo) {
8155 /* There's already a field with this name.
8156 * Put the current field *before* that field
8157 * in the list of fields with this name, Thus,
8158 * we end up with an effectively
8159 * doubly-linked-list of same-named hfinfo's,
8160 * with the head of the list (stored in the
8161 * hash) being the last seen hfinfo.
8163 same_name_next_hfinfo =
8164 same_name_hfinfo->same_name_next;
8166 hfinfo->same_name_next = same_name_next_hfinfo;
8167 if (same_name_next_hfinfo)
8168 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
8170 same_name_hfinfo->same_name_next = hfinfo;
8171 hfinfo->same_name_prev_id = same_name_hfinfo->id;
8172 #ifdef ENABLE_CHECK_FILTER
8173 while (same_name_hfinfo) {
8174 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
8175 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));
8176 same_name_hfinfo = same_name_hfinfo->same_name_next;
8186 proto_register_subtree_array(gint *const *indices, const int num_indices)
8189 gint *const *ptr = indices;
8192 * If we've already allocated the array of tree types, expand
8193 * it; this lets plugins such as mate add tree types after
8194 * the initial startup. (If we haven't already allocated it,
8195 * we don't allocate it; on the first pass, we just assign
8196 * ett values and keep track of how many we've assigned, and
8197 * when we're finished registering all dissectors we allocate
8198 * the array, so that we do only one allocation rather than
8199 * wasting CPU time and memory by growing the array for each
8200 * dissector that registers ett values.)
8202 if (tree_is_expanded != NULL) {
8203 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
8205 /* set new items to 0 */
8206 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
8207 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
8208 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
8212 * Assign "num_indices" subtree numbers starting at "num_tree_types",
8213 * returning the indices through the pointers in the array whose
8214 * first element is pointed to by "indices", and update
8215 * "num_tree_types" appropriately.
8217 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
8219 /* g_error will terminate the program */
8220 g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
8221 " This is a development error:"
8222 " Either the subtree item type has already been assigned or"
8223 " was not initialized to -1.");
8225 **ptr = num_tree_types;
8230 label_concat(char *label_str, gsize pos, const char *str)
8232 if (pos < ITEM_LABEL_LENGTH)
8233 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
8239 label_mark_truncated(char *label_str, gsize name_pos)
8241 static const char trunc_str[] = " [truncated]";
8242 const size_t trunc_len = sizeof(trunc_str)-1;
8245 /* ..... field_name: dataaaaaaaaaaaaa
8249 * ..... field_name [truncated]: dataaaaaaaaaaaaa
8251 * name_pos==0 means that we have only data or only a field_name
8254 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
8255 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
8256 memcpy(label_str + name_pos, trunc_str, trunc_len);
8258 /* in general, label_str is UTF-8
8259 we can truncate it only at the beginning of a new character
8260 we go backwards from the byte right after our buffer and
8261 find the next starting byte of a UTF-8 character, this is
8263 there's no need to use g_utf8_find_prev_char(), the search
8264 will always succeed since we copied trunc_str into the
8266 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH - 1]);
8269 } else if (name_pos < ITEM_LABEL_LENGTH)
8270 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
8274 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
8278 /* "%s: %s", hfinfo->name, text */
8279 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
8280 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
8281 pos = label_concat(label_str, pos, ": ");
8282 pos = label_concat(label_str, pos, text ? text : "(null)");
8285 if (pos >= ITEM_LABEL_LENGTH) {
8286 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8287 label_mark_truncated(label_str, name_pos);
8294 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
8298 /* "%s: %s (%s)", hfinfo->name, text, descr */
8299 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
8300 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
8301 pos = label_concat(label_str, pos, ": ");
8302 if (hfinfo->display & BASE_UNIT_STRING) {
8303 pos = label_concat(label_str, pos, descr ? descr : "(null)");
8304 pos = label_concat(label_str, pos, text ? text : "(null)");
8306 pos = label_concat(label_str, pos, text ? text : "(null)");
8307 pos = label_concat(label_str, pos, " (");
8308 pos = label_concat(label_str, pos, descr ? descr : "(null)");
8309 pos = label_concat(label_str, pos, ")");
8313 if (pos >= ITEM_LABEL_LENGTH) {
8314 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8315 label_mark_truncated(label_str, name_pos);
8322 proto_item_fill_label(field_info *fi, gchar *label_str)
8324 header_field_info *hfinfo;
8338 /* XXX: Check validity of hfinfo->type */
8342 hfinfo = fi->hfinfo;
8344 switch (hfinfo->type) {
8347 g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
8351 fill_label_boolean(fi, label_str);
8356 bytes = (guint8 *)fvalue_get(&fi->value);
8359 switch (hfinfo->display) {
8361 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
8364 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
8367 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
8370 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
8374 if (prefs.display_byte_fields_with_spaces) {
8375 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
8377 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
8381 label_fill(label_str, 0, hfinfo, str);
8382 wmem_free(NULL, str);
8384 if (hfinfo->display & BASE_ALLOW_ZERO) {
8385 label_fill(label_str, 0, hfinfo, "<none>");
8387 label_fill(label_str, 0, hfinfo, "<MISSING>");
8393 if (hfinfo->bitmask) {
8394 fill_label_bitfield_char(fi, label_str);
8396 fill_label_char(fi, label_str);
8400 /* Four types of integers to take care of:
8401 * Bitfield, with val_string
8402 * Bitfield, w/o val_string
8403 * Non-bitfield, with val_string
8404 * Non-bitfield, w/o val_string
8410 if (hfinfo->bitmask) {
8411 if (fi->flags & FI_VARINT) {
8412 fill_label_bitfield_varint(fi, label_str, FALSE);
8414 fill_label_bitfield(fi, label_str, FALSE);
8417 fill_label_number(fi, label_str, FALSE);
8422 fill_label_number(fi, label_str, FALSE);
8429 if (hfinfo->bitmask) {
8430 if (fi->flags & FI_VARINT) {
8431 fill_label_bitfield_varint64(fi, label_str, FALSE);
8433 fill_label_bitfield64(fi, label_str, FALSE);
8436 fill_label_number64(fi, label_str, FALSE);
8444 if (hfinfo->bitmask) {
8445 if (fi->flags & FI_VARINT) {
8446 fill_label_bitfield_varint(fi, label_str, TRUE);
8448 fill_label_bitfield(fi, label_str, TRUE);
8451 fill_label_number(fi, label_str, TRUE);
8459 if (hfinfo->bitmask) {
8460 if (fi->flags & FI_VARINT) {
8461 fill_label_bitfield_varint64(fi, label_str, TRUE);
8463 fill_label_bitfield64(fi, label_str, TRUE);
8466 fill_label_number64(fi, label_str, TRUE);
8472 double d_value = fvalue_get_floating(&fi->value);
8473 if (hfinfo->display & BASE_UNIT_STRING) {
8474 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8475 "%s: %." G_STRINGIFY(FLT_DIG) "g%s",
8476 hfinfo->name, d_value,
8477 unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
8479 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8480 "%s: %." G_STRINGIFY(FLT_DIG) "g",
8481 hfinfo->name, d_value);
8488 double d_value = fvalue_get_floating(&fi->value);
8489 if (hfinfo->display & BASE_UNIT_STRING) {
8490 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8491 "%s: %." G_STRINGIFY(DBL_DIG) "g%s",
8492 hfinfo->name, d_value,
8493 unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
8495 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8496 "%s: %." G_STRINGIFY(DBL_DIG) "g",
8497 hfinfo->name, d_value);
8502 case FT_ABSOLUTE_TIME:
8503 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
8504 label_fill(label_str, 0, hfinfo, tmp);
8505 wmem_free(NULL, tmp);
8508 case FT_RELATIVE_TIME:
8509 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
8510 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8511 "%s: %s seconds", hfinfo->name, tmp);
8512 wmem_free(NULL, tmp);
8516 integer = fvalue_get_uinteger(&fi->value);
8517 tmp = get_ipxnet_name(NULL, integer);
8518 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8519 "%s: %s (0x%08X)", hfinfo->name,
8521 wmem_free(NULL, tmp);
8525 addr.type = AT_AX25;
8526 addr.len = AX25_ADDR_LEN;
8527 addr.data = (guint8 *)fvalue_get(&fi->value);
8529 addr_str = (char*)address_to_str(NULL, &addr);
8530 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8531 "%s: %s", hfinfo->name, addr_str);
8532 wmem_free(NULL, addr_str);
8536 addr.type = AT_VINES;
8537 addr.len = VINES_ADDR_LEN;
8538 addr.data = (guint8 *)fvalue_get(&fi->value);
8540 addr_str = (char*)address_to_str(NULL, &addr);
8541 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8542 "%s: %s", hfinfo->name, addr_str);
8543 wmem_free(NULL, addr_str);
8547 bytes = (guint8 *)fvalue_get(&fi->value);
8549 addr.type = AT_ETHER;
8553 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8554 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8555 "%s: %s", hfinfo->name, addr_str);
8556 wmem_free(NULL, addr_str);
8560 ipv4 = fvalue_get_uinteger(&fi->value);
8562 addr.type = AT_IPv4;
8566 if (hfinfo->display == BASE_NETMASK) {
8567 addr_str = (char*)address_to_str(NULL, &addr);
8569 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8571 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8572 "%s: %s", hfinfo->name, addr_str);
8573 wmem_free(NULL, addr_str);
8577 bytes = (guint8 *)fvalue_get(&fi->value);
8579 addr.type = AT_IPv6;
8583 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8584 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8585 "%s: %s", hfinfo->name, addr_str);
8586 wmem_free(NULL, addr_str);
8590 addr.type = AT_FCWWN;
8591 addr.len = FCWWN_ADDR_LEN;
8592 addr.data = (guint8 *)fvalue_get(&fi->value);
8594 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8595 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8596 "%s: %s", hfinfo->name, addr_str);
8597 wmem_free(NULL, addr_str);
8601 guid = (e_guid_t *)fvalue_get(&fi->value);
8602 tmp = guid_to_str(NULL, guid);
8603 label_fill(label_str, 0, hfinfo, tmp);
8604 wmem_free(NULL, tmp);
8608 bytes = (guint8 *)fvalue_get(&fi->value);
8609 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
8610 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
8612 label_fill_descr(label_str, 0, hfinfo, tmp, name);
8613 wmem_free(NULL, name);
8615 label_fill(label_str, 0, hfinfo, tmp);
8617 wmem_free(NULL, tmp);
8621 bytes = (guint8 *)fvalue_get(&fi->value);
8622 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
8623 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
8625 label_fill_descr(label_str, 0, hfinfo, tmp, name);
8626 wmem_free(NULL, name);
8628 label_fill(label_str, 0, hfinfo, tmp);
8630 wmem_free(NULL, tmp);
8634 bytes = (guint8 *)fvalue_get(&fi->value);
8635 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
8636 label_fill(label_str, 0, hfinfo, tmp);
8637 wmem_free(NULL, tmp);
8641 integer64 = fvalue_get_uinteger64(&fi->value);
8642 addr_str = eui64_to_str(NULL, integer64);
8643 tmp = (char*)eui64_to_display(NULL, integer64);
8644 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
8645 wmem_free(NULL, tmp);
8646 wmem_free(NULL, addr_str);
8650 case FT_UINT_STRING:
8652 bytes = (guint8 *)fvalue_get(&fi->value);
8653 tmp = hfinfo_format_text(hfinfo, bytes);
8654 label_fill(label_str, 0, hfinfo, tmp);
8655 wmem_free(NULL, tmp);
8658 case FT_IEEE_11073_SFLOAT:
8659 case FT_IEEE_11073_FLOAT:
8660 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
8661 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8664 wmem_free(NULL, tmp);
8668 g_error("hfinfo->type %d (%s) not handled\n",
8669 hfinfo->type, ftype_name(hfinfo->type));
8670 DISSECTOR_ASSERT_NOT_REACHED();
8676 fill_label_boolean(field_info *fi, gchar *label_str)
8678 char *p = label_str;
8679 int bitfield_byte_length = 0, bitwidth;
8680 guint64 unshifted_value;
8683 header_field_info *hfinfo = fi->hfinfo;
8684 const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
8686 if (hfinfo->strings) {
8687 tfstring = (const struct true_false_string*) hfinfo->strings;
8690 value = fvalue_get_uinteger64(&fi->value);
8691 if (hfinfo->bitmask) {
8692 /* Figure out the bit width */
8693 bitwidth = hfinfo_container_bitwidth(hfinfo);
8696 unshifted_value = value;
8697 unshifted_value <<= hfinfo_bitshift(hfinfo);
8699 /* Create the bitfield first */
8700 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8701 bitfield_byte_length = (int) (p - label_str);
8704 /* Fill in the textual info */
8705 label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
8709 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
8711 if (hfinfo->display & BASE_RANGE_STRING)
8712 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
8714 if (hfinfo->display & BASE_EXT_STRING)
8715 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
8717 if (hfinfo->display & BASE_VAL64_STRING)
8718 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
8720 if (hfinfo->display & BASE_UNIT_STRING)
8721 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
8723 return try_val_to_str(value, (const value_string *) hfinfo->strings);
8727 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
8729 if (hfinfo->display & BASE_VAL64_STRING)
8730 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
8732 if (hfinfo->display & BASE_RANGE_STRING)
8733 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
8735 if (hfinfo->display & BASE_UNIT_STRING)
8736 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
8738 /* If this is reached somebody registered a 64-bit field with a 32-bit
8739 * value-string, which isn't right. */
8740 REPORT_DISSECTOR_BUG("field %s is a 64-bit field with a 32-bit value_string",
8743 /* This is necessary to squelch MSVC errors; is there
8744 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
8750 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
8752 const char *str = hf_try_val_to_str(value, hfinfo);
8754 return (str) ? str : unknown_str;
8758 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
8760 const char *str = hf_try_val64_to_str(value, hfinfo);
8762 return (str) ? str : unknown_str;
8765 /* Fills data for bitfield chars with val_strings */
8767 fill_label_bitfield_char(field_info *fi, gchar *label_str)
8770 int bitfield_byte_length, bitwidth;
8771 guint32 unshifted_value;
8777 header_field_info *hfinfo = fi->hfinfo;
8779 /* Figure out the bit width */
8780 bitwidth = hfinfo_container_bitwidth(hfinfo);
8783 value = fvalue_get_uinteger(&fi->value);
8785 unshifted_value = value;
8786 if (hfinfo->bitmask) {
8787 unshifted_value <<= hfinfo_bitshift(hfinfo);
8790 /* Create the bitfield first */
8791 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8792 bitfield_byte_length = (int) (p - label_str);
8794 /* Fill in the textual info using stored (shifted) value */
8795 if (hfinfo->display == BASE_CUSTOM) {
8796 gchar tmp[ITEM_LABEL_LENGTH];
8797 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8799 DISSECTOR_ASSERT(fmtfunc);
8800 fmtfunc(tmp, value);
8801 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8803 else if (hfinfo->strings) {
8804 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8806 out = hfinfo_char_vals_format(hfinfo, buf, value);
8807 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8808 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8810 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8813 out = hfinfo_char_value_format(hfinfo, buf, value);
8815 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8819 /* Fills data for bitfield ints with val_strings */
8821 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
8824 int bitfield_byte_length, bitwidth;
8825 guint32 unshifted_value;
8831 header_field_info *hfinfo = fi->hfinfo;
8833 /* Figure out the bit width */
8834 bitwidth = hfinfo_container_bitwidth(hfinfo);
8838 value = fvalue_get_sinteger(&fi->value);
8840 value = fvalue_get_uinteger(&fi->value);
8842 unshifted_value = value;
8843 if (hfinfo->bitmask) {
8844 unshifted_value <<= hfinfo_bitshift(hfinfo);
8847 /* Create the bitfield first */
8848 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8849 bitfield_byte_length = (int) (p - label_str);
8851 /* Fill in the textual info using stored (shifted) value */
8852 if (hfinfo->display == BASE_CUSTOM) {
8853 gchar tmp[ITEM_LABEL_LENGTH];
8854 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8856 DISSECTOR_ASSERT(fmtfunc);
8857 fmtfunc(tmp, value);
8858 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8860 else if (hfinfo->strings) {
8861 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8863 out = hfinfo_number_vals_format(hfinfo, buf, value);
8864 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8865 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8867 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8870 out = hfinfo_number_value_format(hfinfo, buf, value);
8872 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8877 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
8880 int bitfield_byte_length, bitwidth;
8881 guint64 unshifted_value;
8887 header_field_info *hfinfo = fi->hfinfo;
8889 /* Figure out the bit width */
8890 bitwidth = hfinfo_container_bitwidth(hfinfo);
8894 value = fvalue_get_sinteger64(&fi->value);
8896 value = fvalue_get_uinteger64(&fi->value);
8898 unshifted_value = value;
8899 if (hfinfo->bitmask) {
8900 unshifted_value <<= hfinfo_bitshift(hfinfo);
8903 /* Create the bitfield first */
8904 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8905 bitfield_byte_length = (int) (p - label_str);
8907 /* Fill in the textual info using stored (shifted) value */
8908 if (hfinfo->display == BASE_CUSTOM) {
8909 gchar tmp[ITEM_LABEL_LENGTH];
8910 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
8912 DISSECTOR_ASSERT(fmtfunc64);
8913 fmtfunc64(tmp, value);
8914 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8916 else if (hfinfo->strings) {
8917 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
8919 out = hfinfo_number_vals_format64(hfinfo, buf, value);
8920 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8921 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8923 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8926 out = hfinfo_number_value_format64(hfinfo, buf, value);
8928 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8933 fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed)
8936 int bitfield_byte_length;
8937 guint32 value, unshifted_value;
8941 header_field_info *hfinfo = fi->hfinfo;
8945 value = fvalue_get_sinteger(&fi->value);
8947 value = fvalue_get_uinteger(&fi->value);
8949 unshifted_value = value;
8950 if (hfinfo->bitmask) {
8951 unshifted_value <<= hfinfo_bitshift(hfinfo);
8954 /* Create the bitfield first */
8955 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
8956 bitfield_byte_length = (int) (p - label_str);
8958 /* Fill in the textual info using stored (shifted) value */
8959 if (hfinfo->display == BASE_CUSTOM) {
8960 gchar tmp[ITEM_LABEL_LENGTH];
8961 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8963 DISSECTOR_ASSERT(fmtfunc);
8964 fmtfunc(tmp, value);
8965 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8967 else if (hfinfo->strings) {
8968 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8970 out = hfinfo_number_vals_format(hfinfo, buf, value);
8971 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8972 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8974 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8977 out = hfinfo_number_value_format(hfinfo, buf, value);
8979 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8984 fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed)
8987 int bitfield_byte_length;
8988 guint64 unshifted_value;
8994 header_field_info *hfinfo = fi->hfinfo;
8998 value = fvalue_get_sinteger64(&fi->value);
9000 value = fvalue_get_uinteger64(&fi->value);
9002 unshifted_value = value;
9003 if (hfinfo->bitmask) {
9004 unshifted_value <<= hfinfo_bitshift(hfinfo);
9007 /* Create the bitfield first */
9008 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
9009 bitfield_byte_length = (int) (p - label_str);
9011 /* Fill in the textual info using stored (shifted) value */
9012 if (hfinfo->display == BASE_CUSTOM) {
9013 gchar tmp[ITEM_LABEL_LENGTH];
9014 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9016 DISSECTOR_ASSERT(fmtfunc64);
9017 fmtfunc64(tmp, value);
9018 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9020 else if (hfinfo->strings) {
9021 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
9023 out = hfinfo_number_vals_format64(hfinfo, buf, value);
9024 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9025 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9027 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9030 out = hfinfo_number_value_format64(hfinfo, buf, value);
9032 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9037 fill_label_char(field_info *fi, gchar *label_str)
9039 header_field_info *hfinfo = fi->hfinfo;
9045 value = fvalue_get_uinteger(&fi->value);
9047 /* Fill in the textual info */
9048 if (hfinfo->display == BASE_CUSTOM) {
9049 gchar tmp[ITEM_LABEL_LENGTH];
9050 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9052 DISSECTOR_ASSERT(fmtfunc);
9053 fmtfunc(tmp, value);
9054 label_fill(label_str, 0, hfinfo, tmp);
9056 else if (hfinfo->strings) {
9057 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9059 out = hfinfo_char_vals_format(hfinfo, buf, value);
9060 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9063 out = hfinfo_char_value_format(hfinfo, buf, value);
9065 label_fill(label_str, 0, hfinfo, out);
9070 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
9072 header_field_info *hfinfo = fi->hfinfo;
9079 value = fvalue_get_sinteger(&fi->value);
9081 value = fvalue_get_uinteger(&fi->value);
9083 /* Fill in the textual info */
9084 if (hfinfo->display == BASE_CUSTOM) {
9085 gchar tmp[ITEM_LABEL_LENGTH];
9086 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9088 DISSECTOR_ASSERT(fmtfunc);
9089 fmtfunc(tmp, value);
9090 label_fill(label_str, 0, hfinfo, tmp);
9092 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
9094 * It makes no sense to have a value-string table for a
9095 * frame-number field - they're just integers giving
9096 * the ordinal frame number.
9098 const char *val_str = hf_try_val_to_str(value, hfinfo);
9100 out = hfinfo_number_vals_format(hfinfo, buf, value);
9101 if (hfinfo->display & BASE_SPECIAL_VALS) {
9103 * Unique values only display value_string string
9104 * if there is a match. Otherwise it's just a number
9107 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9109 label_fill(label_str, 0, hfinfo, out);
9112 if (val_str == NULL)
9113 val_str = "Unknown";
9115 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9116 label_fill(label_str, 0, hfinfo, val_str);
9118 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9121 else if (IS_BASE_PORT(hfinfo->display)) {
9122 gchar tmp[ITEM_LABEL_LENGTH];
9124 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
9125 display_to_port_type((field_display_e)hfinfo->display), value);
9126 label_fill(label_str, 0, hfinfo, tmp);
9129 out = hfinfo_number_value_format(hfinfo, buf, value);
9131 label_fill(label_str, 0, hfinfo, out);
9136 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
9138 header_field_info *hfinfo = fi->hfinfo;
9145 value = fvalue_get_sinteger64(&fi->value);
9147 value = fvalue_get_uinteger64(&fi->value);
9149 /* Fill in the textual info */
9150 if (hfinfo->display == BASE_CUSTOM) {
9151 gchar tmp[ITEM_LABEL_LENGTH];
9152 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9154 DISSECTOR_ASSERT(fmtfunc64);
9155 fmtfunc64(tmp, value);
9156 label_fill(label_str, 0, hfinfo, tmp);
9158 else if (hfinfo->strings) {
9159 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
9161 out = hfinfo_number_vals_format64(hfinfo, buf, value);
9162 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9163 label_fill(label_str, 0, hfinfo, val_str);
9165 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9168 out = hfinfo_number_value_format64(hfinfo, buf, value);
9170 label_fill(label_str, 0, hfinfo, out);
9175 hfinfo_bitshift(const header_field_info *hfinfo)
9177 return ws_ctz(hfinfo->bitmask);
9181 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
9183 if (!hfinfo->bitmask) {
9187 /* ilog2 = first set bit, ctz = last set bit */
9188 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
9192 hfinfo_type_bitwidth(enum ftenum type)
9231 DISSECTOR_ASSERT_NOT_REACHED();
9239 hfinfo_container_bitwidth(const header_field_info *hfinfo)
9241 if (!hfinfo->bitmask) {
9245 if (hfinfo->type == FT_BOOLEAN) {
9246 return hfinfo->display; /* hacky? :) */
9249 return hfinfo_type_bitwidth(hfinfo->type);
9253 hfinfo_hex_digits(const header_field_info *hfinfo)
9257 /* If we have a bitmask, hfinfo->type is the width of the container, so not
9258 * appropriate to determine the number of hex digits for the field.
9259 * So instead, we compute it from the bitmask.
9261 if (hfinfo->bitmask != 0) {
9262 bitwidth = hfinfo_mask_bitwidth(hfinfo);
9264 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
9267 /* Divide by 4, rounding up, to get number of hex digits. */
9268 return (bitwidth + 3) / 4;
9272 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
9274 char *ptr = &buf[6];
9275 static const gchar hex_digits[16] =
9276 { '0', '1', '2', '3', '4', '5', '6', '7',
9277 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
9281 /* Properly format value */
9282 if (g_ascii_isprint(value)) {
9284 * Printable, so just show the character, and, if it needs
9285 * to be escaped, escape it.
9288 if (value == '\\' || value == '\'')
9292 * Non-printable; show it as an escape sequence.
9298 * Show a NUL with only one digit.
9332 switch (FIELD_DISPLAY(display)) {
9335 *(--ptr) = (value & 0x7) + '0';
9337 *(--ptr) = (value & 0x7) + '0';
9339 *(--ptr) = (value & 0x7) + '0';
9343 *(--ptr) = hex_digits[value & 0x0F];
9345 *(--ptr) = hex_digits[value & 0x0F];
9350 g_assert_not_reached();
9360 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
9362 char *ptr = &buf[31];
9363 gboolean isint = IS_FT_INT(hfinfo->type);
9366 /* Properly format value */
9367 switch (FIELD_DISPLAY(display)) {
9369 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
9373 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9376 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
9380 return oct_to_str_back(ptr, value);
9383 return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9387 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
9390 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9397 port_with_resolution_to_str_buf(buf, 32,
9398 display_to_port_type((field_display_e)display), value);
9403 const gchar *manuf_name;
9405 p_oui[0] = value >> 16 & 0xFF;
9406 p_oui[1] = value >> 8 & 0xFF;
9407 p_oui[2] = value & 0xFF;
9409 /* Attempt an OUI lookup. */
9410 manuf_name = uint_get_manuf_name_if_known(value);
9411 if (manuf_name == NULL) {
9412 /* Could not find an OUI. */
9413 g_snprintf(buf, 32, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
9416 /* Found an address string. */
9417 g_snprintf(buf, 32, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
9423 g_assert_not_reached();
9429 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
9431 char *ptr = &buf[47];
9432 gboolean isint = IS_FT_INT(hfinfo->type);
9435 /* Properly format value */
9436 switch (FIELD_DISPLAY(display)) {
9438 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
9442 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9445 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
9449 return oct64_to_str_back(ptr, value);
9452 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9456 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
9459 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9463 g_assert_not_reached();
9470 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9472 int display = hfinfo->display;
9474 if (hfinfo->type == FT_FRAMENUM) {
9476 * Frame numbers are always displayed in decimal.
9481 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
9485 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
9487 int display = hfinfo->display;
9489 if (hfinfo->type == FT_FRAMENUM) {
9491 * Frame numbers are always displayed in decimal.
9496 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
9500 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9502 /* Get the underlying BASE_ value */
9503 int display = FIELD_DISPLAY(hfinfo->display);
9505 return hfinfo_char_value_format_display(display, buf, value);
9509 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9511 /* Get the underlying BASE_ value */
9512 int display = FIELD_DISPLAY(hfinfo->display);
9514 if (hfinfo->type == FT_FRAMENUM) {
9516 * Frame numbers are always displayed in decimal.
9521 if (IS_BASE_PORT(display)) {
9523 } else if (display == BASE_OUI) {
9529 /* case BASE_DEC: */
9531 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
9536 /* case BASE_HEX: */
9542 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
9546 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
9548 /* Get the underlying BASE_ value */
9549 int display = FIELD_DISPLAY(hfinfo->display);
9551 if (hfinfo->type == FT_FRAMENUM) {
9553 * Frame numbers are always displayed in decimal.
9560 /* case BASE_DEC: */
9562 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
9567 /* case BASE_HEX: */
9573 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
9577 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9579 /* Get the underlying BASE_ value */
9580 int display = FIELD_DISPLAY(hfinfo->display);
9582 return hfinfo_char_value_format_display(display, buf, value);
9586 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9588 /* Get the underlying BASE_ value */
9589 int display = FIELD_DISPLAY(hfinfo->display);
9591 if (display == BASE_NONE)
9594 if (display == BASE_DEC_HEX)
9596 if (display == BASE_HEX_DEC)
9599 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
9603 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
9605 /* Get the underlying BASE_ value */
9606 int display = FIELD_DISPLAY(hfinfo->display);
9608 if (display == BASE_NONE)
9611 if (display == BASE_DEC_HEX)
9613 if (display == BASE_HEX_DEC)
9616 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
9620 proto_registrar_get_name(const int n)
9622 header_field_info *hfinfo;
9624 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9625 return hfinfo->name;
9629 proto_registrar_get_abbrev(const int n)
9631 header_field_info *hfinfo;
9633 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9634 return hfinfo->abbrev;
9638 proto_registrar_get_ftype(const int n)
9640 header_field_info *hfinfo;
9642 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9643 return hfinfo->type;
9647 proto_registrar_get_parent(const int n)
9649 header_field_info *hfinfo;
9651 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9652 return hfinfo->parent;
9656 proto_registrar_is_protocol(const int n)
9658 header_field_info *hfinfo;
9660 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9661 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
9664 /* Returns length of field in packet (not necessarily the length
9665 * in our internal representation, as in the case of IPv4).
9666 * 0 means undeterminable at time of registration
9667 * -1 means the field is not registered. */
9669 proto_registrar_get_length(const int n)
9671 header_field_info *hfinfo;
9673 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9674 return ftype_length(hfinfo->type);
9677 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
9678 * it exists anywhere, or FALSE if it exists nowhere. */
9680 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
9682 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
9684 if (g_ptr_array_len(ptrs) > 0) {
9692 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
9693 * This only works if the hfindex was "primed" before the dissection
9694 * took place, as we just pass back the already-created GPtrArray*.
9695 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
9698 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
9703 if (PTREE_DATA(tree)->interesting_hfids != NULL)
9704 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
9705 GINT_TO_POINTER(id));
9711 proto_tracking_interesting_fields(const proto_tree *tree)
9713 GHashTable *interesting_hfids;
9718 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
9720 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
9723 /* Helper struct for proto_find_info() and proto_all_finfos() */
9729 /* Helper function for proto_find_info() */
9731 find_finfo(proto_node *node, gpointer data)
9733 field_info *fi = PNODE_FINFO(node);
9734 if (fi && fi->hfinfo) {
9735 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
9736 g_ptr_array_add(((ffdata_t*)data)->array, fi);
9740 /* Don't stop traversing. */
9744 /* Helper function for proto_find_first_info() */
9746 find_first_finfo(proto_node *node, gpointer data)
9748 field_info *fi = PNODE_FINFO(node);
9749 if (fi && fi->hfinfo) {
9750 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
9751 g_ptr_array_add(((ffdata_t*)data)->array, fi);
9753 /* Stop traversing. */
9758 /* Continue traversing. */
9762 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
9763 * This works on any proto_tree, primed or unprimed, but actually searches
9764 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
9765 * The caller does need to free the returned GPtrArray with
9766 * g_ptr_array_free(<array>, TRUE).
9769 proto_find_finfo(proto_tree *tree, const int id)
9773 ffdata.array = g_ptr_array_new();
9776 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
9778 return ffdata.array;
9781 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
9782 * This works on any proto_tree, primed or unprimed, but actually searches
9783 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
9784 * The caller does need to free the returned GPtrArray with
9785 * g_ptr_array_free(<array>, TRUE).
9788 proto_find_first_finfo(proto_tree *tree, const int id)
9792 ffdata.array = g_ptr_array_new();
9795 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
9797 return ffdata.array;
9800 /* Helper function for proto_all_finfos() */
9802 every_finfo(proto_node *node, gpointer data)
9804 field_info *fi = PNODE_FINFO(node);
9805 if (fi && fi->hfinfo) {
9806 g_ptr_array_add(((ffdata_t*)data)->array, fi);
9809 /* Don't stop traversing. */
9813 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
9815 proto_all_finfos(proto_tree *tree)
9819 /* Pre allocate enough space to hold all fields in most cases */
9820 ffdata.array = g_ptr_array_sized_new(512);
9823 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
9825 return ffdata.array;
9836 check_for_offset(proto_node *node, gpointer data)
9838 field_info *fi = PNODE_FINFO(node);
9839 offset_search_t *offsearch = (offset_search_t *)data;
9841 /* !fi == the top most container node which holds nothing */
9842 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
9843 if (offsearch->offset >= (guint) fi->start &&
9844 offsearch->offset < (guint) (fi->start + fi->length)) {
9846 offsearch->finfo = fi;
9847 return FALSE; /* keep traversing */
9850 return FALSE; /* keep traversing */
9853 /* Search a proto_tree backwards (from leaves to root) looking for the field
9854 * whose start/length occupies 'offset' */
9855 /* XXX - I couldn't find an easy way to search backwards, so I search
9856 * forwards, w/o stopping. Therefore, the last finfo I find will the be
9857 * the one I want to return to the user. This algorithm is inefficient
9858 * and could be re-done, but I'd have to handle all the children and
9859 * siblings of each node myself. When I have more time I'll do that.
9862 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
9864 offset_search_t offsearch;
9866 offsearch.offset = offset;
9867 offsearch.finfo = NULL;
9868 offsearch.tvb = tvb;
9870 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
9872 return offsearch.finfo;
9881 check_for_undecoded(proto_node *node, gpointer data)
9883 field_info *fi = PNODE_FINFO(node);
9884 decoded_data_t* decoded = (decoded_data_t*)data;
9889 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
9890 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
9893 decoded->buf[byte] |= (1 << bit);
9901 proto_find_undecoded_data(proto_tree *tree, guint length)
9903 decoded_data_t decoded;
9904 decoded.length = length;
9905 decoded.buf = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
9907 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
9911 /* Dumps the protocols in the registration database to stdout. An independent
9912 * program can take this output and format it into nice tables or HTML or
9915 * There is one record per line. The fields are tab-delimited.
9917 * Field 1 = protocol name
9918 * Field 2 = protocol short name
9919 * Field 3 = protocol filter name
9922 proto_registrar_dump_protocols(void)
9924 protocol_t *protocol;
9926 void *cookie = NULL;
9929 i = proto_get_first_protocol(&cookie);
9931 protocol = find_protocol_by_id(i);
9932 ws_debug_printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
9933 protocol->filter_name);
9934 i = proto_get_next_protocol(&cookie);
9938 /* Dumps the value_strings, extended value string headers, range_strings
9939 * or true/false strings for fields that have them.
9940 * There is one record per line. Fields are tab-delimited.
9941 * There are four types of records: Value String, Extended Value String Header,
9942 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
9943 * the type of record.
9945 * Note that a record will be generated only if the value_string,... is referenced
9946 * in a registered hfinfo entry.
9952 * Field 2 = Field abbreviation to which this value string corresponds
9953 * Field 3 = Integer value
9956 * Extended Value String Headers
9957 * -----------------------------
9959 * Field 2 = Field abbreviation to which this extended value string header corresponds
9960 * Field 3 = Extended Value String "Name"
9961 * Field 4 = Number of entries in the associated value_string array
9962 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
9967 * Field 2 = Field abbreviation to which this range string corresponds
9968 * Field 3 = Integer value: lower bound
9969 * Field 4 = Integer value: upper bound
9972 * True/False Strings
9973 * ------------------
9975 * Field 2 = Field abbreviation to which this true/false string corresponds
9976 * Field 3 = True String
9977 * Field 4 = False String
9980 proto_registrar_dump_values(void)
9982 header_field_info *hfinfo;
9984 const value_string *vals;
9985 const val64_string *vals64;
9986 const range_string *range;
9987 const true_false_string *tfs;
9988 const unit_name_string *units;
9990 len = gpa_hfinfo.len;
9991 for (i = 0; i < len ; i++) {
9992 if (gpa_hfinfo.hfi[i] == NULL)
9993 continue; /* This is a deregistered protocol or field */
9995 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
9997 if (hfinfo->id == hf_text_only) {
10001 /* ignore protocols */
10002 if (proto_registrar_is_protocol(i)) {
10005 /* process header fields */
10006 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
10008 * If this field isn't at the head of the list of
10009 * fields with this name, skip this field - all
10010 * fields with the same name are really just versions
10011 * of the same field stored in different bits, and
10012 * should have the same type/radix/value list, and
10013 * just differ in their bit masks. (If a field isn't
10014 * a bitfield, but can be, say, 1 or 2 bytes long,
10015 * it can just be made FT_UINT16, meaning the
10016 * *maximum* length is 2 bytes, and be used
10017 * for all lengths.)
10019 if (hfinfo->same_name_prev_id != -1)
10028 if (hfinfo->strings != NULL) {
10029 if (FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM &&
10030 (hfinfo->type == FT_CHAR ||
10031 hfinfo->type == FT_UINT8 ||
10032 hfinfo->type == FT_UINT16 ||
10033 hfinfo->type == FT_UINT24 ||
10034 hfinfo->type == FT_UINT32 ||
10035 hfinfo->type == FT_UINT40 ||
10036 hfinfo->type == FT_UINT48 ||
10037 hfinfo->type == FT_UINT56 ||
10038 hfinfo->type == FT_UINT64 ||
10039 hfinfo->type == FT_INT8 ||
10040 hfinfo->type == FT_INT16 ||
10041 hfinfo->type == FT_INT24 ||
10042 hfinfo->type == FT_INT32 ||
10043 hfinfo->type == FT_INT40 ||
10044 hfinfo->type == FT_INT48 ||
10045 hfinfo->type == FT_INT56 ||
10046 hfinfo->type == FT_INT64 ||
10047 hfinfo->type == FT_FLOAT ||
10048 hfinfo->type == FT_DOUBLE)) {
10050 if (hfinfo->display & BASE_RANGE_STRING) {
10051 range = (const range_string *)hfinfo->strings;
10052 } else if (hfinfo->display & BASE_EXT_STRING) {
10053 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
10054 } else if (hfinfo->display & BASE_VAL64_STRING) {
10055 vals64 = (const val64_string *)hfinfo->strings;
10056 } else if (hfinfo->display & BASE_UNIT_STRING) {
10057 units = (const unit_name_string *)hfinfo->strings;
10059 vals = (const value_string *)hfinfo->strings;
10062 else if (hfinfo->type == FT_BOOLEAN) {
10063 tfs = (const struct true_false_string *)hfinfo->strings;
10067 /* Print value strings? */
10069 if (hfinfo->display & BASE_EXT_STRING) {
10070 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
10071 if (!value_string_ext_validate(vse_p)) {
10072 ws_g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
10075 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
10076 ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
10078 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
10079 VALUE_STRING_EXT_VS_NAME(vse_p),
10080 value_string_ext_match_type_str(vse_p));
10083 while (vals[vi].strptr) {
10084 /* Print in the proper base */
10085 if (hfinfo->type == FT_CHAR) {
10086 if (g_ascii_isprint(vals[vi].value)) {
10087 ws_debug_printf("V\t%s\t'%c'\t%s\n",
10092 if (hfinfo->display == BASE_HEX) {
10093 ws_debug_printf("V\t%s\t'\\x%02x'\t%s\n",
10099 ws_debug_printf("V\t%s\t'\\%03o'\t%s\n",
10106 if (hfinfo->display == BASE_HEX) {
10107 ws_debug_printf("V\t%s\t0x%x\t%s\n",
10113 ws_debug_printf("V\t%s\t%u\t%s\n",
10124 while (vals64[vi].strptr) {
10125 ws_debug_printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
10128 vals64[vi].strptr);
10133 /* print range strings? */
10136 while (range[vi].strptr) {
10137 /* Print in the proper base */
10138 if (FIELD_DISPLAY(hfinfo->display) == BASE_HEX) {
10139 ws_debug_printf("R\t%s\t0x%x\t0x%x\t%s\n",
10141 range[vi].value_min,
10142 range[vi].value_max,
10146 ws_debug_printf("R\t%s\t%u\t%u\t%s\n",
10148 range[vi].value_min,
10149 range[vi].value_max,
10156 /* Print true/false strings? */
10158 ws_debug_printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
10159 tfs->true_string, tfs->false_string);
10161 /* Print unit strings? */
10163 ws_debug_printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
10164 units->singular, units->plural ? units->plural : "(no plural)");
10169 /* Prints the number of registered fields.
10170 * Useful for determining an appropriate value for
10171 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
10173 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
10174 * the number of fields, TRUE otherwise.
10177 proto_registrar_dump_fieldcount(void)
10180 header_field_info *hfinfo;
10181 guint32 deregistered_count = 0;
10182 guint32 same_name_count = 0;
10183 guint32 protocol_count = 0;
10185 for (i = 0; i < gpa_hfinfo.len; i++) {
10186 if (gpa_hfinfo.hfi[i] == NULL) {
10187 deregistered_count++;
10188 continue; /* This is a deregistered protocol or header field */
10191 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10193 if (proto_registrar_is_protocol(i))
10196 if (hfinfo->same_name_prev_id != -1)
10200 ws_debug_printf("There are %u header fields registered, of which:\n"
10201 "\t%u are deregistered\n"
10202 "\t%u are protocols\n"
10203 "\t%u have the same name as another field\n\n",
10204 gpa_hfinfo.len, deregistered_count, protocol_count,
10207 ws_debug_printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
10208 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
10209 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
10212 ws_debug_printf("The header field table consumes %u KiB of memory.\n",
10213 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
10214 ws_debug_printf("The fields themselves consume %u KiB of memory.\n",
10215 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
10217 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
10220 #ifdef HAVE_JSONGLIB
10222 static JsonBuilder*
10223 elastic_add_base_mapping(JsonBuilder* builder)
10225 json_builder_set_member_name(builder, "template");
10226 json_builder_add_string_value(builder, "packets-*");
10228 json_builder_set_member_name(builder, "settings");
10229 json_builder_begin_object(builder);
10230 json_builder_set_member_name(builder, "index.mapping.total_fields.limit");
10231 json_builder_add_int_value(builder, 1000000);
10232 json_builder_end_object(builder);
10237 gchar* ws_type_to_elastic(guint type _U_)
10264 case FT_ABSOLUTE_TIME:
10265 case FT_RELATIVE_TIME:
10268 case FT_UINT_BYTES:
10278 case FT_UINT_STRING:
10282 case FT_IEEE_11073_SFLOAT:
10283 case FT_IEEE_11073_FLOAT:
10284 case FT_STRINGZPAD:
10293 DISSECTOR_ASSERT_NOT_REACHED();
10298 dot_to_underscore(gchar* str)
10301 for (i = 0; i < strlen(str); i++) {
10308 /* Dumps a mapping file for ElasticSearch
10311 proto_registrar_dump_elastic(const gchar* filter)
10313 header_field_info *hfinfo;
10314 header_field_info *parent_hfinfo;
10315 JsonGenerator* generator;
10316 JsonBuilder* builder;
10320 gboolean open_object = TRUE;
10321 const char* prev_proto = NULL;
10324 gchar** protos = NULL;
10329 /* We have filtering protocols. Extract them. */
10331 protos = g_strsplit(filter, ",", -1);
10335 * To help tracking down the json tree, objects have been appended with a comment:
10336 * n.label -> where n is the indentation level and label the name of the object
10339 builder = json_builder_new();
10340 json_builder_begin_object(builder); // 1.root
10341 builder = elastic_add_base_mapping(builder);
10343 json_builder_set_member_name(builder, "mappings");
10344 json_builder_begin_object(builder); // 2.mappings
10345 json_builder_set_member_name(builder, "pcap_file");
10347 json_builder_begin_object(builder); // 3.pcap_file
10348 json_builder_set_member_name(builder, "dynamic");
10349 json_builder_add_boolean_value(builder, FALSE);
10351 json_builder_set_member_name(builder, "properties");
10352 json_builder_begin_object(builder); // 4.properties
10353 json_builder_set_member_name(builder, "timestamp");
10354 json_builder_begin_object(builder); // 5.timestamp
10355 json_builder_set_member_name(builder, "type");
10356 json_builder_add_string_value(builder, "date");
10357 json_builder_end_object(builder); // 5.timestamp
10359 json_builder_set_member_name(builder, "layers");
10360 json_builder_begin_object(builder); // 5.layers
10361 json_builder_set_member_name(builder, "properties");
10362 json_builder_begin_object(builder); // 6.properties
10364 for (i = 0; i < gpa_hfinfo.len; i++) {
10365 if (gpa_hfinfo.hfi[i] == NULL)
10366 continue; /* This is a deregistered protocol or header field */
10368 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10371 * Skip the pseudo-field for "proto_tree_add_text()" since
10372 * we don't want it in the list of filterable protocols.
10374 if (hfinfo->id == hf_text_only)
10377 if (!proto_registrar_is_protocol(i)) {
10378 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
10381 * Skip the field if filter protocols have been set and this one's
10382 * parent is not listed.
10389 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
10400 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
10401 json_builder_end_object(builder); // 8.properties
10402 json_builder_end_object(builder); // 7.parent_hfinfo->abbrev
10403 open_object = TRUE;
10406 prev_proto = parent_hfinfo->abbrev;
10409 json_builder_set_member_name(builder, parent_hfinfo->abbrev);
10410 json_builder_begin_object(builder); // 7.parent_hfinfo->abbrev
10411 json_builder_set_member_name(builder, "properties");
10412 json_builder_begin_object(builder); // 8.properties
10413 open_object = FALSE;
10415 str = g_strdup(hfinfo->abbrev);
10416 json_builder_set_member_name(builder, dot_to_underscore(str));
10418 json_builder_begin_object(builder); // 9.hfinfo->abbrev
10419 json_builder_set_member_name(builder, "type");
10420 json_builder_add_string_value(builder, ws_type_to_elastic(hfinfo->type));
10421 json_builder_end_object(builder); // 9.hfinfo->abbrev
10426 json_builder_end_object(builder); // 8.properties
10427 json_builder_end_object(builder); // 7.parent_hfinfo->abbrev
10430 json_builder_end_object(builder); // 6.properties
10431 json_builder_end_object(builder); // 5.layers
10432 json_builder_end_object(builder); // 4.properties
10433 json_builder_end_object(builder); // 3.pcap_file
10434 json_builder_end_object(builder); // 2.mappings
10435 DISSECTOR_ASSERT(json_builder_end_object(builder)); // 1.root
10437 generator = json_generator_new();
10438 json_generator_set_pretty(generator, TRUE);
10439 root = json_builder_get_root(builder);
10440 json_generator_set_root(generator, root);
10441 json_node_free(root);
10442 g_object_unref(builder);
10443 data = json_generator_to_data(generator, &length);
10444 g_object_unref(generator);
10445 ws_debug_printf("%s\n", data);
10447 g_strfreev(protos);
10451 /* Dumps the contents of the registration database to stdout. An independent
10452 * program can take this output and format it into nice tables or HTML or
10455 * There is one record per line. Each record is either a protocol or a header
10456 * field, differentiated by the first field. The fields are tab-delimited.
10461 * Field 2 = descriptive protocol name
10462 * Field 3 = protocol abbreviation
10467 * Field 2 = descriptive field name
10468 * Field 3 = field abbreviation
10469 * Field 4 = type ( textual representation of the the ftenum type )
10470 * Field 5 = parent protocol abbreviation
10471 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
10472 * Field 7 = bitmask: format: hex: 0x....
10473 * Field 8 = blurb describing field
10476 proto_registrar_dump_fields(void)
10478 header_field_info *hfinfo, *parent_hfinfo;
10480 const char *enum_name;
10481 const char *base_name;
10485 len = gpa_hfinfo.len;
10486 for (i = 0; i < len ; i++) {
10487 if (gpa_hfinfo.hfi[i] == NULL)
10488 continue; /* This is a deregistered protocol or header field */
10490 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10493 * Skip the pseudo-field for "proto_tree_add_text()" since
10494 * we don't want it in the list of filterable fields.
10496 if (hfinfo->id == hf_text_only)
10499 /* format for protocols */
10500 if (proto_registrar_is_protocol(i)) {
10501 ws_debug_printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
10503 /* format for header fields */
10506 * If this field isn't at the head of the list of
10507 * fields with this name, skip this field - all
10508 * fields with the same name are really just versions
10509 * of the same field stored in different bits, and
10510 * should have the same type/radix/value list, and
10511 * just differ in their bit masks. (If a field isn't
10512 * a bitfield, but can be, say, 1 or 2 bytes long,
10513 * it can just be made FT_UINT16, meaning the
10514 * *maximum* length is 2 bytes, and be used
10515 * for all lengths.)
10517 if (hfinfo->same_name_prev_id != -1)
10520 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
10522 enum_name = ftype_name(hfinfo->type);
10525 if (hfinfo->type == FT_CHAR ||
10526 hfinfo->type == FT_UINT8 ||
10527 hfinfo->type == FT_UINT16 ||
10528 hfinfo->type == FT_UINT24 ||
10529 hfinfo->type == FT_UINT32 ||
10530 hfinfo->type == FT_UINT40 ||
10531 hfinfo->type == FT_UINT48 ||
10532 hfinfo->type == FT_UINT56 ||
10533 hfinfo->type == FT_UINT64 ||
10534 hfinfo->type == FT_INT8 ||
10535 hfinfo->type == FT_INT16 ||
10536 hfinfo->type == FT_INT24 ||
10537 hfinfo->type == FT_INT32 ||
10538 hfinfo->type == FT_INT40 ||
10539 hfinfo->type == FT_INT48 ||
10540 hfinfo->type == FT_INT56 ||
10541 hfinfo->type == FT_INT64) {
10543 switch (FIELD_DISPLAY(hfinfo->display)) {
10556 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
10559 base_name = "????";
10562 } else if (hfinfo->type == FT_BOOLEAN) {
10563 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
10564 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
10568 blurb = hfinfo->blurb;
10571 else if (strlen(blurb) == 0)
10574 ws_debug_printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
10575 hfinfo->name, hfinfo->abbrev, enum_name,
10576 parent_hfinfo->abbrev, base_name,
10577 hfinfo->bitmask, blurb);
10582 /* Dumps field types and descriptive names to stdout. An independent
10583 * program can take this output and format it into nice tables or HTML or
10586 * There is one record per line. The fields are tab-delimited.
10588 * Field 1 = field type name, e.g. FT_UINT8
10589 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
10592 proto_registrar_dump_ftypes(void)
10596 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
10597 ws_debug_printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
10601 /* This function indicates whether it's possible to construct a
10602 * "match selected" display filter string for the specified field,
10603 * returns an indication of whether it's possible, and, if it's
10604 * possible and "filter" is non-null, constructs the filter and
10605 * sets "*filter" to point to it.
10606 * You do not need to [g_]free() this string since it will be automatically
10607 * freed once the next packet is dissected.
10610 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
10613 header_field_info *hfinfo;
10617 int dfilter_len, i;
10618 gint start, length, length_remaining;
10620 gchar is_signed_num = FALSE;
10625 hfinfo = finfo->hfinfo;
10626 DISSECTOR_ASSERT(hfinfo);
10627 abbrev_len = (int) strlen(hfinfo->abbrev);
10629 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
10630 const gchar *str = NULL;
10632 switch (hfinfo->type) {
10638 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
10646 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
10653 if (str != NULL && filter != NULL) {
10654 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
10660 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
10661 * functions for FT_UINT and FT_INT types, as we choose the base in
10662 * the string expression based on the display base of the field.
10664 * Note that the base does matter, as this is also used for
10665 * the protocolinfo tap.
10667 * It might be nice to use them in "proto_item_fill_label()"
10668 * as well, although, there, you'd have to deal with the base
10669 * *and* with resolved values for addresses.
10671 * Perhaps we need two different val_to_string routines, one
10672 * to generate items for display filters and one to generate
10673 * strings for display, and pass to both of them the
10674 * "display" and "strings" values in the header_field_info
10675 * structure for the field, so they can get the base and,
10676 * if the field is Boolean or an enumerated integer type,
10677 * the tables used to generate human-readable values.
10679 switch (hfinfo->type) {
10682 if (filter != NULL) {
10688 number = fvalue_get_uinteger(&finfo->value);
10690 out = hfinfo_char_value_format(hfinfo, buf, number);
10692 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
10700 is_signed_num = TRUE;
10707 if (filter != NULL) {
10714 number = fvalue_get_sinteger(&finfo->value);
10716 number = fvalue_get_uinteger(&finfo->value);
10718 out = hfinfo_numeric_value_format(hfinfo, buf, number);
10720 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
10728 is_signed_num = TRUE;
10734 if (filter != NULL) {
10741 number = fvalue_get_sinteger64(&finfo->value);
10743 number = fvalue_get_uinteger64(&finfo->value);
10745 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
10747 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
10752 if (filter != NULL)
10753 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
10758 * If the length is 0, just match the name of the
10761 * (Also check for negative values, just in case,
10762 * as we'll cast it to an unsigned value later.)
10764 length = finfo->length;
10766 if (filter != NULL)
10767 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
10774 * This doesn't have a value, so we'd match
10775 * on the raw bytes at this address.
10777 * Should we be allowed to access to the raw bytes?
10778 * If "edt" is NULL, the answer is "no".
10784 * Is this field part of the raw frame tvbuff?
10785 * If not, we can't use "frame[N:M]" to match
10788 * XXX - should this be frame-relative, or
10789 * protocol-relative?
10791 * XXX - does this fallback for non-registered
10792 * fields even make sense?
10794 if (finfo->ds_tvb != edt->tvb)
10795 return FALSE; /* you lose */
10798 * Don't go past the end of that tvbuff.
10800 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
10801 if (length > length_remaining)
10802 length = length_remaining;
10806 if (filter != NULL) {
10807 start = finfo->start;
10808 buf_len = 32 + length * 3;
10809 *filter = (char *)wmem_alloc0(NULL, buf_len);
10812 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
10813 "frame[%d:%d] == ", finfo->start, length);
10814 for (i=0; i<length; i++) {
10815 c = tvb_get_guint8(finfo->ds_tvb, start);
10818 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
10821 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
10828 /* FT_PCRE never appears as a type for a registered field. It is
10829 * only used internally. */
10830 DISSECTOR_ASSERT_NOT_REACHED();
10833 /* By default, use the fvalue's "to_string_repr" method. */
10835 /* Figure out the string length needed.
10836 * The ft_repr length.
10837 * 4 bytes for " == ".
10838 * 1 byte for trailing NUL.
10840 if (filter != NULL) {
10842 dfilter_len = fvalue_string_repr_len(&finfo->value,
10843 FTREPR_DFILTER, finfo->hfinfo->display);
10844 dfilter_len += abbrev_len + 4 + 1;
10845 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
10847 /* Create the string */
10848 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
10849 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
10850 wmem_free(NULL, str);
10859 * Returns TRUE if we can do a "match selected" on the field, FALSE
10863 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
10865 return construct_match_selected_string(finfo, edt, NULL);
10868 /* This function attempts to construct a "match selected" display filter
10869 * string for the specified field; if it can do so, it returns a pointer
10870 * to the string, otherwise it returns NULL.
10872 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
10875 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
10877 char *filter = NULL;
10879 if (!construct_match_selected_string(finfo, edt, &filter))
10881 wmem_free(NULL, filter);
10887 /* This function is common code for all proto_tree_add_bitmask... functions.
10891 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
10892 const int len, const gint ett, const int **fields,
10893 const int flags, gboolean first,
10894 gboolean use_parent_tree,
10895 proto_tree* tree, guint64 value)
10898 guint64 available_bits = 0;
10900 header_field_info *hf;
10904 if (len < 0 || len > 8)
10905 g_assert_not_reached();
10906 bitshift = (8 - (guint)len)*8;
10907 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
10909 if (use_parent_tree == FALSE)
10910 tree = proto_item_add_subtree(item, ett);
10913 guint64 present_bits;
10914 PROTO_REGISTRAR_GET_NTH(**fields,hf);
10915 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
10917 /* Skip fields that aren't fully present */
10918 present_bits = available_bits & hf->bitmask;
10919 if (present_bits != hf->bitmask) {
10924 switch (hf->type) {
10930 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
10937 proto_tree_add_int(tree, **fields, tvb, offset, len, (gint32)value);
10944 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
10951 proto_tree_add_int64(tree, **fields, tvb, offset, len, (gint64)value);
10955 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
10959 DISSECTOR_ASSERT_NOT_REACHED();
10962 if (flags & BMT_NO_APPEND) {
10966 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
10968 switch (hf->type) {
10970 if (hf->display == BASE_CUSTOM) {
10971 gchar lbl[ITEM_LABEL_LENGTH];
10972 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
10974 DISSECTOR_ASSERT(fmtfunc);
10975 fmtfunc(lbl, (guint32) tmpval);
10976 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10980 else if (hf->strings) {
10981 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10982 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
10985 else if (!(flags & BMT_NO_INT)) {
10990 proto_item_append_text(item, ", ");
10993 out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
10994 proto_item_append_text(item, "%s: %s", hf->name, out);
11004 if (hf->display == BASE_CUSTOM) {
11005 gchar lbl[ITEM_LABEL_LENGTH];
11006 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11008 DISSECTOR_ASSERT(fmtfunc);
11009 fmtfunc(lbl, (guint32) tmpval);
11010 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11014 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11015 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11016 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
11019 else if (!(flags & BMT_NO_INT)) {
11024 proto_item_append_text(item, ", ");
11027 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
11028 if (hf->display & BASE_UNIT_STRING) {
11029 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
11031 proto_item_append_text(item, "%s: %s", hf->name, out);
11042 integer32 = (guint32) tmpval;
11044 no_of_bits = ws_count_ones(hf->bitmask);
11045 integer32 = ws_sign_ext32(integer32, no_of_bits);
11047 if (hf->display == BASE_CUSTOM) {
11048 gchar lbl[ITEM_LABEL_LENGTH];
11049 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11051 DISSECTOR_ASSERT(fmtfunc);
11052 fmtfunc(lbl, (gint32) integer32);
11053 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11057 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11058 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11059 hf->name, hf_try_val_to_str_const((gint32) integer32, hf, "Unknown"));
11062 else if (!(flags & BMT_NO_INT)) {
11067 proto_item_append_text(item, ", ");
11070 out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
11071 if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11072 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
11074 proto_item_append_text(item, "%s: %s", hf->name, out);
11085 if (hf->display == BASE_CUSTOM) {
11086 gchar lbl[ITEM_LABEL_LENGTH];
11087 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
11089 DISSECTOR_ASSERT(fmtfunc);
11090 fmtfunc(lbl, tmpval);
11091 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11095 else if (hf->strings) {
11096 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11097 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
11100 else if (!(flags & BMT_NO_INT)) {
11105 proto_item_append_text(item, ", ");
11108 out = hfinfo_number_value_format64(hf, buf, tmpval);
11109 proto_item_append_text(item, "%s: %s", hf->name, out);
11120 no_of_bits = ws_count_ones(hf->bitmask);
11121 tmpval = ws_sign_ext64(tmpval, no_of_bits);
11123 if (hf->display == BASE_CUSTOM) {
11124 gchar lbl[ITEM_LABEL_LENGTH];
11125 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
11127 DISSECTOR_ASSERT(fmtfunc);
11128 fmtfunc(lbl, (gint64) tmpval);
11129 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11133 else if (hf->strings) {
11134 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11135 hf->name, hf_try_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
11138 else if (!(flags & BMT_NO_INT)) {
11143 proto_item_append_text(item, ", ");
11146 out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
11147 proto_item_append_text(item, "%s: %s", hf->name, out);
11154 if (hf->strings && !(flags & BMT_NO_TFS)) {
11155 /* If we have true/false strings, emit full - otherwise messages
11156 might look weird */
11157 const struct true_false_string *tfs =
11158 (const struct true_false_string *)hf->strings;
11161 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11162 hf->name, tfs->true_string);
11164 } else if (!(flags & BMT_NO_FALSE)) {
11165 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11166 hf->name, tfs->false_string);
11169 } else if (hf->bitmask & value) {
11170 /* If the flag is set, show the name */
11171 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
11176 DISSECTOR_ASSERT_NOT_REACHED();
11186 /* This function will dissect a sequence of bytes that describe a
11187 * bitmask and supply the value of that sequence through a pointer.
11188 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
11190 * This field will form an expansion under which the individual fields of the
11191 * bitmask is dissected and displayed.
11192 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
11194 * fields is an array of pointers to int that lists all the fields of the
11195 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
11196 * or another integer of the same type/size as hf_hdr with a mask specified.
11197 * This array is terminated by a NULL entry.
11199 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
11200 * FT_integer fields that have a value_string attached will have the
11201 * matched string displayed on the expansion line.
11204 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
11205 const guint offset, const int hf_hdr,
11206 const gint ett, const int **fields,
11207 const guint encoding, guint64 *retval)
11209 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);
11212 /* This function will dissect a sequence of bytes that describe a
11214 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
11216 * This field will form an expansion under which the individual fields of the
11217 * bitmask is dissected and displayed.
11218 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
11220 * fields is an array of pointers to int that lists all the fields of the
11221 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
11222 * or another integer of the same type/size as hf_hdr with a mask specified.
11223 * This array is terminated by a NULL entry.
11225 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
11226 * FT_integer fields that have a value_string attached will have the
11227 * matched string displayed on the expansion line.
11230 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
11231 const guint offset, const int hf_hdr,
11232 const gint ett, const int **fields,
11233 const guint encoding)
11235 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
11238 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
11239 * what data is appended to the header.
11242 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11243 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
11246 proto_item *item = NULL;
11247 header_field_info *hf;
11251 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
11252 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
11253 len = ftype_length(hf->type);
11254 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
11257 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
11258 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
11259 flags, FALSE, FALSE, NULL, value);
11264 /* Mask out irrelevant portions */
11265 *retval &= hf->bitmask;
11267 *retval >>= hfinfo_bitshift(hf);
11273 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
11274 * what data is appended to the header.
11277 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11278 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
11280 proto_item *item = NULL;
11281 header_field_info *hf;
11285 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
11286 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
11289 len = ftype_length(hf->type);
11290 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
11291 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
11292 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
11293 flags, FALSE, FALSE, NULL, value);
11299 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
11300 can't be retrieved directly from tvb) */
11302 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11303 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
11305 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
11306 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
11309 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
11310 WS_DLL_PUBLIC proto_item *
11311 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11312 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
11314 proto_item *item = NULL;
11315 header_field_info *hf;
11318 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
11319 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
11320 /* the proto_tree_add_uint/_uint64() calls below
11321 will fail if tvb==NULL and len!=0 */
11322 len = tvb ? ftype_length(hf->type) : 0;
11326 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
11328 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
11330 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
11331 flags, FALSE, FALSE, NULL, value);
11337 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
11339 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
11340 const int len, const int **fields, const guint encoding)
11345 value = get_uint64_value(tree, tvb, offset, len, encoding);
11346 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
11347 BMT_NO_APPEND, FALSE, TRUE, tree, value);
11352 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
11353 const int len, const int **fields, const guint64 value)
11356 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
11357 BMT_NO_APPEND, FALSE, TRUE, tree, value);
11362 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
11363 * This is intended to support bitmask fields whose lengths can vary, perhaps
11364 * as the underlying standard evolves over time.
11365 * With this API there is the possibility of being called to display more or
11366 * less data than the dissector was coded to support.
11367 * In such cases, it is assumed that bitmasks are extended on the MSb end.
11368 * Thus when presented with "too much" or "too little" data, MSbits will be
11369 * ignored or MSfields sacrificed.
11371 * Only fields for which all defined bits are available are displayed.
11374 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
11375 const guint offset, const guint len, const int hf_hdr,
11376 const gint ett, const int **fields, struct expert_field* exp,
11377 const guint encoding)
11379 proto_item *item = NULL;
11380 header_field_info *hf;
11381 guint decodable_len;
11382 guint decodable_offset;
11383 guint32 decodable_value;
11386 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
11387 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
11389 decodable_offset = offset;
11390 decodable_len = MIN(len, (guint) ftype_length(hf->type));
11392 /* If we are ftype_length-limited,
11393 * make sure we decode as many LSBs as possible.
11395 if (encoding == ENC_BIG_ENDIAN) {
11396 decodable_offset += (len - decodable_len);
11400 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
11401 decodable_len, encoding);
11403 /* The root item covers all the bytes even if we can't decode them all */
11404 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
11408 if (decodable_len < len) {
11409 /* Dissector likely requires updating for new protocol revision */
11410 expert_add_info_format(NULL, item, exp,
11411 "Only least-significant %d of %d bytes decoded",
11412 decodable_len, len);
11416 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
11417 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
11418 ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
11424 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
11426 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
11427 const guint offset, const guint len,
11428 const char *name, const char *fallback,
11429 const gint ett, const int **fields,
11430 const guint encoding, const int flags)
11432 proto_item *item = NULL;
11436 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
11437 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
11438 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
11439 flags, TRUE, FALSE, NULL, value) && fallback) {
11440 /* Still at first item - append 'fallback' text if any */
11441 proto_item_append_text(item, "%s", fallback);
11449 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11450 const guint bit_offset, const gint no_of_bits,
11451 const guint encoding)
11453 header_field_info *hfinfo;
11457 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
11459 octet_length = (no_of_bits + 7) >> 3;
11460 octet_offset = bit_offset >> 3;
11461 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
11463 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
11464 * but only after doing a bunch more work (which we can, in the common
11465 * case, shortcut here).
11467 CHECK_FOR_NULL_TREE(tree);
11468 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
11470 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
11474 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
11475 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
11476 * Offset should be given in bits from the start of the tvb.
11479 static proto_item *
11480 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11481 const guint bit_offset, const gint no_of_bits,
11482 guint64 *return_value, const guint encoding)
11486 guint8 tot_no_bits;
11488 char lbl_str[ITEM_LABEL_LENGTH];
11492 header_field_info *hf_field;
11494 const true_false_string *tfstring;
11496 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
11497 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
11499 if (hf_field->bitmask != 0) {
11500 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_ret_val"
11501 " with field '%s' (%s) with bitmask != 0",
11502 hf_field->abbrev, hf_field->name);
11505 DISSECTOR_ASSERT(no_of_bits > 0);
11507 /* Byte align offset */
11508 offset = bit_offset>>3;
11511 * Calculate the number of octets used to hold the bits
11513 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
11514 length = (tot_no_bits + 7) >> 3;
11516 if (no_of_bits < 65) {
11517 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
11519 DISSECTOR_ASSERT_NOT_REACHED();
11523 /* Sign extend for signed types */
11524 switch (hf_field->type) {
11533 value = ws_sign_ext64(value, no_of_bits);
11540 if (return_value) {
11541 *return_value = value;
11544 /* Coast clear. Try and fake it */
11545 CHECK_FOR_NULL_TREE(tree);
11546 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11548 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
11550 switch (hf_field->type) {
11552 /* Boolean field */
11553 tfstring = (const true_false_string *) &tfs_true_false;
11554 if (hf_field->strings)
11555 tfstring = (const true_false_string *)hf_field->strings;
11556 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
11558 bf_str, hf_field->name,
11559 (guint64)value ? tfstring->true_string : tfstring->false_string);
11563 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
11564 fill_label_char(PITEM_FINFO(pi), lbl_str);
11571 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
11572 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
11579 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
11580 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
11587 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
11588 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
11595 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
11596 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
11600 DISSECTOR_ASSERT_NOT_REACHED();
11605 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
11610 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11611 const guint bit_offset, const crumb_spec_t *crumb_spec,
11612 guint64 *return_value)
11617 guint mask_initial_bit_offset;
11618 guint mask_greatest_bit_offset;
11619 guint octet_length;
11622 char lbl_str[ITEM_LABEL_LENGTH];
11624 guint64 composite_bitmask;
11625 guint64 composite_bitmap;
11627 header_field_info *hf_field;
11628 const true_false_string *tfstring;
11630 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
11631 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
11633 if (hf_field->bitmask != 0) {
11634 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_split_bits_item_ret_val"
11635 " with field '%s' (%s) with bitmask != 0",
11636 hf_field->abbrev, hf_field->name);
11639 mask_initial_bit_offset = bit_offset % 8;
11644 mask_greatest_bit_offset = 0;
11645 composite_bitmask = 0;
11646 composite_bitmap = 0;
11648 while (crumb_spec[i].crumb_bit_length != 0) {
11649 guint64 crumb_mask, crumb_value;
11650 guint8 crumb_end_bit_offset;
11652 crumb_value = tvb_get_bits64(tvb,
11653 bit_offset + crumb_spec[i].crumb_bit_offset,
11654 crumb_spec[i].crumb_bit_length,
11656 value += crumb_value;
11657 no_of_bits += crumb_spec[i].crumb_bit_length;
11658 DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "a value larger than 64 bits cannot be represented");
11660 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
11661 octet containing the initial offset.
11662 If the mask is beyond 32 bits, then give up on bit map display.
11663 This could be improved in future, probably showing a table
11664 of 32 or 64 bits per row */
11665 if (mask_greatest_bit_offset < 32) {
11666 crumb_end_bit_offset = mask_initial_bit_offset
11667 + crumb_spec[i].crumb_bit_offset
11668 + crumb_spec[i].crumb_bit_length;
11669 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
11671 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
11672 mask_greatest_bit_offset = crumb_end_bit_offset;
11674 /* Currently the bitmap of the crumbs are only shown if
11675 * smaller than 32 bits. Do not bother calculating the
11676 * mask if it is larger than that. */
11677 if (crumb_end_bit_offset <= 32) {
11678 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
11679 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
11682 /* Shift left for the next segment */
11683 value <<= crumb_spec[++i].crumb_bit_length;
11686 /* Sign extend for signed types */
11687 switch (hf_field->type) {
11696 value = ws_sign_ext64(value, no_of_bits);
11702 if (return_value) {
11703 *return_value = value;
11706 /* Coast clear. Try and fake it */
11707 CHECK_FOR_NULL_TREE(tree);
11708 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11710 /* initialise the format string */
11713 octet_offset = bit_offset >> 3;
11715 /* Round up mask length to nearest octet */
11716 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
11717 mask_greatest_bit_offset = octet_length << 3;
11719 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
11720 It would be a useful enhancement to eliminate this restriction. */
11721 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
11722 other_decode_bitfield_value(bf_str,
11723 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
11724 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
11725 mask_greatest_bit_offset);
11727 /* If the bitmask is too large, try to describe its contents. */
11728 g_snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
11731 switch (hf_field->type) {
11732 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
11733 /* Boolean field */
11734 tfstring = (const true_false_string *) &tfs_true_false;
11735 if (hf_field->strings)
11736 tfstring = (const true_false_string *) hf_field->strings;
11737 return proto_tree_add_boolean_format(tree, hfindex,
11738 tvb, octet_offset, octet_length, (guint32)value,
11740 bf_str, hf_field->name,
11741 (guint64)value ? tfstring->true_string : tfstring->false_string);
11745 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
11746 fill_label_char(PITEM_FINFO(pi), lbl_str);
11753 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
11754 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
11761 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
11762 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
11769 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
11770 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
11777 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
11778 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
11782 DISSECTOR_ASSERT_NOT_REACHED();
11786 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
11791 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
11792 const crumb_spec_t *crumb_spec, guint16 crumb_index)
11794 header_field_info *hfinfo;
11796 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
11797 proto_tree_add_text_internal(tree, tvb,
11799 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
11800 "%s crumb %d of %s (decoded above)",
11801 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
11804 crumb_spec[crumb_index].crumb_bit_length,
11811 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11812 const guint bit_offset, const gint no_of_bits,
11813 guint64 *return_value, const guint encoding)
11817 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
11818 bit_offset, no_of_bits,
11819 return_value, encoding))) {
11820 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
11821 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
11826 static proto_item *
11827 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
11828 tvbuff_t *tvb, const guint bit_offset,
11829 const gint no_of_bits, void *value_ptr,
11834 guint8 tot_no_bits;
11837 header_field_info *hf_field;
11839 /* We do not have to return a value, try to fake it as soon as possible */
11840 CHECK_FOR_NULL_TREE(tree);
11841 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11843 if (hf_field->bitmask != 0) {
11844 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_format_value"
11845 " with field '%s' (%s) with bitmask != 0",
11846 hf_field->abbrev, hf_field->name);
11849 DISSECTOR_ASSERT(no_of_bits > 0);
11851 /* Byte align offset */
11852 offset = bit_offset>>3;
11855 * Calculate the number of octets used to hold the bits
11857 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
11858 length = tot_no_bits>>3;
11859 /* If we are using part of the next octet, increase length by 1 */
11860 if (tot_no_bits & 0x07)
11863 if (no_of_bits < 65) {
11864 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
11866 DISSECTOR_ASSERT_NOT_REACHED();
11870 str = decode_bits_in_field(bit_offset, no_of_bits, value);
11872 g_strlcat(str, " = ", 256+64);
11873 g_strlcat(str, hf_field->name, 256+64);
11876 * This function does not receive an actual value but a dimensionless pointer to that value.
11877 * For this reason, the type of the header field is examined in order to determine
11878 * what kind of value we should read from this address.
11879 * The caller of this function must make sure that for the specific header field type the address of
11880 * a compatible value is provided.
11882 switch (hf_field->type) {
11884 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
11885 "%s: %s", str, value_str);
11893 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
11894 "%s: %s", str, value_str);
11901 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
11902 "%s: %s", str, value_str);
11909 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
11910 "%s: %s", str, value_str);
11917 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
11918 "%s: %s", str, value_str);
11922 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
11923 "%s: %s", str, value_str);
11927 DISSECTOR_ASSERT_NOT_REACHED();
11933 static proto_item *
11934 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
11935 tvbuff_t *tvb, const guint bit_offset,
11936 const gint no_of_bits, void *value_ptr,
11941 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
11942 tvb, bit_offset, no_of_bits,
11943 value_ptr, value_str))) {
11944 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
11945 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
11950 #define CREATE_VALUE_STRING(dst,format,ap) \
11951 va_start(ap, format); \
11952 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
11956 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
11957 tvbuff_t *tvb, const guint bit_offset,
11958 const gint no_of_bits, guint32 value,
11959 const char *format, ...)
11963 header_field_info *hf_field;
11965 CHECK_FOR_NULL_TREE(tree);
11967 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11969 switch (hf_field->type) {
11977 DISSECTOR_ASSERT_NOT_REACHED();
11982 CREATE_VALUE_STRING(dst, format, ap);
11984 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11988 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
11989 tvbuff_t *tvb, const guint bit_offset,
11990 const gint no_of_bits, guint64 value,
11991 const char *format, ...)
11995 header_field_info *hf_field;
11997 CHECK_FOR_NULL_TREE(tree);
11999 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12001 switch (hf_field->type) {
12009 DISSECTOR_ASSERT_NOT_REACHED();
12014 CREATE_VALUE_STRING(dst, format, ap);
12016 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12020 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
12021 tvbuff_t *tvb, const guint bit_offset,
12022 const gint no_of_bits, float value,
12023 const char *format, ...)
12027 header_field_info *hf_field;
12029 CHECK_FOR_NULL_TREE(tree);
12031 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12033 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
12035 CREATE_VALUE_STRING(dst, format, ap);
12037 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12041 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
12042 tvbuff_t *tvb, const guint bit_offset,
12043 const gint no_of_bits, gint32 value,
12044 const char *format, ...)
12048 header_field_info *hf_field;
12050 CHECK_FOR_NULL_TREE(tree);
12052 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12054 switch (hf_field->type) {
12062 DISSECTOR_ASSERT_NOT_REACHED();
12067 CREATE_VALUE_STRING(dst, format, ap);
12069 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12073 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
12074 tvbuff_t *tvb, const guint bit_offset,
12075 const gint no_of_bits, gint64 value,
12076 const char *format, ...)
12080 header_field_info *hf_field;
12082 CHECK_FOR_NULL_TREE(tree);
12084 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12086 switch (hf_field->type) {
12094 DISSECTOR_ASSERT_NOT_REACHED();
12099 CREATE_VALUE_STRING(dst, format, ap);
12101 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12105 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
12106 tvbuff_t *tvb, const guint bit_offset,
12107 const gint no_of_bits, guint32 value,
12108 const char *format, ...)
12112 header_field_info *hf_field;
12114 CHECK_FOR_NULL_TREE(tree);
12116 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12118 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
12120 CREATE_VALUE_STRING(dst, format, ap);
12122 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12126 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
12127 tvbuff_t *tvb, const guint bit_offset,
12128 const gint no_of_bits, guint64 value,
12129 const char *format, ...)
12133 header_field_info *hf_field;
12135 CHECK_FOR_NULL_TREE(tree);
12137 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12139 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
12141 CREATE_VALUE_STRING(dst, format, ap);
12143 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12147 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12148 const guint bit_offset, const gint no_of_chars)
12151 header_field_info *hfinfo;
12156 CHECK_FOR_NULL_TREE(tree);
12158 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12160 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
12162 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
12163 byte_offset = bit_offset >> 3;
12165 string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
12167 if (hfinfo->display == STR_UNICODE) {
12168 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
12171 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
12172 DISSECTOR_ASSERT(byte_length >= 0);
12173 proto_tree_set_string(PNODE_FINFO(pi), string);
12179 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12180 const guint bit_offset, const gint no_of_chars)
12183 header_field_info *hfinfo;
12188 CHECK_FOR_NULL_TREE(tree);
12190 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12192 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
12194 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
12195 byte_offset = bit_offset >> 3;
12197 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
12199 if (hfinfo->display == STR_UNICODE) {
12200 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
12203 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
12204 DISSECTOR_ASSERT(byte_length >= 0);
12205 proto_tree_set_string(PNODE_FINFO(pi), string);
12210 const value_string proto_checksum_vals[] = {
12211 { PROTO_CHECKSUM_E_BAD, "Bad" },
12212 { PROTO_CHECKSUM_E_GOOD, "Good" },
12213 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
12214 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
12220 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
12221 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
12222 packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
12224 header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
12227 proto_item* ti = NULL;
12229 gboolean incorrect_checksum = TRUE;
12231 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
12233 switch (hfinfo->type) {
12247 DISSECTOR_ASSERT_NOT_REACHED();
12250 if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
12251 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
12252 PROTO_ITEM_SET_GENERATED(ti);
12253 if (hf_checksum_status != -1) {
12254 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
12255 PROTO_ITEM_SET_GENERATED(ti2);
12260 if (flags & PROTO_CHECKSUM_GENERATED) {
12261 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
12262 PROTO_ITEM_SET_GENERATED(ti);
12264 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
12265 if (flags & PROTO_CHECKSUM_VERIFY) {
12266 if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
12267 if (computed_checksum == 0) {
12268 proto_item_append_text(ti, " [correct]");
12269 if (hf_checksum_status != -1) {
12270 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
12271 PROTO_ITEM_SET_GENERATED(ti2);
12273 incorrect_checksum = FALSE;
12274 } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
12275 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
12278 if (checksum == computed_checksum) {
12279 proto_item_append_text(ti, " [correct]");
12280 if (hf_checksum_status != -1) {
12281 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
12282 PROTO_ITEM_SET_GENERATED(ti2);
12284 incorrect_checksum = FALSE;
12288 if (incorrect_checksum) {
12289 if (hf_checksum_status != -1) {
12290 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
12291 PROTO_ITEM_SET_GENERATED(ti2);
12293 if (flags & PROTO_CHECKSUM_ZERO) {
12294 proto_item_append_text(ti, " [incorrect]");
12295 if (bad_checksum_expert != NULL)
12296 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
12298 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
12299 if (bad_checksum_expert != NULL)
12300 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%0*x]", expert_get_summary(bad_checksum_expert), len * 2, computed_checksum);
12304 if (hf_checksum_status != -1) {
12305 proto_item_append_text(ti, " [unverified]");
12306 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
12307 PROTO_ITEM_SET_GENERATED(ti2);
12316 proto_check_field_name(const gchar *field_name)
12318 const char *p = field_name;
12319 guchar c = '.', lastc;
12324 /* Leading '.' or substring ".." are disallowed. */
12325 if (c == '.' && lastc == '.') {
12328 } while (fld_abbrev_chars[c]);
12330 /* Trailing '.' is disallowed. */
12331 if (lastc == '.') {
12338 tree_expanded(int tree_type)
12340 if (tree_type == -1) {
12343 g_assert(tree_type >= 0 && tree_type < num_tree_types);
12344 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
12348 tree_expanded_set(int tree_type, gboolean value)
12350 g_assert(tree_type >= 0 && tree_type < num_tree_types);
12353 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
12355 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
12359 * Editor modelines - http://www.wireshark.org/tools/modelines.html
12362 * c-basic-offset: 8
12364 * indent-tabs-mode: t
12367 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
12368 * :indentSize=8:tabSize=8:noTabs=false: