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
12 #define WS_LOG_DOMAIN LOG_DOMAIN_EPAN
20 #include <wsutil/bits_ctz.h>
21 #include <wsutil/bits_count_ones.h>
22 #include <wsutil/sign_ext.h>
23 #include <wsutil/utf8_entities.h>
24 #include <wsutil/json_dumper.h>
25 #include <wsutil/wslog.h>
27 #include <ftypes/ftypes-int.h>
30 #include "exceptions.h"
31 #include "ptvcursor.h"
33 #include "addr_resolv.h"
34 #include "address_types.h"
37 #include "epan_dissect.h"
39 #include "wmem/wmem.h"
41 #include "column-utils.h"
42 #include "to_str-int.h"
44 #include "osi-utils.h"
46 #include "show_exception.h"
48 #include "register-int.h"
50 #include <wsutil/crash_info.h>
51 #include <wsutil/epochs.h>
53 /* Ptvcursor limits */
54 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
55 #define SUBTREE_MAX_LEVELS 256
57 typedef struct __subtree_lvl {
64 subtree_lvl *pushed_tree;
65 guint8 pushed_tree_index;
66 guint8 pushed_tree_max;
72 #define cVALS(x) (const value_string*)(x)
74 /** See inlined comments.
75 @param tree the tree to append this item to
76 @param free_block a code block to call to free resources if this returns
77 @return NULL if 'tree' is null */
78 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block) \
84 /** See inlined comments.
85 @param tree the tree to append this item to
86 @param free_block a code block to call to free resources if this returns
87 @return NULL if 'tree' is null */
88 #define CHECK_FOR_NULL_TREE(tree) \
89 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
91 /** See inlined comments.
92 @param tree the tree to append this item to
93 @param hfindex field index
94 @param hfinfo header_field
95 @param free_block a code block to call to free resources if this returns
96 @return the header field matching 'hfinfo' */
97 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
98 /* If this item is not referenced we don't have to do much work \
99 at all but we should still return a node so that field items \
100 below this node (think proto_item_add_subtree()) will still \
101 have somewhere to attach to or else filtering will not work \
102 (they would be ignored since tree would be NULL). \
103 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
104 since dissectors that want to do proto_item_set_len() or \
105 other operations that dereference this would crash. \
106 We fake FT_PROTOCOL unless some clients have requested us \
109 PTREE_DATA(tree)->count++; \
110 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
111 if (PTREE_DATA(tree)->count > prefs.gui_max_tree_items) { \
113 if (wireshark_abort_on_too_many_items) \
114 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \
115 hfinfo->abbrev, prefs.gui_max_tree_items); \
116 /* Let the exception handler add items to the tree */ \
117 PTREE_DATA(tree)->count = 0; \
118 THROW_MESSAGE(DissectorError, \
119 wmem_strdup_printf(wmem_packet_scope(), \
120 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \
121 hfinfo->abbrev, prefs.gui_max_tree_items)); \
123 if (!(PTREE_DATA(tree)->visible)) { \
124 if (PTREE_FINFO(tree)) { \
125 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
126 && (hfinfo->type != FT_PROTOCOL || \
127 PTREE_DATA(tree)->fake_protocols)) { \
129 /* just return tree back to the caller */\
135 /** See inlined comments.
136 @param tree the tree to append this item to
137 @param hfindex field index
138 @param hfinfo header_field
139 @return the header field matching 'hfinfo' */
140 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
141 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
144 /** See inlined comments.
145 @param pi the created protocol item we're about to return */
146 #define TRY_TO_FAKE_THIS_REPR(pi) \
148 if (!(PTREE_DATA(pi)->visible)) { \
149 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
150 * items string representation */ \
153 /* Same as above but returning void */
154 #define TRY_TO_FAKE_THIS_REPR_VOID(pi) \
157 if (!(PTREE_DATA(pi)->visible)) { \
158 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
159 * items string representation */ \
162 /* Similar to above, but allows a NULL tree */
163 #define TRY_TO_FAKE_THIS_REPR_NESTED(pi) \
164 if ((pi == NULL) || (!(PTREE_DATA(pi)->visible))) { \
165 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
166 * items string representation */ \
170 #ifdef ENABLE_CHECK_FILTER
171 #define CHECK_HF_VALUE(type, modifier, start_values) \
173 const type *current; \
175 current = start_values; \
176 for (n=0; current; n++, current++) { \
177 /* Drop out if we reached the end. */ \
178 if ((current->value == 0) && (current->strptr == NULL)) { \
181 /* Check value against all previous */ \
182 for (m=0; m < n; m++) { \
183 /* There are lots of duplicates with the same string, \
184 so only report if different... */ \
185 if ((start_values[m].value == current->value) && \
186 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
187 ws_warning("Field '%s' (%s) has a conflicting entry in its" \
188 " value_string: %" modifier "u is at indices %u (%s) and %u (%s)", \
189 hfinfo->name, hfinfo->abbrev, \
190 current->value, m, start_values[m].strptr, n, current->strptr); \
198 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
199 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
200 static int hfinfo_bitoffset(const header_field_info *hfinfo);
201 static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
202 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
204 static void label_mark_truncated(char *label_str, gsize name_pos);
205 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
207 static void fill_label_boolean(field_info *fi, gchar *label_str);
208 static void fill_label_bitfield_char(field_info *fi, gchar *label_str);
209 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
210 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
211 static void fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed);
212 static void fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed);
213 static void fill_label_char(field_info *fi, gchar *label_str);
214 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
215 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
217 static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value);
218 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
219 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
220 static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
221 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
222 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
223 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
224 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
225 static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
226 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
227 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
229 static void proto_cleanup_base(void);
232 proto_tree_add_node(proto_tree *tree, field_info *fi);
235 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
236 gint *item_length, const guint encoding);
239 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
240 gint length, guint item_length, const gint encoding);
243 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
244 const gint start, const gint item_length);
247 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
248 gint start, gint *length);
251 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
253 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
256 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
258 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
260 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
262 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
264 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
266 proto_tree_set_string(field_info *fi, const char* value);
268 proto_tree_set_ax25(field_info *fi, const guint8* value);
270 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
272 proto_tree_set_vines(field_info *fi, const guint8* value);
274 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
276 proto_tree_set_ether(field_info *fi, const guint8* value);
278 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
280 proto_tree_set_ipxnet(field_info *fi, guint32 value);
282 proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
284 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
286 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
288 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
290 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
292 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
294 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
296 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
298 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
300 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
302 proto_tree_set_boolean(field_info *fi, guint64 value);
304 proto_tree_set_float(field_info *fi, float value);
306 proto_tree_set_double(field_info *fi, double value);
308 proto_tree_set_uint(field_info *fi, guint32 value);
310 proto_tree_set_int(field_info *fi, gint32 value);
312 proto_tree_set_uint64(field_info *fi, guint64 value);
314 proto_tree_set_int64(field_info *fi, gint64 value);
316 proto_tree_set_eui64(field_info *fi, const guint64 value);
318 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
320 /* Handle type length mismatch (now filterable) expert info */
321 static int proto_type_length_mismatch = -1;
322 static expert_field ei_type_length_mismatch_error = EI_INIT;
323 static expert_field ei_type_length_mismatch_warn = EI_INIT;
324 static void register_type_length_mismatch(void);
326 /* Handle number string decoding errors with expert info */
327 static int proto_number_string_decoding_error = -1;
328 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
329 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
330 static void register_number_string_decodinws_error(void);
332 /* Handle string errors expert info */
333 static int proto_string_errors = -1;
334 static expert_field ei_string_trailing_characters = EI_INIT;
335 static void register_string_errors(void);
337 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
339 /* special-case header field used within proto.c */
340 static header_field_info hfi_text_only =
341 { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
342 int hf_text_only = -1;
344 /* Structure for information about a protocol */
346 const char *name; /* long description */
347 const char *short_name; /* short description */
348 const char *filter_name; /* name of this protocol in filters */
349 GPtrArray *fields; /* fields for this protocol */
350 int proto_id; /* field ID for this protocol */
351 gboolean is_enabled; /* TRUE if protocol is enabled */
352 gboolean enabled_by_default; /* TRUE if protocol is enabled by default */
353 gboolean can_toggle; /* TRUE if is_enabled can be changed */
354 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
355 For dissectors that need a protocol name so they
356 can be added to a dissector table, but use the
357 parent_proto_id for things like enable/disable */
358 GList *heur_list; /* Heuristic dissectors associated with this protocol */
361 /* List of all protocols */
362 static GList *protocols = NULL;
364 /* Deregistered fields */
365 static GPtrArray *deregistered_fields = NULL;
366 static GPtrArray *deregistered_data = NULL;
368 /* indexed by prefix, contains initializers */
369 static GHashTable* prefixes = NULL;
371 /* Contains information about a field when a dissector calls
372 * proto_tree_add_item. */
373 #define FIELD_INFO_NEW(pool, fi) fi = wmem_new(pool, field_info)
374 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
376 /* Contains the space for proto_nodes. */
377 #define PROTO_NODE_INIT(node) \
378 node->first_child = NULL; \
379 node->last_child = NULL; \
382 #define PROTO_NODE_FREE(pool, node) \
383 wmem_free(pool, node)
385 /* String space for protocol and field items for the GUI */
386 #define ITEM_LABEL_NEW(pool, il) \
387 il = wmem_new(pool, item_label_t);
388 #define ITEM_LABEL_FREE(pool, il) \
391 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
392 if((guint)hfindex >= gpa_hfinfo.len && wireshark_abort_on_dissector_bug) \
393 ws_error("Unregistered hf! index=%d", hfindex); \
394 DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
395 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
396 hfinfo = gpa_hfinfo.hfi[hfindex];
398 /* List which stores protocols and fields that have been registered */
399 typedef struct _gpa_hfinfo_t {
401 guint32 allocated_len;
402 header_field_info **hfi;
405 static gpa_hfinfo_t gpa_hfinfo;
407 /* Hash table of abbreviations and IDs */
408 static GHashTable *gpa_name_map = NULL;
409 static header_field_info *same_name_hfinfo;
411 /* Hash table protocol aliases. const char * -> const char * */
412 static GHashTable *gpa_protocol_aliases = NULL;
415 * We're called repeatedly with the same field name when sorting a column.
416 * Cache our last gpa_name_map hit for faster lookups.
418 static char *last_field_name = NULL;
419 static header_field_info *last_hfinfo;
421 static void save_same_name_hfinfo(gpointer data)
423 same_name_hfinfo = (header_field_info*)data;
426 /* Points to the first element of an array of bits, indexed by
427 a subtree item type; that array element is TRUE if subtrees of
428 an item of that type are to be expanded. */
429 static guint32 *tree_is_expanded;
431 /* Number of elements in that array. */
434 /* Name hashtables for fast detection of duplicate names */
435 static GHashTable* proto_names = NULL;
436 static GHashTable* proto_short_names = NULL;
437 static GHashTable* proto_filter_names = NULL;
440 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
442 const protocol_t *p1 = (const protocol_t *)p1_arg;
443 const protocol_t *p2 = (const protocol_t *)p2_arg;
445 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
448 static GSList *dissector_plugins = NULL;
452 proto_register_plugin(const proto_plugin *plug)
454 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
456 #else /* HAVE_PLUGINS */
458 proto_register_plugin(const proto_plugin *plug _U_)
460 ws_warning("proto_register_plugin: built without support for binary plugins");
462 #endif /* HAVE_PLUGINS */
465 call_plugin_register_protoinfo(gpointer data, gpointer user_data _U_)
467 proto_plugin *plug = (proto_plugin *)data;
469 if (plug->register_protoinfo) {
470 plug->register_protoinfo();
475 call_plugin_register_handoff(gpointer data, gpointer user_data _U_)
477 proto_plugin *plug = (proto_plugin *)data;
479 if (plug->register_handoff) {
480 plug->register_handoff();
484 /* initialize data structures and register protocols and fields */
486 proto_init(GSList *register_all_plugin_protocols_list,
487 GSList *register_all_plugin_handoffs_list,
489 gpointer client_data)
491 proto_cleanup_base();
493 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
494 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
495 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
498 gpa_hfinfo.allocated_len = 0;
499 gpa_hfinfo.hfi = NULL;
500 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
501 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
502 deregistered_fields = g_ptr_array_new();
503 deregistered_data = g_ptr_array_new();
505 /* Initialize the ftype subsystem */
508 /* Initialize the addres type subsystem */
509 address_types_initialize();
511 /* Register one special-case FT_TEXT_ONLY field for use when
512 converting wireshark to new-style proto_tree. These fields
513 are merely strings on the GUI tree; they are not filterable */
514 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
516 /* Register the pseudo-protocols used for exceptions. */
517 register_show_exception();
518 register_type_length_mismatch();
519 register_number_string_decodinws_error();
520 register_string_errors();
522 /* Have each built-in dissector register its protocols, fields,
523 dissector tables, and dissectors to be called through a
524 handle, and do whatever one-time initialization it needs to
526 register_all_protocols(cb, client_data);
528 /* Now call the registration routines for all epan plugins. */
529 for (GSList *l = register_all_plugin_protocols_list; l != NULL; l = l->next) {
530 ((void (*)(register_cb, gpointer))l->data)(cb, client_data);
533 /* Now call the registration routines for all dissector plugins. */
535 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
536 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL);
538 /* Now call the "handoff registration" routines of all built-in
539 dissectors; those routines register the dissector in other
540 dissectors' handoff tables, and fetch any dissector handles
542 register_all_protocol_handoffs(cb, client_data);
544 /* Now do the same with epan plugins. */
545 for (GSList *l = register_all_plugin_handoffs_list; l != NULL; l = l->next) {
546 ((void (*)(register_cb, gpointer))l->data)(cb, client_data);
549 /* Now do the same with dissector plugins. */
551 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
552 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL);
554 /* sort the protocols by protocol name */
555 protocols = g_list_sort(protocols, proto_compare_name);
557 /* We've assigned all the subtree type values; allocate the array
558 for them, and zero it out. */
559 tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
563 proto_cleanup_base(void)
565 protocol_t *protocol;
566 header_field_info *hfinfo;
568 /* Free the abbrev/ID hash table */
570 g_hash_table_destroy(gpa_name_map);
573 if (gpa_protocol_aliases) {
574 g_hash_table_destroy(gpa_protocol_aliases);
575 gpa_protocol_aliases = NULL;
577 g_free(last_field_name);
578 last_field_name = NULL;
581 protocol = (protocol_t *)protocols->data;
582 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
583 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
585 g_slice_free(header_field_info, hfinfo);
586 if (protocol->parent_proto_id != -1) {
588 DISSECTOR_ASSERT(protocol->fields == NULL); //helpers should not have any registered fields
589 DISSECTOR_ASSERT(protocol->heur_list == NULL); //helpers should not have a heuristic list
591 if (protocol->fields) {
592 g_ptr_array_free(protocol->fields, TRUE);
594 g_list_free(protocol->heur_list);
596 protocols = g_list_remove(protocols, protocol);
601 g_hash_table_destroy(proto_names);
605 if (proto_short_names) {
606 g_hash_table_destroy(proto_short_names);
607 proto_short_names = NULL;
610 if (proto_filter_names) {
611 g_hash_table_destroy(proto_filter_names);
612 proto_filter_names = NULL;
615 if (gpa_hfinfo.allocated_len) {
617 gpa_hfinfo.allocated_len = 0;
618 g_free(gpa_hfinfo.hfi);
619 gpa_hfinfo.hfi = NULL;
622 if (deregistered_fields) {
623 g_ptr_array_free(deregistered_fields, TRUE);
624 deregistered_fields = NULL;
627 if (deregistered_data) {
628 g_ptr_array_free(deregistered_data, TRUE);
629 deregistered_data = NULL;
632 g_free(tree_is_expanded);
633 tree_is_expanded = NULL;
636 g_hash_table_destroy(prefixes);
642 proto_free_deregistered_fields();
643 proto_cleanup_base();
645 g_slist_free(dissector_plugins);
646 dissector_plugins = NULL;
650 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
653 proto_node *pnode = tree;
657 if (func(pnode, data))
660 child = pnode->first_child;
661 while (child != NULL) {
663 * The routine we call might modify the child, e.g. by
664 * freeing it, so we get the child's successor before
665 * calling that routine.
668 child = current->next;
669 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
677 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
680 proto_node *pnode = tree;
684 child = pnode->first_child;
685 while (child != NULL) {
687 * The routine we call might modify the child, e.g. by
688 * freeing it, so we get the child's successor before
689 * calling that routine.
692 child = current->next;
693 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
696 if (func(pnode, data))
703 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
706 proto_node *node = tree;
712 node = node->first_child;
713 while (node != NULL) {
715 node = current->next;
716 func((proto_tree *)current, data);
721 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
723 GPtrArray *ptrs = (GPtrArray *)value;
724 gint hfid = GPOINTER_TO_UINT(key);
725 header_field_info *hfinfo;
727 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
728 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
729 /* when a field is referenced by a filter this also
730 affects the refcount for the parent protocol so we need
731 to adjust the refcount for the parent as well
733 if (hfinfo->parent != -1) {
734 header_field_info *parent_hfinfo;
735 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
736 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
738 hfinfo->ref_type = HF_REF_TYPE_NONE;
741 g_ptr_array_free(ptrs, TRUE);
745 proto_tree_free_node(proto_node *node, gpointer data _U_)
747 field_info *finfo = PNODE_FINFO(node);
749 proto_tree_children_foreach(node, proto_tree_free_node, NULL);
751 FVALUE_CLEANUP(&finfo->value);
755 proto_tree_reset(proto_tree *tree)
757 tree_data_t *tree_data = PTREE_DATA(tree);
759 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
762 if (tree_data->interesting_hfids) {
763 /* Free all the GPtrArray's in the interesting_hfids hash. */
764 g_hash_table_foreach(tree_data->interesting_hfids,
765 free_GPtrArray_value, NULL);
767 /* And then remove all values. */
768 g_hash_table_remove_all(tree_data->interesting_hfids);
771 /* Reset track of the number of children */
772 tree_data->count = 0;
774 PROTO_NODE_INIT(tree);
777 /* frees the resources that the dissection a proto_tree uses */
779 proto_tree_free(proto_tree *tree)
781 tree_data_t *tree_data = PTREE_DATA(tree);
783 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
786 if (tree_data->interesting_hfids) {
787 /* Free all the GPtrArray's in the interesting_hfids hash. */
788 g_hash_table_foreach(tree_data->interesting_hfids,
789 free_GPtrArray_value, NULL);
791 /* And then destroy the hash. */
792 g_hash_table_destroy(tree_data->interesting_hfids);
795 g_slice_free(tree_data_t, tree_data);
797 g_slice_free(proto_tree, tree);
800 /* Is the parsing being done for a visible proto_tree or an invisible one?
801 * By setting this correctly, the proto_tree creation is sped up by not
802 * having to call g_vsnprintf and copy strings around.
805 proto_tree_set_visible(proto_tree *tree, gboolean visible)
807 gboolean old_visible = PTREE_DATA(tree)->visible;
809 PTREE_DATA(tree)->visible = visible;
815 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
817 PTREE_DATA(tree)->fake_protocols = fake_protocols;
820 /* Assume dissector set only its protocol fields.
821 This function is called by dissectors and allows the speeding up of filtering
822 in wireshark; if this function returns FALSE it is safe to reset tree to NULL
823 and thus skip calling most of the expensive proto_tree_add_...()
825 If the tree is visible we implicitly assume the field is referenced.
828 proto_field_is_referenced(proto_tree *tree, int proto_id)
830 register header_field_info *hfinfo;
836 if (PTREE_DATA(tree)->visible)
839 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
840 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
843 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
850 /* Finds a record in the hfinfo array by id. */
852 proto_registrar_get_nth(guint hfindex)
854 register header_field_info *hfinfo;
856 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
861 /* Prefix initialization
862 * this allows for a dissector to register a display filter name prefix
863 * so that it can delay the initialization of the hf array as long as
867 /* compute a hash for the part before the dot of a display filter */
869 prefix_hash (gconstpointer key) {
870 /* end the string at the dot and compute its hash */
871 gchar* copy = g_strdup((const gchar *)key);
882 tmp = g_str_hash(copy);
887 /* are both strings equal up to the end or the dot? */
889 prefix_equal (gconstpointer ap, gconstpointer bp) {
890 const gchar* a = (const gchar *)ap;
891 const gchar* b = (const gchar *)bp;
897 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
899 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
900 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
902 if (ac != bc) return FALSE;
908 /* Register a new prefix for "delayed" initialization of field arrays */
910 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
912 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
915 g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
918 /* helper to call all prefix initializers */
920 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
921 ((prefix_initializer_t)v)((const char *)k);
925 /** Initialize every remaining uninitialized prefix. */
927 proto_initialize_all_prefixes(void) {
928 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
931 /* Finds a record in the hfinfo array by name.
932 * If it fails to find it in the already registered fields,
933 * it tries to find and call an initializer in the prefixes
934 * table and if so it looks again.
938 proto_registrar_get_byname(const char *field_name)
940 header_field_info *hfinfo;
941 prefix_initializer_t pi;
946 if (g_strcmp0(field_name, last_field_name) == 0) {
950 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
953 g_free(last_field_name);
954 last_field_name = g_strdup(field_name);
955 last_hfinfo = hfinfo;
962 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
964 g_hash_table_remove(prefixes, field_name);
969 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
972 g_free(last_field_name);
973 last_field_name = g_strdup(field_name);
974 last_hfinfo = hfinfo;
980 proto_registrar_get_byalias(const char *alias_name)
986 /* Find our aliased protocol. */
987 char *an_copy = g_strdup(alias_name);
988 char *dot = strchr(an_copy, '.');
992 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
998 /* Construct our aliased field and look it up. */
999 GString *filter_name = g_string_new(proto_pfx);
1001 g_string_append_printf(filter_name, ".%s", dot+1);
1003 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1005 g_string_free(filter_name, TRUE);
1011 proto_registrar_get_id_byname(const char *field_name)
1013 header_field_info *hfinfo;
1015 hfinfo = proto_registrar_get_byname(field_name);
1025 hfinfo_format_text(wmem_allocator_t *scope, const header_field_info *hfinfo,
1026 const guchar *string)
1028 switch (hfinfo->display) {
1030 return format_text(scope, string, strlen(string));
1033 return format_text_wsp(string, strlen(string));
1036 return format_text(scope, string, strlen(string));
1039 return format_text(scope, string, strlen(string));
1043 hfinfo_format_bytes(wmem_allocator_t *scope, const header_field_info *hfinfo,
1044 const guint8 *bytes, guint length)
1048 gboolean is_printable;
1051 if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE) {
1053 * Check whether all bytes are printable.
1055 is_printable = TRUE;
1056 for (p = bytes; p < bytes+length; p++) {
1057 if (!g_ascii_isprint(*p)) {
1058 /* Not printable. */
1059 is_printable = FALSE;
1065 * If all bytes are printable ASCII, show the bytes
1066 * as a string - in quotes to indicate that it's
1070 str = wmem_strdup_printf(scope, "\"%.*s\"",
1071 (int)length, bytes);
1077 * Either it's not printable ASCII, or we don't care whether
1078 * it's printable ASCII; show it as hex bytes.
1080 switch (FIELD_DISPLAY(hfinfo->display)) {
1082 str = bytestring_to_str(scope, bytes, length, '.');
1085 str = bytestring_to_str(scope, bytes, length, '-');
1088 str = bytestring_to_str(scope, bytes, length, ':');
1091 str = bytestring_to_str(scope, bytes, length, ' ');
1095 if (prefs.display_byte_fields_with_spaces) {
1096 str = bytestring_to_str(scope, bytes, length, ' ');
1098 str = bytes_to_str(scope, bytes, length);
1104 if (hfinfo->display & BASE_ALLOW_ZERO) {
1105 str = wmem_strdup(scope, "<none>");
1107 str = wmem_strdup(scope, "<MISSING>");
1114 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1116 subtree_lvl *pushed_tree;
1118 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
1119 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
1121 pushed_tree = (subtree_lvl *)wmem_realloc(wmem_packet_scope(), (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1122 DISSECTOR_ASSERT(pushed_tree != NULL);
1123 ptvc->pushed_tree = pushed_tree;
1127 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1129 ptvc->pushed_tree = NULL;
1130 ptvc->pushed_tree_max = 0;
1131 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1132 ptvc->pushed_tree_index = 0;
1135 /* Allocates an initializes a ptvcursor_t with 3 variables:
1136 * proto_tree, tvbuff, and offset. */
1138 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
1142 ptvc = wmem_new(wmem_packet_scope(), ptvcursor_t);
1145 ptvc->offset = offset;
1146 ptvc->pushed_tree = NULL;
1147 ptvc->pushed_tree_max = 0;
1148 ptvc->pushed_tree_index = 0;
1153 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1155 ptvcursor_free(ptvcursor_t *ptvc)
1157 ptvcursor_free_subtree_levels(ptvc);
1161 /* Returns tvbuff. */
1163 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1168 /* Returns current offset. */
1170 ptvcursor_current_offset(ptvcursor_t *ptvc)
1172 return ptvc->offset;
1176 ptvcursor_tree(ptvcursor_t *ptvc)
1185 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1190 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1192 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1194 subtree_lvl *subtree;
1195 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1196 ptvcursor_new_subtree_levels(ptvc);
1198 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1199 subtree->tree = ptvc->tree;
1201 ptvc->pushed_tree_index++;
1202 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1205 /* pops a subtree */
1207 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1209 subtree_lvl *subtree;
1211 if (ptvc->pushed_tree_index <= 0)
1214 ptvc->pushed_tree_index--;
1215 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1216 if (subtree->it != NULL)
1217 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1219 ptvc->tree = subtree->tree;
1222 /* saves the current tvb offset and the item in the current subtree level */
1224 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1226 subtree_lvl *subtree;
1228 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1230 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1232 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1235 /* Creates a subtree and adds it to the cursor as the working tree but does not
1236 * save the old working tree */
1238 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1240 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1245 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1247 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1248 if (length == SUBTREE_UNDEFINED_LENGTH)
1249 ptvcursor_subtree_set_item(ptvc, it);
1250 return ptvcursor_tree(ptvc);
1253 /* Add an item to the tree and create a subtree
1254 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1255 * In this case, when the subtree will be closed, the parent item length will
1256 * be equal to the advancement of the cursor since the creation of the subtree.
1259 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1260 const guint encoding, gint ett_subtree)
1264 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1265 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1269 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1271 /* Add a text node to the tree and create a subtree
1272 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1273 * In this case, when the subtree will be closed, the item length will be equal
1274 * to the advancement of the cursor since the creation of the subtree.
1277 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1278 gint ett_subtree, const char *format, ...)
1282 header_field_info *hfinfo;
1285 tree = ptvcursor_tree(ptvc);
1287 CHECK_FOR_NULL_TREE(tree);
1289 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1291 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1292 ptvcursor_current_offset(ptvc), length);
1294 TRY_TO_FAKE_THIS_REPR(pi);
1296 va_start(ap, format);
1297 proto_tree_set_representation(pi, format, ap);
1300 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1303 /* Add a text-only node, leaving it to our caller to fill the text in */
1305 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1312 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1317 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1319 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1320 const char *format, ...)
1324 header_field_info *hfinfo;
1327 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1329 tvb_ensure_bytes_exist(tvb, start, length);
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 va_start(ap, format);
1341 proto_tree_set_representation(pi, format, ap);
1347 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1349 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1350 gint length, const char *format, va_list ap)
1353 header_field_info *hfinfo;
1356 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1358 tvb_ensure_bytes_exist(tvb, start, length);
1361 CHECK_FOR_NULL_TREE(tree);
1363 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1365 pi = proto_tree_add_text_node(tree, tvb, start, length);
1367 TRY_TO_FAKE_THIS_REPR(pi);
1369 proto_tree_set_representation(pi, format, ap);
1374 /* Add a text-only node that creates a subtree underneath.
1377 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1379 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1382 /* Add a text-only node that creates a subtree underneath.
1385 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1391 va_start(ap, format);
1392 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1395 if (tree_item != NULL)
1398 pt = proto_item_add_subtree(pi, idx);
1403 /* Add a text-only node for debugging purposes. The caller doesn't need
1404 * to worry about tvbuff, start, or length. Debug message gets sent to
1407 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1412 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1415 va_start(ap, format);
1416 proto_tree_set_representation(pi, format, ap);
1419 va_start(ap, format);
1420 vprintf(format, ap);
1428 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1431 header_field_info *hfinfo;
1433 CHECK_FOR_NULL_TREE(tree);
1435 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1437 pi = proto_tree_add_text_node(tree, tvb, start, length);
1439 TRY_TO_FAKE_THIS_REPR(pi);
1441 proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1447 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1450 header_field_info *hfinfo;
1453 CHECK_FOR_NULL_TREE(tree);
1455 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1457 pi = proto_tree_add_text_node(tree, tvb, start, length);
1459 TRY_TO_FAKE_THIS_REPR(pi);
1461 str = tvb_format_text_wsp(NULL, tvb, start, length);
1462 proto_item_set_text(pi, "%s", str);
1463 wmem_free(NULL, str);
1468 void proto_report_dissector_bug(const char *format, ...)
1472 if (wireshark_abort_on_dissector_bug) {
1474 * Try to have the error message show up in the crash
1477 va_start(args, format);
1478 ws_vadd_crash_info(format, args);
1482 * Print the error message.
1484 va_start(args, format);
1485 vfprintf(stderr, format, args);
1494 va_start(args, format);
1495 VTHROW_FORMATTED(DissectorError, format, args);
1500 /* We could probably get away with changing is_error to a minimum length value. */
1502 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error)
1505 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1507 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1511 THROW(ReportedBoundsError);
1516 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1519 gboolean length_error;
1524 value = tvb_get_guint8(tvb, offset);
1525 if (encoding & ENC_ZIGBEE) {
1526 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1533 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1534 : tvb_get_ntohs(tvb, offset);
1535 if (encoding & ENC_ZIGBEE) {
1536 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1543 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1544 : tvb_get_ntoh24(tvb, offset);
1548 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1549 : tvb_get_ntohl(tvb, offset);
1554 length_error = TRUE;
1557 length_error = FALSE;
1558 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1559 : tvb_get_ntohl(tvb, offset);
1561 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1567 static inline guint64
1568 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1571 gboolean length_error;
1576 value = tvb_get_guint8(tvb, offset);
1580 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1581 : tvb_get_ntohs(tvb, offset);
1585 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1586 : tvb_get_ntoh24(tvb, offset);
1590 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1591 : tvb_get_ntohl(tvb, offset);
1595 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1596 : tvb_get_ntoh40(tvb, offset);
1600 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1601 : tvb_get_ntoh48(tvb, offset);
1605 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1606 : tvb_get_ntoh56(tvb, offset);
1610 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1611 : tvb_get_ntoh64(tvb, offset);
1616 length_error = TRUE;
1619 length_error = FALSE;
1620 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1621 : tvb_get_ntoh64(tvb, offset);
1623 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1630 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1633 gboolean length_error;
1638 value = tvb_get_gint8(tvb, offset);
1642 value = encoding ? tvb_get_letohis(tvb, offset)
1643 : tvb_get_ntohis(tvb, offset);
1647 value = encoding ? tvb_get_letohi24(tvb, offset)
1648 : tvb_get_ntohi24(tvb, offset);
1652 value = encoding ? tvb_get_letohil(tvb, offset)
1653 : tvb_get_ntohil(tvb, offset);
1658 length_error = TRUE;
1661 length_error = FALSE;
1662 value = encoding ? tvb_get_letohil(tvb, offset)
1663 : tvb_get_ntohil(tvb, offset);
1665 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1671 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1672 * be cast-able as a gint64. This is weird, but what the code has always done.
1674 static inline guint64
1675 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1677 guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1681 value = ws_sign_ext64(value, 56);
1684 value = ws_sign_ext64(value, 48);
1687 value = ws_sign_ext64(value, 40);
1690 value = ws_sign_ext64(value, 32);
1693 value = ws_sign_ext64(value, 24);
1696 value = ws_sign_ext64(value, 16);
1699 value = ws_sign_ext64(value, 8);
1707 static inline const guint8 *
1708 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1709 gint length, gint *ret_length, const guint encoding)
1712 length = tvb_ensure_captured_length_remaining(tvb, start);
1714 *ret_length = length;
1715 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1718 /* For FT_STRINGZ */
1719 static inline const guint8 *
1720 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1721 gint start, gint length, gint *ret_length, const guint encoding)
1723 const guint8 *value;
1726 report_type_length_mismatch(tree, "a string", length, TRUE);
1729 /* This can throw an exception */
1730 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1732 /* In this case, length signifies the length of the string.
1734 * This could either be a null-padded string, which doesn't
1735 * necessarily have a '\0' at the end, or a null-terminated
1736 * string, with a trailing '\0'. (Yes, there are cases
1737 * where you have a string that's both counted and null-
1740 * In the first case, we must allocate a buffer of length
1741 * "length+1", to make room for a trailing '\0'.
1743 * In the second case, we don't assume that there is a
1744 * trailing '\0' there, as the packet might be malformed.
1745 * (XXX - should we throw an exception if there's no
1746 * trailing '\0'?) Therefore, we allocate a buffer of
1747 * length "length+1", and put in a trailing '\0', just to
1750 * (XXX - this would change if we made string values counted
1751 * rather than null-terminated.)
1753 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1755 *ret_length = length;
1759 /* For FT_UINT_STRING */
1760 static inline const guint8 *
1761 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1762 tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1763 const guint encoding)
1766 const guint8 *value;
1768 /* I believe it's ok if this is called with a NULL tree */
1769 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1770 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1772 *ret_length = length;
1776 /* For FT_STRINGZPAD */
1777 static inline const guint8 *
1778 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1779 gint length, gint *ret_length, const guint encoding)
1782 * XXX - currently, string values are null-
1783 * terminated, so a "zero-padded" string
1784 * isn't special. If we represent string
1785 * values as something that includes a counted
1786 * array of bytes, we'll need to strip the
1790 length = tvb_ensure_captured_length_remaining(tvb, start);
1792 *ret_length = length;
1793 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1796 /* For FT_STRINGZTRUNC */
1797 static inline const guint8 *
1798 get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1799 gint length, gint *ret_length, const guint encoding)
1802 * XXX - currently, string values are null-
1803 * terminated, so a "zero-truncated" string
1804 * isn't special. If we represent string
1805 * values as something that includes a counted
1806 * array of bytes, we'll need to strip everything
1807 * starting with the terminating NUL.
1810 length = tvb_ensure_captured_length_remaining(tvb, start);
1812 *ret_length = length;
1813 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1817 * Deltas between the epochs for various non-UN*X time stamp formats and
1818 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1823 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1824 * XXX - if it's OK if this is unsigned, can we just use
1825 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1827 #define NTP_TIMEDIFF1900TO1970SEC G_GINT64_CONSTANT(2208988800)
1830 * NTP Era 1: the epoch is January 1, 2036, 00:00:00 UTC.
1832 #define NTP_TIMEDIFF1970TO2036SEC G_GINT64_CONSTANT(2085978496)
1834 /* this can be called when there is no tree, so tree may be null */
1836 get_time_value(proto_tree *tree, tvbuff_t *tvb, const gint start,
1837 const gint length, const guint encoding, nstime_t *time_stamp,
1838 const gboolean is_relative)
1846 case ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN:
1848 * If the length is 16, 8-byte seconds, followed
1849 * by 8-byte fractional time in nanoseconds,
1852 * If the length is 12, 8-byte seconds, followed
1853 * by 4-byte fractional time in nanoseconds,
1856 * If the length is 8, 4-byte seconds, followed
1857 * by 4-byte fractional time in nanoseconds,
1860 * For absolute times, the seconds are seconds
1861 * since the UN*X epoch.
1864 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1865 time_stamp->nsecs = (guint32)tvb_get_ntoh64(tvb, start+8);
1866 } else if (length == 12) {
1867 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1868 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1869 } else if (length == 8) {
1870 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1871 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1872 } else if (length == 4) {
1874 * Backwards compatibility.
1875 * ENC_TIME_SECS_NSECS is 0; using
1876 * ENC_BIG_ENDIAN by itself with a 4-byte
1877 * time-in-seconds value was done in the
1880 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1881 time_stamp->nsecs = 0;
1883 time_stamp->secs = 0;
1884 time_stamp->nsecs = 0;
1885 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1889 case ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN:
1891 * If the length is 16, 8-byte seconds, followed
1892 * by 8-byte fractional time in nanoseconds,
1893 * both little-endian.
1895 * If the length is 12, 8-byte seconds, followed
1896 * by 4-byte fractional time in nanoseconds,
1897 * both little-endian.
1899 * If the length is 8, 4-byte seconds, followed
1900 * by 4-byte fractional time in nanoseconds,
1901 * both little-endian.
1903 * For absolute times, the seconds are seconds
1904 * since the UN*X epoch.
1907 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1908 time_stamp->nsecs = (guint32)tvb_get_letoh64(tvb, start+8);
1909 } else if (length == 12) {
1910 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1911 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1912 } else if (length == 8) {
1913 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1914 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1915 } else if (length == 4) {
1917 * Backwards compatibility.
1918 * ENC_TIME_SECS_NSECS is 0; using
1919 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1920 * time-in-seconds value was done in the
1923 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1924 time_stamp->nsecs = 0;
1926 time_stamp->secs = 0;
1927 time_stamp->nsecs = 0;
1928 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1932 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1934 * NTP time stamp, big-endian.
1935 * Only supported for absolute times.
1937 DISSECTOR_ASSERT(!is_relative);
1939 /* We need a temporary variable here so the unsigned math
1940 * works correctly (for years > 2036 according to RFC 2030
1943 * If bit 0 is set, the UTC time is in the range 1968-2036 and
1944 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
1945 * If bit 0 is not set, the time is in the range 2036-2104 and
1946 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
1948 tmpsecs = tvb_get_ntohl(tvb, start);
1949 if ((tmpsecs & 0x80000000) != 0)
1950 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
1952 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
1956 * Convert 1/2^32s of a second to nanoseconds.
1958 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1959 if ((time_stamp->nsecs == 0) && (tmpsecs == 0)) {
1960 //This is "NULL" time
1961 time_stamp->secs = 0;
1963 } else if (length == 4) {
1965 * Backwards compatibility.
1968 //This is "NULL" time
1969 time_stamp->secs = 0;
1971 time_stamp->nsecs = 0;
1973 time_stamp->secs = 0;
1974 time_stamp->nsecs = 0;
1975 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
1979 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1981 * NTP time stamp, little-endian.
1982 * Only supported for absolute times.
1984 DISSECTOR_ASSERT(!is_relative);
1986 /* We need a temporary variable here so the unsigned math
1987 * works correctly (for years > 2036 according to RFC 2030
1990 * If bit 0 is set, the UTC time is in the range 1968-2036 and
1991 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
1992 * If bit 0 is not set, the time is in the range 2036-2104 and
1993 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
1995 tmpsecs = tvb_get_letohl(tvb, start);
1996 if ((tmpsecs & 0x80000000) != 0)
1997 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
1999 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2003 * Convert 1/2^32s of a second to nanoseconds.
2005 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2006 if ((time_stamp->nsecs == 0) && (tmpsecs == 0)) {
2007 //This is "NULL" time
2008 time_stamp->secs = 0;
2010 } else if (length == 4) {
2012 * Backwards compatibility.
2015 //This is "NULL" time
2016 time_stamp->secs = 0;
2018 time_stamp->nsecs = 0;
2020 time_stamp->secs = 0;
2021 time_stamp->nsecs = 0;
2022 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2026 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
2028 * S/3x0 and z/Architecture TOD clock time stamp,
2029 * big-endian. The epoch is January 1, 1900,
2030 * 00:00:00 (proleptic?) UTC.
2032 * Only supported for absolute times.
2034 DISSECTOR_ASSERT(!is_relative);
2035 DISSECTOR_ASSERT(length == 8);
2038 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2039 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
2040 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2042 time_stamp->secs = 0;
2043 time_stamp->nsecs = 0;
2044 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2048 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
2050 * S/3x0 and z/Architecture TOD clock time stamp,
2051 * little-endian. The epoch is January 1, 1900,
2052 * 00:00:00 (proleptic?) UTC.
2054 * Only supported for absolute times.
2056 DISSECTOR_ASSERT(!is_relative);
2059 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2060 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
2061 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2063 time_stamp->secs = 0;
2064 time_stamp->nsecs = 0;
2065 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2069 case ENC_TIME_RTPS|ENC_BIG_ENDIAN:
2071 * Time stamp using the same seconds/fraction format
2072 * as NTP, but with the origin of the time stamp being
2073 * the UNIX epoch rather than the NTP epoch; big-
2076 * Only supported for absolute times.
2078 DISSECTOR_ASSERT(!is_relative);
2081 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2083 * Convert 1/2^32s of a second to nanoseconds.
2085 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2087 time_stamp->secs = 0;
2088 time_stamp->nsecs = 0;
2089 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2093 case ENC_TIME_RTPS|ENC_LITTLE_ENDIAN:
2095 * Time stamp using the same seconds/fraction format
2096 * as NTP, but with the origin of the time stamp being
2097 * the UNIX epoch rather than the NTP epoch; little-
2100 * Only supported for absolute times.
2102 DISSECTOR_ASSERT(!is_relative);
2105 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2107 * Convert 1/2^32s of a second to nanoseconds.
2109 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2111 time_stamp->secs = 0;
2112 time_stamp->nsecs = 0;
2113 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2117 case ENC_TIME_MIP6 | ENC_BIG_ENDIAN:
2119 * MIP6 time stamp, big-endian.
2120 * A 64-bit unsigned integer field containing a timestamp. The
2121 * value indicates the number of seconds since January 1, 1970,
2122 * 00:00 UTC, by using a fixed point format. In this format, the
2123 * integer number of seconds is contained in the first 48 bits of
2124 * the field, and the remaining 16 bits indicate the number of
2125 * 1/65536 fractions of a second.
2127 * Only supported for absolute times.
2129 DISSECTOR_ASSERT(!is_relative);
2132 /* We need a temporary variable here so the casting and fractions
2133 * of a second work correctly.
2135 tmp64secs = tvb_get_ntoh48(tvb, start);
2136 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2139 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2140 //This is "NULL" time
2141 time_stamp->secs = 0;
2142 time_stamp->nsecs = 0;
2144 time_stamp->secs = (time_t)tmp64secs;
2145 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2148 time_stamp->secs = 0;
2149 time_stamp->nsecs = 0;
2150 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2154 case ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN:
2156 * 4-byte seconds, followed by 4-byte fractional
2157 * time in microseconds, both big-endian.
2158 * For absolute times, the seconds are seconds
2159 * since the UN*X epoch.
2162 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2163 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2165 time_stamp->secs = 0;
2166 time_stamp->nsecs = 0;
2167 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2171 case ENC_TIME_SECS_USECS|ENC_LITTLE_ENDIAN:
2173 * 4-byte seconds, followed by 4-byte fractional
2174 * time in microseconds, both little-endian.
2175 * For absolute times, the seconds are seconds
2176 * since the UN*X epoch.
2179 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2180 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2182 time_stamp->secs = 0;
2183 time_stamp->nsecs = 0;
2184 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2188 case ENC_TIME_SECS|ENC_BIG_ENDIAN:
2189 case ENC_TIME_SECS|ENC_LITTLE_ENDIAN:
2191 * Seconds, 1 to 8 bytes.
2192 * For absolute times, it's seconds since the
2195 if (length >= 1 && length <= 8) {
2196 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2197 time_stamp->nsecs = 0;
2199 time_stamp->secs = 0;
2200 time_stamp->nsecs = 0;
2201 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2205 case ENC_TIME_MSECS|ENC_BIG_ENDIAN:
2206 case ENC_TIME_MSECS|ENC_LITTLE_ENDIAN:
2208 * Milliseconds, 1 to 8 bytes.
2209 * For absolute times, it's milliseconds since the
2212 if (length >= 1 && length <= 8) {
2215 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2216 time_stamp->secs = (time_t)(msecs / 1000);
2217 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2219 time_stamp->secs = 0;
2220 time_stamp->nsecs = 0;
2221 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2225 case ENC_TIME_NSECS|ENC_BIG_ENDIAN:
2226 case ENC_TIME_NSECS|ENC_LITTLE_ENDIAN:
2228 * nanoseconds, 1 to 8 bytes.
2229 * For absolute times, it's nanoseconds since the
2233 if (length >= 1 && length <= 8) {
2236 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2237 time_stamp->secs = (time_t)(nsecs / 1000000000);
2238 time_stamp->nsecs = (int)(nsecs % 1000000000);
2240 time_stamp->secs = 0;
2241 time_stamp->nsecs = 0;
2242 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2246 case ENC_TIME_RFC_3971|ENC_BIG_ENDIAN:
2248 * 1/64ths of a second since the UN*X epoch,
2251 * Only supported for absolute times.
2253 DISSECTOR_ASSERT(!is_relative);
2257 * The upper 48 bits are seconds since the
2260 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2262 * The lower 16 bits are 1/2^16s of a second;
2263 * convert them to nanoseconds.
2265 * XXX - this may give the impression of higher
2266 * precision than you actually get.
2268 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2270 time_stamp->secs = 0;
2271 time_stamp->nsecs = 0;
2272 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2276 case ENC_TIME_RFC_3971|ENC_LITTLE_ENDIAN:
2278 * 1/64ths of a second since the UN*X epoch,
2281 * Only supported for absolute times.
2283 DISSECTOR_ASSERT(!is_relative);
2287 * XXX - this is assuming that, if anybody
2288 * were ever to use this format - RFC 3971
2289 * doesn't, because that's an Internet
2290 * protocol, and those use network byte
2291 * order, i.e. big-endian - they'd treat it
2292 * as a 64-bit count of 1/2^16s of a second,
2293 * putting the upper 48 bits at the end.
2295 * The lower 48 bits are seconds since the
2298 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2300 * The upper 16 bits are 1/2^16s of a second;
2301 * convert them to nanoseconds.
2303 * XXX - this may give the impression of higher
2304 * precision than you actually get.
2306 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2308 time_stamp->secs = 0;
2309 time_stamp->nsecs = 0;
2310 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2314 case ENC_TIME_SECS_NTP|ENC_BIG_ENDIAN:
2316 * NTP time stamp, with 1-second resolution (i.e.,
2317 * seconds since the NTP epoch), big-endian.
2318 * Only supported for absolute times.
2320 DISSECTOR_ASSERT(!is_relative);
2324 * We need a temporary variable here so the unsigned math
2325 * works correctly (for years > 2036 according to RFC 2030
2328 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2329 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2330 * If bit 0 is not set, the time is in the range 2036-2104 and
2331 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2333 tmpsecs = tvb_get_ntohl(tvb, start);
2334 if ((tmpsecs & 0x80000000) != 0)
2335 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2337 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2338 time_stamp->nsecs = 0;
2340 time_stamp->secs = 0;
2341 time_stamp->nsecs = 0;
2342 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2346 case ENC_TIME_SECS_NTP|ENC_LITTLE_ENDIAN:
2348 * NTP time stamp, with 1-second resolution (i.e.,
2349 * seconds since the NTP epoch), little-endian.
2350 * Only supported for absolute times.
2352 DISSECTOR_ASSERT(!is_relative);
2355 * We need a temporary variable here so the unsigned math
2356 * works correctly (for years > 2036 according to RFC 2030
2359 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2360 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2361 * If bit 0 is not set, the time is in the range 2036-2104 and
2362 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2365 tmpsecs = tvb_get_letohl(tvb, start);
2366 if ((tmpsecs & 0x80000000) != 0)
2367 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2369 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2370 time_stamp->nsecs = 0;
2372 time_stamp->secs = 0;
2373 time_stamp->nsecs = 0;
2374 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2377 case ENC_TIME_MSEC_NTP | ENC_BIG_ENDIAN:
2379 * Milliseconds, 1 to 8 bytes.
2380 * For absolute times, it's milliseconds since the
2383 if (length >= 1 && length <= 8) {
2386 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2387 tmpsecs = (guint32)(msecs / 1000);
2389 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2390 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2391 * If bit 0 is not set, the time is in the range 2036-2104 and
2392 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2394 if ((tmpsecs & 0x80000000) != 0)
2395 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2397 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2398 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2401 time_stamp->secs = 0;
2402 time_stamp->nsecs = 0;
2403 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 4));
2407 case ENC_TIME_CLASSIC_MAC_OS_SECS|ENC_BIG_ENDIAN:
2409 * Classic Mac OS time stamps, big-endian.
2410 * Only supported for absolute times.
2412 DISSECTOR_ASSERT(!is_relative);
2415 tmp64secs = tvb_get_ntoh64(tvb, start);
2416 time_stamp->secs = (time_t)(gint64)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
2417 time_stamp->nsecs = 0;
2418 } else if (length == 4) {
2419 tmpsecs = tvb_get_ntohl(tvb, start);
2420 time_stamp->secs = (time_t)(gint32)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
2421 time_stamp->nsecs = 0;
2423 time_stamp->secs = 0;
2424 time_stamp->nsecs = 0;
2425 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2430 DISSECTOR_ASSERT_NOT_REACHED();
2436 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2438 const header_field_info *hfinfo = fi->hfinfo;
2440 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
2441 GPtrArray *ptrs = NULL;
2443 if (tree_data->interesting_hfids == NULL) {
2444 /* Initialize the hash because we now know that it is needed */
2445 tree_data->interesting_hfids =
2446 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
2447 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2448 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2449 GINT_TO_POINTER(hfinfo->id));
2453 /* First element triggers the creation of pointer array */
2454 ptrs = g_ptr_array_new();
2455 g_hash_table_insert(tree_data->interesting_hfids,
2456 GINT_TO_POINTER(hfinfo->id), ptrs);
2459 g_ptr_array_add(ptrs, fi);
2465 * Validates that field length bytes are available starting from
2466 * start (pos/neg). Throws an exception if they aren't.
2469 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2470 gint start, gint length, const guint encoding)
2477 if ((hfinfo->type == FT_STRINGZ) ||
2478 ((encoding & (ENC_VARIANT_MASK)) &&
2479 (IS_FT_UINT(hfinfo->type) || IS_FT_INT(hfinfo->type)))) {
2480 /* If we're fetching until the end of the TVB, only validate
2481 * that the offset is within range.
2487 tvb_ensure_bytes_exist(tvb, start, size);
2491 detect_trailing_stray_characters(guint encoding, const char *string, gint length, proto_item *pi)
2493 gboolean found_stray_character = FALSE;
2498 switch (encoding & ENC_CHARENCODING_MASK) {
2501 for (gint i = (gint)strlen(string); i < length; i++) {
2502 if (string[i] != '\0') {
2503 found_stray_character = TRUE;
2513 if (found_stray_character) {
2514 expert_add_info(NULL, pi, &ei_string_trailing_characters);
2518 /* Add an item to a proto_tree, using the text label registered to that item;
2519 the item is extracted from the tvbuff handed to it. */
2521 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2522 tvbuff_t *tvb, gint start, gint length,
2528 ws_in4_addr ipv4_value;
2531 const char *stringval = NULL;
2532 nstime_t time_stamp;
2533 gboolean length_error;
2535 switch (new_fi->hfinfo->type) {
2537 /* no value to set for FT_NONE */
2541 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
2545 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2549 n = get_uint_value(tree, tvb, start, length, encoding);
2550 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2552 /* Instead of calling proto_item_set_len(), since we don't yet
2553 * have a proto_item, we set the field_info's length ourselves. */
2554 new_fi->length = n + length;
2559 * Map all non-zero values to little-endian for
2560 * backwards compatibility.
2563 encoding = ENC_LITTLE_ENDIAN;
2564 proto_tree_set_boolean(new_fi,
2565 get_uint64_value(tree, tvb, start, length, encoding));
2569 /* XXX - make these just FT_UINT? */
2574 if (encoding & ENC_VARINT_PROTOBUF) {
2575 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2576 new_fi->flags |= FI_VARINT;
2577 value = (guint32)value64;
2578 } else if (encoding & ENC_VARINT_QUIC) {
2579 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2580 value = (guint32)value64;
2581 } else if (encoding & ENC_VARINT_ZIGZAG) {
2582 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2583 new_fi->flags |= FI_VARINT;
2584 value = (guint32)value64;
2588 * Map all non-zero values to little-endian for
2589 * backwards compatibility.
2592 encoding = ENC_LITTLE_ENDIAN;
2594 value = get_uint_value(tree, tvb, start, length, encoding);
2596 proto_tree_set_uint(new_fi, value);
2604 if (encoding & ENC_VARINT_PROTOBUF) {
2605 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2606 new_fi->flags |= FI_VARINT;
2607 } else if (encoding & ENC_VARINT_QUIC) {
2608 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2609 } else if (encoding & ENC_VARINT_ZIGZAG) {
2610 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2611 new_fi->flags |= FI_VARINT;
2615 * Map all other non-zero values to little-endian for
2616 * backwards compatibility.
2619 encoding = ENC_LITTLE_ENDIAN;
2621 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2623 proto_tree_set_uint64(new_fi, value64);
2626 /* XXX - make these just FT_INT? */
2632 * Map all non-zero values to little-endian for
2633 * backwards compatibility.
2636 encoding = ENC_LITTLE_ENDIAN;
2637 proto_tree_set_int(new_fi,
2638 get_int_value(tree, tvb, start, length, encoding));
2646 * Map all non-zero values to little-endian for
2647 * backwards compatibility.
2650 encoding = ENC_LITTLE_ENDIAN;
2651 proto_tree_set_int64(new_fi,
2652 get_int64_value(tree, tvb, start, length, encoding));
2657 * Map all non-zero values to little-endian for
2658 * backwards compatibility.
2661 encoding = ENC_LITTLE_ENDIAN;
2662 if (length != FT_IPv4_LEN) {
2663 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
2664 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2666 ipv4_value = tvb_get_ipv4(tvb, start);
2668 * NOTE: to support code written when
2669 * proto_tree_add_item() took a gboolean as its
2670 * last argument, with FALSE meaning "big-endian"
2671 * and TRUE meaning "little-endian", we treat any
2672 * non-zero value of "encoding" as meaning
2675 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value) : ipv4_value);
2679 if (length != FT_IPXNET_LEN) {
2680 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
2681 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2683 proto_tree_set_ipxnet(new_fi,
2684 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
2688 if (length != FT_IPv6_LEN) {
2689 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
2690 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2692 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2696 if (length != FT_FCWWN_LEN) {
2697 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2698 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2700 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2705 length_error = length < 7 ? TRUE : FALSE;
2706 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2708 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2712 if (length != VINES_ADDR_LEN) {
2713 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2714 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2716 proto_tree_set_vines_tvb(new_fi, tvb, start);
2720 if (length != FT_ETHER_LEN) {
2721 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2722 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2724 proto_tree_set_ether_tvb(new_fi, tvb, start);
2729 * Map all non-zero values to little-endian for
2730 * backwards compatibility.
2733 encoding = ENC_LITTLE_ENDIAN;
2734 if (length != FT_EUI64_LEN) {
2735 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2736 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2738 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2742 * Map all non-zero values to little-endian for
2743 * backwards compatibility.
2746 encoding = ENC_LITTLE_ENDIAN;
2747 if (length != FT_GUID_LEN) {
2748 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2749 report_type_length_mismatch(tree, "a GUID", length, length_error);
2751 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2756 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2760 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2765 * NOTE: to support code written when
2766 * proto_tree_add_item() took a gboolean as its
2767 * last argument, with FALSE meaning "big-endian"
2768 * and TRUE meaning "little-endian", we treat any
2769 * non-zero value of "encoding" as meaning
2772 * At some point in the future, we might
2773 * support non-IEEE-binary floating-point
2774 * formats in the encoding as well
2775 * (IEEE decimal, System/3x0, VAX).
2778 encoding = ENC_LITTLE_ENDIAN;
2780 length_error = length < 4 ? TRUE : FALSE;
2781 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2784 floatval = tvb_get_letohieee_float(tvb, start);
2786 floatval = tvb_get_ntohieee_float(tvb, start);
2787 proto_tree_set_float(new_fi, floatval);
2792 * NOTE: to support code written when
2793 * proto_tree_add_item() took a gboolean as its
2794 * last argument, with FALSE meaning "big-endian"
2795 * and TRUE meaning "little-endian", we treat any
2796 * non-zero value of "encoding" as meaning
2799 * At some point in the future, we might
2800 * support non-IEEE-binary floating-point
2801 * formats in the encoding as well
2802 * (IEEE decimal, System/3x0, VAX).
2804 if (encoding == TRUE)
2805 encoding = ENC_LITTLE_ENDIAN;
2807 length_error = length < 8 ? TRUE : FALSE;
2808 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2811 doubleval = tvb_get_letohieee_double(tvb, start);
2813 doubleval = tvb_get_ntohieee_double(tvb, start);
2814 proto_tree_set_double(new_fi, doubleval);
2818 stringval = get_string_value(wmem_packet_scope(),
2819 tvb, start, length, &length, encoding);
2820 proto_tree_set_string(new_fi, stringval);
2822 /* Instead of calling proto_item_set_len(), since we
2823 * don't yet have a proto_item, we set the
2824 * field_info's length ourselves.
2826 * XXX - our caller can't use that length to
2827 * advance an offset unless they arrange that
2828 * there always be a protocol tree into which
2829 * we're putting this item.
2831 new_fi->length = length;
2835 stringval = get_stringz_value(wmem_packet_scope(),
2836 tree, tvb, start, length, &length, encoding);
2837 proto_tree_set_string(new_fi, stringval);
2839 /* Instead of calling proto_item_set_len(),
2840 * since we don't yet have a proto_item, we
2841 * set the field_info's length ourselves.
2843 * XXX - our caller can't use that length to
2844 * advance an offset unless they arrange that
2845 * there always be a protocol tree into which
2846 * we're putting this item.
2848 new_fi->length = length;
2851 case FT_UINT_STRING:
2853 * NOTE: to support code written when
2854 * proto_tree_add_item() took a gboolean as its
2855 * last argument, with FALSE meaning "big-endian"
2856 * and TRUE meaning "little-endian", if the
2857 * encoding value is TRUE, treat that as
2858 * ASCII with a little-endian length.
2860 * This won't work for code that passes
2861 * arbitrary non-zero values; that code
2862 * will need to be fixed.
2864 if (encoding == TRUE)
2865 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2866 stringval = get_uint_string_value(wmem_packet_scope(),
2867 tree, tvb, start, length, &length, encoding);
2868 proto_tree_set_string(new_fi, stringval);
2870 /* Instead of calling proto_item_set_len(), since we
2871 * don't yet have a proto_item, we set the
2872 * field_info's length ourselves.
2874 * XXX - our caller can't use that length to
2875 * advance an offset unless they arrange that
2876 * there always be a protocol tree into which
2877 * we're putting this item.
2879 new_fi->length = length;
2883 stringval = get_stringzpad_value(wmem_packet_scope(),
2884 tvb, start, length, &length, encoding);
2885 proto_tree_set_string(new_fi, stringval);
2887 /* Instead of calling proto_item_set_len(), since we
2888 * don't yet have a proto_item, we set the
2889 * field_info's length ourselves.
2891 * XXX - our caller can't use that length to
2892 * advance an offset unless they arrange that
2893 * there always be a protocol tree into which
2894 * we're putting this item.
2896 new_fi->length = length;
2899 case FT_STRINGZTRUNC:
2900 stringval = get_stringztrunc_value(wmem_packet_scope(),
2901 tvb, start, length, &length, encoding);
2902 proto_tree_set_string(new_fi, stringval);
2904 /* Instead of calling proto_item_set_len(), since we
2905 * don't yet have a proto_item, we set the
2906 * field_info's length ourselves.
2908 * XXX - our caller can't use that length to
2909 * advance an offset unless they arrange that
2910 * there always be a protocol tree into which
2911 * we're putting this item.
2913 new_fi->length = length;
2916 case FT_ABSOLUTE_TIME:
2918 * Absolute times can be in any of a number of
2919 * formats, and they can be big-endian or
2922 * Historically FT_TIMEs were only timespecs;
2923 * the only question was whether they were stored
2924 * in big- or little-endian format.
2926 * For backwards compatibility, we interpret an
2927 * encoding of 1 as meaning "little-endian timespec",
2928 * so that passing TRUE is interpreted as that.
2930 if (encoding == TRUE)
2931 encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2933 get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
2935 proto_tree_set_time(new_fi, &time_stamp);
2938 case FT_RELATIVE_TIME:
2940 * Relative times can be in any of a number of
2941 * formats, and they can be big-endian or
2944 * Historically FT_TIMEs were only timespecs;
2945 * the only question was whether they were stored
2946 * in big- or little-endian format.
2948 * For backwards compatibility, we interpret an
2949 * encoding of 1 as meaning "little-endian timespec",
2950 * so that passing TRUE is interpreted as that.
2952 if (encoding == TRUE)
2953 encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2955 get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
2957 proto_tree_set_time(new_fi, &time_stamp);
2959 case FT_IEEE_11073_SFLOAT:
2961 encoding = ENC_LITTLE_ENDIAN;
2963 length_error = length < 2 ? TRUE : FALSE;
2964 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2967 fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2970 case FT_IEEE_11073_FLOAT:
2972 encoding = ENC_LITTLE_ENDIAN;
2974 length_error = length < 4 ? TRUE : FALSE;
2975 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2980 REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",
2981 new_fi->hfinfo->abbrev,
2982 new_fi->hfinfo->type,
2983 ftype_name(new_fi->hfinfo->type));
2986 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2988 /* Don't add new node to proto_tree until now so that any exceptions
2989 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2990 /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2991 * to know which item caused exception? */
2992 pi = proto_tree_add_node(tree, new_fi);
2994 switch (new_fi->hfinfo->type) {
2997 detect_trailing_stray_characters(encoding, stringval, length, pi);
3008 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3009 const gint start, gint length,
3010 const guint encoding, gint32 *retval)
3012 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3016 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3018 switch (hfinfo->type) {
3025 REPORT_DISSECTOR_BUG("64-bit signed integer field %s used with proto_tree_add_item_ret_int()",
3028 REPORT_DISSECTOR_BUG("Non-signed-integer field %s used with proto_tree_add_item_ret_int()",
3032 /* length validation for native number encoding caught by get_uint_value() */
3033 /* length has to be -1 or > 0 regardless of encoding */
3034 if (length < -1 || length == 0)
3035 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_int",
3038 if (encoding & ENC_STRING) {
3039 REPORT_DISSECTOR_BUG("wrong encoding");
3041 /* I believe it's ok if this is called with a NULL tree */
3042 value = get_int_value(tree, tvb, start, length, encoding);
3047 if (hfinfo->bitmask) {
3048 /* Mask out irrelevant portions */
3049 *retval &= (guint32)(hfinfo->bitmask);
3051 *retval >>= hfinfo_bitshift(hfinfo);
3053 no_of_bits = ws_count_ones(hfinfo->bitmask);
3054 *retval = ws_sign_ext32(*retval, no_of_bits);
3057 CHECK_FOR_NULL_TREE(tree);
3059 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3061 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3063 proto_tree_set_int(new_fi, value);
3065 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3067 return proto_tree_add_node(tree, new_fi);
3071 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3072 const gint start, gint length,
3073 const guint encoding, guint32 *retval)
3075 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3079 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3081 switch (hfinfo->type) {
3089 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
3093 /* length validation for native number encoding caught by get_uint_value() */
3094 /* length has to be -1 or > 0 regardless of encoding */
3095 if (length < -1 || length == 0)
3096 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3099 if (encoding & ENC_STRING) {
3100 REPORT_DISSECTOR_BUG("wrong encoding");
3102 /* I believe it's ok if this is called with a NULL tree */
3103 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3104 if (encoding & (ENC_VARIANT_MASK)) {
3106 tvb_get_varint(tvb, start, length, &temp64, encoding);
3107 value = (guint32)temp64;
3109 value = get_uint_value(tree, tvb, start, length, encoding);
3114 if (hfinfo->bitmask) {
3115 /* Mask out irrelevant portions */
3116 *retval &= (guint32)(hfinfo->bitmask);
3118 *retval >>= hfinfo_bitshift(hfinfo);
3122 CHECK_FOR_NULL_TREE(tree);
3124 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3126 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3128 proto_tree_set_uint(new_fi, value);
3130 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3131 if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
3132 new_fi->flags |= FI_VARINT;
3134 return proto_tree_add_node(tree, new_fi);
3137 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3138 * and returns proto_item* and uint value retreived*/
3140 ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, gint length,
3141 const guint encoding, guint32 *retval)
3144 header_field_info *hfinfo;
3149 offset = ptvc->offset;
3150 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3152 switch (hfinfo->type) {
3160 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
3164 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3165 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3167 /* I believe it's ok if this is called with a NULL tree */
3168 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3169 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3173 if (hfinfo->bitmask) {
3174 /* Mask out irrelevant portions */
3175 *retval &= (guint32)(hfinfo->bitmask);
3177 *retval >>= hfinfo_bitshift(hfinfo);
3181 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3182 item_length, encoding);
3184 CHECK_FOR_NULL_TREE(ptvc->tree);
3186 /* Coast clear. Try and fake it */
3187 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3189 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3191 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3192 offset, length, encoding);
3195 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3196 * and returns proto_item* and int value retreived*/
3198 ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, gint length,
3199 const guint encoding, gint32 *retval)
3202 header_field_info *hfinfo;
3207 offset = ptvc->offset;
3208 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3210 switch (hfinfo->type) {
3217 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
3221 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3222 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3224 /* I believe it's ok if this is called with a NULL tree */
3225 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3226 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3231 if (hfinfo->bitmask) {
3232 /* Mask out irrelevant portions */
3233 *retval &= (guint32)(hfinfo->bitmask);
3235 *retval >>= hfinfo_bitshift(hfinfo);
3237 no_of_bits = ws_count_ones(hfinfo->bitmask);
3238 *retval = ws_sign_ext32(*retval, no_of_bits);
3241 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3242 item_length, encoding);
3244 CHECK_FOR_NULL_TREE(ptvc->tree);
3246 /* Coast clear. Try and fake it */
3247 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3249 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3251 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3252 offset, length, encoding);
3255 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3256 * and returns proto_item* and string value retreived */
3258 ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, wmem_allocator_t *scope, const guint8 **retval)
3260 header_field_info *hfinfo;
3262 const guint8 *value;
3266 offset = ptvc->offset;
3268 PROTO_REGISTRAR_GET_NTH(hf, hfinfo);
3270 switch (hfinfo->type) {
3272 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3275 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3277 case FT_UINT_STRING:
3278 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3281 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3283 case FT_STRINGZTRUNC:
3284 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3287 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
3294 ptvc->offset += item_length;
3296 CHECK_FOR_NULL_TREE(ptvc->tree);
3298 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3300 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3302 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3303 offset, length, encoding);
3306 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3307 * and returns proto_item* and boolean value retreived */
3309 ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, gint length, const guint encoding, gboolean *retval)
3311 header_field_info *hfinfo;
3315 guint64 value, bitval;
3317 offset = ptvc->offset;
3318 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3320 if (hfinfo->type != FT_BOOLEAN) {
3321 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3325 /* length validation for native number encoding caught by get_uint64_value() */
3326 /* length has to be -1 or > 0 regardless of encoding */
3327 if (length < -1 || length == 0)
3328 REPORT_DISSECTOR_BUG("Invalid length %d passed to ptvcursor_add_ret_boolean",
3331 if (encoding & ENC_STRING) {
3332 REPORT_DISSECTOR_BUG("wrong encoding");
3335 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3336 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3338 /* I believe it's ok if this is called with a NULL tree */
3339 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3343 if (hfinfo->bitmask) {
3344 /* Mask out irrelevant portions */
3345 bitval &= hfinfo->bitmask;
3347 *retval = (bitval != 0);
3350 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3351 item_length, encoding);
3353 CHECK_FOR_NULL_TREE(ptvc->tree);
3355 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3357 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3359 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3360 offset, length, encoding);
3364 proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3365 const gint start, gint length, const guint encoding, guint64 *retval)
3367 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3371 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3373 switch (hfinfo->type) {
3380 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
3384 /* length validation for native number encoding caught by get_uint64_value() */
3385 /* length has to be -1 or > 0 regardless of encoding */
3386 if (length < -1 || length == 0)
3387 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint64",
3390 if (encoding & ENC_STRING) {
3391 REPORT_DISSECTOR_BUG("wrong encoding");
3393 /* I believe it's ok if this is called with a NULL tree */
3394 if (encoding & (ENC_VARIANT_MASK)) {
3395 tvb_get_varint(tvb, start, length, &value, encoding);
3397 value = get_uint64_value(tree, tvb, start, length, encoding);
3402 if (hfinfo->bitmask) {
3403 /* Mask out irrelevant portions */
3404 *retval &= hfinfo->bitmask;
3406 *retval >>= hfinfo_bitshift(hfinfo);
3410 CHECK_FOR_NULL_TREE(tree);
3412 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3414 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3416 proto_tree_set_uint64(new_fi, value);
3418 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3419 if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
3420 new_fi->flags |= FI_VARINT;
3423 return proto_tree_add_node(tree, new_fi);
3427 proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3428 const gint start, gint length, const guint encoding, gint64 *retval)
3430 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3434 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3436 switch (hfinfo->type) {
3443 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
3447 /* length validation for native number encoding caught by get_uint64_value() */
3448 /* length has to be -1 or > 0 regardless of encoding */
3449 if (length < -1 || length == 0)
3450 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_int64",
3453 if (encoding & ENC_STRING) {
3454 REPORT_DISSECTOR_BUG("wrong encoding");
3456 /* I believe it's ok if this is called with a NULL tree */
3457 if (encoding & (ENC_VARIANT_MASK)) {
3458 tvb_get_varint(tvb, start, length, &value, encoding);
3461 value = get_int64_value(tree, tvb, start, length, encoding);
3468 CHECK_FOR_NULL_TREE(tree);
3470 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3472 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3474 proto_tree_set_int64(new_fi, value);
3476 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3477 if (encoding & (ENC_VARINT_PROTOBUF | ENC_VARINT_ZIGZAG)) {
3478 new_fi->flags |= FI_VARINT;
3481 return proto_tree_add_node(tree, new_fi);
3485 proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3486 const gint start, gint length, const guint encoding, guint64 *retval, gint *lenretval)
3488 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3492 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3494 if ((!IS_FT_INT(hfinfo->type)) && (!IS_FT_UINT(hfinfo->type))) {
3495 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",
3499 /* length validation for native number encoding caught by get_uint64_value() */
3500 /* length has to be -1 or > 0 regardless of encoding */
3502 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",
3505 if (encoding & ENC_STRING) {
3506 REPORT_DISSECTOR_BUG("wrong encoding");
3509 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value, encoding);
3513 if (hfinfo->bitmask) {
3514 /* Mask out irrelevant portions */
3515 *retval &= hfinfo->bitmask;
3517 *retval >>= hfinfo_bitshift(hfinfo);
3522 *lenretval = length;
3525 CHECK_FOR_NULL_TREE(tree);
3527 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3529 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3531 proto_tree_set_uint64(new_fi, value);
3533 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3534 if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
3535 new_fi->flags |= FI_VARINT;
3538 return proto_tree_add_node(tree, new_fi);
3543 proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3544 const gint start, gint length,
3545 const guint encoding, gboolean *retval)
3547 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3549 guint64 value, bitval;
3551 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3553 if (hfinfo->type != FT_BOOLEAN) {
3554 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3558 /* length validation for native number encoding caught by get_uint64_value() */
3559 /* length has to be -1 or > 0 regardless of encoding */
3560 if (length < -1 || length == 0)
3561 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_boolean",
3564 if (encoding & ENC_STRING) {
3565 REPORT_DISSECTOR_BUG("wrong encoding");
3567 /* I believe it's ok if this is called with a NULL tree */
3568 value = get_uint64_value(tree, tvb, start, length, encoding);
3572 if (hfinfo->bitmask) {
3573 /* Mask out irrelevant portions */
3574 bitval &= hfinfo->bitmask;
3576 *retval = (bitval != 0);
3579 CHECK_FOR_NULL_TREE(tree);
3581 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3583 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3585 proto_tree_set_boolean(new_fi, value);
3587 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3589 return proto_tree_add_node(tree, new_fi);
3593 proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3594 const gint start, gint length,
3595 const guint encoding, ws_in4_addr *retval)
3597 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3601 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3603 switch (hfinfo->type) {
3607 REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv4",
3611 if (length != FT_IPv4_LEN)
3612 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv4",
3615 if (encoding & (ENC_STRING | ENC_VARIANT_MASK | ENC_VARINT_PROTOBUF | ENC_VARINT_ZIGZAG)) {
3616 REPORT_DISSECTOR_BUG("wrong encoding");
3620 * NOTE: to support code written when proto_tree_add_item() took
3621 * a gboolean as its last argument, with FALSE meaning "big-endian"
3622 * and TRUE meaning "little-endian", we treat any non-zero value
3623 * of "encoding" as meaning "little-endian".
3625 value = tvb_get_ipv4(tvb, start);
3627 value = GUINT32_SWAP_LE_BE(value);
3633 CHECK_FOR_NULL_TREE(tree);
3635 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3637 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3639 proto_tree_set_ipv4(new_fi, value);
3641 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3642 return proto_tree_add_node(tree, new_fi);
3646 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
3648 const gint start, gint length,
3649 const guint encoding,
3650 wmem_allocator_t *scope,
3651 const guint8 **retval,
3655 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3657 const guint8 *value;
3659 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3661 switch (hfinfo->type) {
3663 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
3666 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
3668 case FT_UINT_STRING:
3669 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
3672 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
3674 case FT_STRINGZTRUNC:
3675 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
3678 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
3685 CHECK_FOR_NULL_TREE(tree);
3687 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3689 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
3691 proto_tree_set_string(new_fi, value);
3693 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3695 pi = proto_tree_add_node(tree, new_fi);
3697 switch (hfinfo->type) {
3701 case FT_STRINGZTRUNC:
3702 case FT_UINT_STRING:
3706 detect_trailing_stray_characters(encoding, value, length, pi);
3710 g_assert_not_reached();
3717 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3718 const gint start, gint length,
3719 const guint encoding, wmem_allocator_t *scope,
3720 const guint8 **retval)
3722 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
3723 tvb, start, length, encoding, scope, retval, &length);
3727 proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
3729 const gint start, gint length,
3730 const guint encoding,
3731 wmem_allocator_t *scope,
3736 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3738 const guint8 *value;
3741 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3743 switch (hfinfo->type) {
3745 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
3746 *retval = hfinfo_format_text(scope, hfinfo, value);
3749 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
3750 *retval = hfinfo_format_text(scope, hfinfo, value);
3752 case FT_UINT_STRING:
3753 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
3754 *retval = hfinfo_format_text(scope, hfinfo, value);
3757 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
3758 *retval = hfinfo_format_text(scope, hfinfo, value);
3760 case FT_STRINGZTRUNC:
3761 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
3762 *retval = hfinfo_format_text(scope, hfinfo, value);
3765 value = tvb_get_ptr(tvb, start, length);
3766 *retval = hfinfo_format_bytes(scope, hfinfo, value, length);
3767 *lenretval = length;
3770 n = get_uint_value(tree, tvb, start, length, encoding);
3771 value = tvb_get_ptr(tvb, start + length, n);
3772 *retval = hfinfo_format_bytes(scope, hfinfo, value, n);
3773 *lenretval = length + n;
3776 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES",
3780 CHECK_FOR_NULL_TREE(tree);
3782 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3784 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
3786 switch (hfinfo->type) {
3790 case FT_UINT_STRING:
3792 case FT_STRINGZTRUNC:
3793 proto_tree_set_string(new_fi, value);
3797 proto_tree_set_bytes(new_fi, value, length);
3801 proto_tree_set_bytes(new_fi, value, n);
3805 g_assert_not_reached();
3808 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3810 pi = proto_tree_add_node(tree, new_fi);
3812 switch (hfinfo->type) {
3816 case FT_STRINGZTRUNC:
3817 case FT_UINT_STRING:
3821 detect_trailing_stray_characters(encoding, value, length, pi);
3829 g_assert_not_reached();
3836 proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
3838 const gint start, gint length,
3839 const guint encoding,
3840 wmem_allocator_t *scope,
3843 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
3844 tvb, start, length, encoding, scope, retval, &length);
3848 proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
3850 const gint start, gint length, const guint encoding,
3851 wmem_allocator_t *scope, char **retval)
3853 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3855 nstime_t time_stamp;
3857 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3859 switch (hfinfo->type) {
3860 case FT_ABSOLUTE_TIME:
3861 get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
3862 *retval = abs_time_to_str(scope, &time_stamp, (absolute_time_display_e)hfinfo->display, TRUE);
3864 case FT_RELATIVE_TIME:
3865 get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
3866 *retval = rel_time_to_secs_str(scope, &time_stamp);
3869 REPORT_DISSECTOR_BUG("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME",
3873 CHECK_FOR_NULL_TREE(tree);
3875 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3877 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3879 switch (hfinfo->type) {
3881 case FT_ABSOLUTE_TIME:
3882 case FT_RELATIVE_TIME:
3883 proto_tree_set_time(new_fi, &time_stamp);
3886 g_assert_not_reached();
3889 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3891 return proto_tree_add_node(tree, new_fi);
3894 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3895 and returns proto_item* */
3897 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
3898 const guint encoding)
3901 header_field_info *hfinfo;
3905 offset = ptvc->offset;
3906 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3907 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3908 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3910 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3911 item_length, encoding);
3913 CHECK_FOR_NULL_TREE(ptvc->tree);
3915 /* Coast clear. Try and fake it */
3916 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3918 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3920 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3921 offset, length, encoding);
3924 /* Add an item to a proto_tree, using the text label registered to that item;
3925 the item is extracted from the tvbuff handed to it. */
3927 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
3928 const gint start, gint length, const guint encoding)
3933 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3935 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3936 test_length(hfinfo, tvb, start, item_length, encoding);
3938 CHECK_FOR_NULL_TREE(tree);
3940 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3942 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3944 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3948 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3949 const gint start, gint length, const guint encoding)
3951 register header_field_info *hfinfo;
3953 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3954 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
3957 /* Add an item to a proto_tree, using the text label registered to that item;
3958 the item is extracted from the tvbuff handed to it.
3960 Return the length of the item through the pointer. */
3962 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
3963 tvbuff_t *tvb, const gint start,
3964 gint length, const guint encoding,
3971 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3973 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3974 test_length(hfinfo, tvb, start, item_length, encoding);
3978 * We need to get the correct item length here.
3979 * That's normally done by proto_tree_new_item(),
3980 * but we won't be calling it.
3982 *lenretval = get_full_length(hfinfo, tvb, start, length,
3983 item_length, encoding);
3987 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
3989 * Even if the tree item is not referenced (and thus faked),
3990 * the caller must still be informed of the actual length.
3992 *lenretval = get_full_length(hfinfo, tvb, start, length,
3993 item_length, encoding);
3996 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3998 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3999 *lenretval = new_fi->length;
4004 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4005 const gint start, gint length,
4006 const guint encoding, gint *lenretval)
4008 register header_field_info *hfinfo;
4010 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4011 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4014 /* which FT_ types can use proto_tree_add_bytes_item() */
4015 static inline gboolean
4016 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4018 return (type == FT_BYTES ||
4019 type == FT_UINT_BYTES ||
4021 type == FT_REL_OID ||
4022 type == FT_SYSTEM_ID );
4025 /* Note: this does no validation that the byte array of an FT_OID or
4026 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4027 so I think it's ok to continue not validating it?
4030 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4031 const gint start, gint length, const guint encoding,
4032 GByteArray *retval, gint *endoff, gint *err)
4035 GByteArray *bytes = retval;
4036 GByteArray *created_bytes = NULL;
4039 header_field_info *hfinfo;
4040 gboolean generate = (bytes || tree) ? TRUE : FALSE;
4042 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4044 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4046 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
4047 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
4049 /* length has to be -1 or > 0 regardless of encoding */
4050 /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
4051 if (length < -1 || length == 0) {
4052 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_bytes_item for %s",
4053 length, ftype_name(hfinfo->type));
4056 if (encoding & ENC_STR_NUM) {
4057 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
4060 if (generate && (encoding & ENC_STR_HEX)) {
4061 if (hfinfo->type == FT_UINT_BYTES) {
4062 /* can't decode FT_UINT_BYTES from strings */
4063 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
4064 "FT_UINT_BYTES type, but as ENC_STR_HEX");
4068 /* caller doesn't care about return value, but we need it to
4069 call tvb_get_string_bytes() and set the tree later */
4070 bytes = created_bytes = g_byte_array_new();
4073 /* bytes might be NULL after this, but can't add expert error until later */
4074 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
4076 /* grab the errno now before it gets overwritten */
4079 else if (generate) {
4080 tvb_ensure_bytes_exist(tvb, start, length);
4083 /* caller doesn't care about return value, but we need it to
4084 call tvb_get_string_bytes() and set the tree later */
4085 bytes = created_bytes = g_byte_array_new();
4088 if (hfinfo->type == FT_UINT_BYTES) {
4089 n = length; /* n is now the "header" length */
4090 length = get_uint_value(tree, tvb, start, n, encoding);
4091 /* length is now the value's length; only store the value in the array */
4092 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4094 else if (length > 0) {
4095 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4099 *endoff = start + n + length;
4102 if (err) *err = saved_err;
4104 CHECK_FOR_NULL_TREE_AND_FREE(tree,
4107 g_byte_array_free(created_bytes, TRUE);
4108 created_bytes = NULL;
4112 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
4115 g_byte_array_free(created_bytes, TRUE);
4116 created_bytes = NULL;
4120 /* n will be zero except when it's a FT_UINT_BYTES */
4121 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4123 if (encoding & ENC_STRING) {
4124 if (saved_err == ERANGE)
4125 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
4126 else if (!bytes || saved_err != 0)
4127 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
4130 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4132 proto_tree_set_bytes(new_fi, NULL, 0);
4135 g_byte_array_free(created_bytes, TRUE);
4138 /* n will be zero except when it's a FT_UINT_BYTES */
4139 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4142 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
4145 return proto_tree_add_node(tree, new_fi);
4150 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4151 const gint start, gint length, const guint encoding,
4152 nstime_t *retval, gint *endoff, gint *err)
4155 nstime_t time_stamp;
4157 header_field_info *hfinfo;
4159 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4161 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4163 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
4165 /* length has to be -1 or > 0 regardless of encoding */
4166 if (length < -1 || length == 0) {
4167 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_time_item",
4171 time_stamp.secs = 0;
4172 time_stamp.nsecs = 0;
4174 if (encoding & ENC_STR_TIME_MASK) {
4175 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
4176 /* grab the errno now before it gets overwritten */
4180 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
4182 tvb_ensure_bytes_exist(tvb, start, length);
4183 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4184 if (endoff) *endoff = length;
4187 if (err) *err = saved_err;
4190 retval->secs = time_stamp.secs;
4191 retval->nsecs = time_stamp.nsecs;
4194 CHECK_FOR_NULL_TREE(tree);
4196 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4198 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4200 proto_tree_set_time(new_fi, &time_stamp);
4202 if (encoding & ENC_STRING) {
4203 if (saved_err == ERANGE)
4204 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
4205 else if (saved_err == EDOM)
4206 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
4210 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
4213 return proto_tree_add_node(tree, new_fi);
4216 /* Add a FT_NONE to a proto_tree */
4218 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4219 const gint start, gint length, const char *format,
4224 header_field_info *hfinfo;
4226 CHECK_FOR_NULL_TREE(tree);
4228 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4230 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
4232 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4234 TRY_TO_FAKE_THIS_REPR(pi);
4236 va_start(ap, format);
4237 proto_tree_set_representation(pi, format, ap);
4240 /* no value to set for FT_NONE */
4244 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4245 * offset, and returns proto_item* */
4247 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
4248 const guint encoding)
4252 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4258 /* Advance the ptvcursor's offset within its tvbuff without
4259 * adding anything to the proto_tree. */
4261 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
4263 ptvc->offset += length;
4268 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
4270 fvalue_set_protocol(&fi->value, tvb, field_data);
4273 /* Add a FT_PROTOCOL to a proto_tree */
4275 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4276 gint start, gint length, const char *format, ...)
4279 tvbuff_t *protocol_tvb;
4281 header_field_info *hfinfo;
4282 gchar* protocol_rep;
4284 CHECK_FOR_NULL_TREE(tree);
4286 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4288 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
4291 * This can throw an exception, so do it before we allocate anything.
4293 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4295 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4297 va_start(ap, format);
4298 protocol_rep = g_strdup_vprintf(format, ap);
4299 proto_tree_set_protocol_tvb(PNODE_FINFO(pi), protocol_tvb, protocol_rep);
4300 g_free(protocol_rep);
4303 TRY_TO_FAKE_THIS_REPR(pi);
4305 va_start(ap, format);
4306 proto_tree_set_representation(pi, format, ap);
4312 /* Add a FT_BYTES to a proto_tree */
4314 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4315 gint length, const guint8 *start_ptr)
4318 header_field_info *hfinfo;
4321 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4322 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
4323 test_length(hfinfo, tvb, start, item_length, ENC_NA);
4325 CHECK_FOR_NULL_TREE(tree);
4327 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4329 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
4331 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4332 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
4337 /* Add a FT_BYTES to a proto_tree */
4339 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4340 gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
4343 header_field_info *hfinfo;
4346 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4347 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA);
4348 test_length(hfinfo, tvb, start, item_length, ENC_NA);
4350 CHECK_FOR_NULL_TREE(tree);
4352 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4354 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
4356 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4357 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
4363 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4364 gint start, gint length,
4365 const guint8 *start_ptr,
4366 const char *format, ...)
4371 if (start_ptr == NULL)
4372 start_ptr = tvb_get_ptr(tvb, start, length);
4374 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4376 TRY_TO_FAKE_THIS_REPR_NESTED(pi);
4378 va_start(ap, format);
4379 proto_tree_set_representation_value(pi, format, ap);
4386 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4387 gint start, gint length, const guint8 *start_ptr,
4388 const char *format, ...)
4393 if (start_ptr == NULL)
4394 start_ptr = tvb_get_ptr(tvb, start, length);
4396 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4398 TRY_TO_FAKE_THIS_REPR_NESTED(pi);
4400 va_start(ap, format);
4401 proto_tree_set_representation(pi, format, ap);
4408 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
4412 DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
4414 bytes = g_byte_array_new();
4416 g_byte_array_append(bytes, start_ptr, length);
4418 fvalue_set_byte_array(&fi->value, bytes);
4423 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
4425 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4429 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4433 DISSECTOR_ASSERT(value != NULL);
4435 bytes = byte_array_dup(value);
4437 fvalue_set_byte_array(&fi->value, bytes);
4440 /* Add a FT_*TIME to a proto_tree */
4442 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4443 gint length, const nstime_t *value_ptr)
4446 header_field_info *hfinfo;
4448 CHECK_FOR_NULL_TREE(tree);
4450 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4452 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
4454 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4455 proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
4461 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4462 gint start, gint length, nstime_t *value_ptr,
4463 const char *format, ...)
4468 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4470 va_start(ap, format);
4471 proto_tree_set_representation_value(pi, format, ap);
4479 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4480 gint start, gint length, nstime_t *value_ptr,
4481 const char *format, ...)
4486 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4488 TRY_TO_FAKE_THIS_REPR(pi);
4490 va_start(ap, format);
4491 proto_tree_set_representation(pi, format, ap);
4498 /* Set the FT_*TIME value */
4500 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4502 DISSECTOR_ASSERT(value_ptr != NULL);
4504 fvalue_set_time(&fi->value, value_ptr);
4507 /* Add a FT_IPXNET to a proto_tree */
4509 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4510 gint length, guint32 value)
4513 header_field_info *hfinfo;
4515 CHECK_FOR_NULL_TREE(tree);
4517 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4519 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
4521 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4522 proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
4528 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4529 gint start, gint length, guint32 value,
4530 const char *format, ...)
4535 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4537 va_start(ap, format);
4538 proto_tree_set_representation_value(pi, format, ap);
4546 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4547 gint start, gint length, guint32 value,
4548 const char *format, ...)
4553 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4555 TRY_TO_FAKE_THIS_REPR(pi);
4557 va_start(ap, format);
4558 proto_tree_set_representation(pi, format, ap);
4565 /* Set the FT_IPXNET value */
4567 proto_tree_set_ipxnet(field_info *fi, guint32 value)
4569 fvalue_set_uinteger(&fi->value, value);
4572 /* Add a FT_IPv4 to a proto_tree */
4574 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4575 gint length, ws_in4_addr value)
4578 header_field_info *hfinfo;
4580 CHECK_FOR_NULL_TREE(tree);
4582 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4584 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
4586 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4587 proto_tree_set_ipv4(PNODE_FINFO(pi), value);
4593 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4594 gint start, gint length, ws_in4_addr value,
4595 const char *format, ...)
4600 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
4602 va_start(ap, format);
4603 proto_tree_set_representation_value(pi, format, ap);
4611 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4612 gint start, gint length, ws_in4_addr value,
4613 const char *format, ...)
4618 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
4620 TRY_TO_FAKE_THIS_REPR(pi);
4622 va_start(ap, format);
4623 proto_tree_set_representation(pi, format, ap);
4630 /* Set the FT_IPv4 value */
4632 proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
4634 fvalue_set_uinteger(&fi->value, value);
4637 /* Add a FT_IPv6 to a proto_tree */
4639 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4640 gint length, const ws_in6_addr *value_ptr)
4643 header_field_info *hfinfo;
4645 CHECK_FOR_NULL_TREE(tree);
4647 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4649 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
4651 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4652 proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
4658 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4659 gint start, gint length,
4660 const ws_in6_addr *value_ptr,
4661 const char *format, ...)
4666 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
4668 va_start(ap, format);
4669 proto_tree_set_representation_value(pi, format, ap);
4677 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4678 gint start, gint length,
4679 const ws_in6_addr *value_ptr,
4680 const char *format, ...)
4685 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
4687 TRY_TO_FAKE_THIS_REPR(pi);
4689 va_start(ap, format);
4690 proto_tree_set_representation(pi, format, ap);
4697 /* Set the FT_IPv6 value */
4699 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
4701 DISSECTOR_ASSERT(value_ptr != NULL);
4702 fvalue_set_bytes(&fi->value, value_ptr);
4706 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4708 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
4711 /* Set the FT_FCWWN value */
4713 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
4715 DISSECTOR_ASSERT(value_ptr != NULL);
4716 fvalue_set_bytes(&fi->value, value_ptr);
4720 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4722 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
4725 /* Add a FT_GUID to a proto_tree */
4727 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4728 gint length, const e_guid_t *value_ptr)
4731 header_field_info *hfinfo;
4733 CHECK_FOR_NULL_TREE(tree);
4735 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4737 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
4739 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4740 proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
4746 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4747 gint start, gint length,
4748 const e_guid_t *value_ptr,
4749 const char *format, ...)
4754 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4756 va_start(ap, format);
4757 proto_tree_set_representation_value(pi, format, ap);
4765 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4766 gint start, gint length, const e_guid_t *value_ptr,
4767 const char *format, ...)
4772 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4774 TRY_TO_FAKE_THIS_REPR(pi);
4776 va_start(ap, format);
4777 proto_tree_set_representation(pi, format, ap);
4784 /* Set the FT_GUID value */
4786 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
4788 DISSECTOR_ASSERT(value_ptr != NULL);
4789 fvalue_set_guid(&fi->value, value_ptr);
4793 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
4794 const guint encoding)
4798 tvb_get_guid(tvb, start, &guid, encoding);
4799 proto_tree_set_guid(fi, &guid);
4802 /* Add a FT_OID to a proto_tree */
4804 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4805 gint length, const guint8* value_ptr)
4808 header_field_info *hfinfo;
4810 CHECK_FOR_NULL_TREE(tree);
4812 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4814 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
4816 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4817 proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
4823 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4824 gint start, gint length,
4825 const guint8* value_ptr,
4826 const char *format, ...)
4831 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4833 va_start(ap, format);
4834 proto_tree_set_representation_value(pi, format, ap);
4842 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4843 gint start, gint length, const guint8* value_ptr,
4844 const char *format, ...)
4849 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4851 TRY_TO_FAKE_THIS_REPR(pi);
4853 va_start(ap, format);
4854 proto_tree_set_representation(pi, format, ap);
4861 /* Set the FT_OID value */
4863 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
4867 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4869 bytes = g_byte_array_new();
4871 g_byte_array_append(bytes, value_ptr, length);
4873 fvalue_set_byte_array(&fi->value, bytes);
4877 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4879 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
4882 /* Set the FT_SYSTEM_ID value */
4884 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
4888 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4890 bytes = g_byte_array_new();
4892 g_byte_array_append(bytes, value_ptr, length);
4894 fvalue_set_byte_array(&fi->value, bytes);
4898 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4900 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
4903 /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
4904 * proto_tree. Creates own copy of string, and frees it when the proto_tree
4907 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4908 gint length, const char* value)
4911 header_field_info *hfinfo;
4914 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4915 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
4917 * Special case - if the length is 0, skip the test, so that
4918 * we can have an empty string right after the end of the
4919 * packet. (This handles URL-encoded forms where the last field
4920 * has no value so the form ends right after the =.)
4922 if (item_length != 0)
4923 test_length(hfinfo, tvb, start, item_length, ENC_NA);
4925 CHECK_FOR_NULL_TREE(tree);
4927 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4929 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
4931 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4932 DISSECTOR_ASSERT(length >= 0);
4933 proto_tree_set_string(PNODE_FINFO(pi), value);
4939 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4940 gint start, gint length, const char* value,
4947 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4949 va_start(ap, format);
4950 proto_tree_set_representation_value(pi, format, ap);
4958 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4959 gint start, gint length, const char* value,
4960 const char *format, ...)
4965 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4967 TRY_TO_FAKE_THIS_REPR(pi);
4969 va_start(ap, format);
4970 proto_tree_set_representation(pi, format, ap);
4977 /* Set the FT_STRING value */
4979 proto_tree_set_string(field_info *fi, const char* value)
4982 fvalue_set_string(&fi->value, value);
4985 * XXX - why is a null value for a string field
4988 fvalue_set_string(&fi->value, "[ Null ]");
4992 /* Set the FT_AX25 value */
4994 proto_tree_set_ax25(field_info *fi, const guint8* value)
4996 fvalue_set_bytes(&fi->value, value);
5000 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
5002 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5005 /* Set the FT_VINES value */
5007 proto_tree_set_vines(field_info *fi, const guint8* value)
5009 fvalue_set_bytes(&fi->value, value);
5013 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
5015 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
5018 /* Add a FT_ETHER to a proto_tree */
5020 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5021 gint length, const guint8* value)
5024 header_field_info *hfinfo;
5026 CHECK_FOR_NULL_TREE(tree);
5028 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5030 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
5032 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5033 proto_tree_set_ether(PNODE_FINFO(pi), value);
5039 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5040 gint start, gint length, const guint8* value,
5041 const char *format, ...)
5046 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5048 va_start(ap, format);
5049 proto_tree_set_representation_value(pi, format, ap);
5057 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5058 gint start, gint length, const guint8* value,
5059 const char *format, ...)
5064 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5066 TRY_TO_FAKE_THIS_REPR(pi);
5068 va_start(ap, format);
5069 proto_tree_set_representation(pi, format, ap);
5076 /* Set the FT_ETHER value */
5078 proto_tree_set_ether(field_info *fi, const guint8* value)
5080 fvalue_set_bytes(&fi->value, value);
5084 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
5086 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
5089 /* Add a FT_BOOLEAN to a proto_tree */
5091 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5092 gint length, guint32 value)
5095 header_field_info *hfinfo;
5097 CHECK_FOR_NULL_TREE(tree);
5099 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5101 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
5103 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5104 proto_tree_set_boolean(PNODE_FINFO(pi), value);
5110 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5111 tvbuff_t *tvb, gint start, gint length,
5112 guint32 value, const char *format, ...)
5117 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5119 va_start(ap, format);
5120 proto_tree_set_representation_value(pi, format, ap);
5128 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5129 gint start, gint length, guint32 value,
5130 const char *format, ...)
5135 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5137 TRY_TO_FAKE_THIS_REPR(pi);
5139 va_start(ap, format);
5140 proto_tree_set_representation(pi, format, ap);
5148 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5149 gint length, guint64 value)
5152 header_field_info *hfinfo;
5154 CHECK_FOR_NULL_TREE(tree);
5156 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5158 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
5160 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5161 proto_tree_set_boolean(PNODE_FINFO(pi), value);
5166 /* Set the FT_BOOLEAN value */
5168 proto_tree_set_boolean(field_info *fi, guint64 value)
5170 proto_tree_set_uint64(fi, value);
5173 /* Generate, into "buf", a string showing the bits of a bitfield.
5174 Return a pointer to the character after that string. */
5176 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
5185 /* This is a devel error. It is safer to stop here. */
5186 DISSECTOR_ASSERT(width >= 1);
5188 bit = G_GUINT64_CONSTANT(1) << (width - 1);
5191 /* This bit is part of the field. Show its value. */
5197 /* This bit is not part of the field. */
5212 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
5216 p = other_decode_bitfield_value(buf, val, mask, width);
5217 p = g_stpcpy(p, " = ");
5223 other_decode_bitfield_varint_value(char *buf, guint64 val, guint64 mask, const int width)
5230 bit = G_GUINT64_CONSTANT(1) << (width - 1);
5232 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5234 /* This bit is part of the field. Show its value. */
5240 /* This bit is not part of the field. */
5256 decode_bitfield_varint_value(char *buf, const guint64 val, const guint64 mask, const int width)
5260 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5261 p = g_stpcpy(p, " = ");
5266 /* Add a FT_FLOAT to a proto_tree */
5268 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5269 gint length, float value)
5272 header_field_info *hfinfo;
5274 CHECK_FOR_NULL_TREE(tree);
5276 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5278 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
5280 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5281 proto_tree_set_float(PNODE_FINFO(pi), value);
5287 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5288 gint start, gint length, float value,
5289 const char *format, ...)
5294 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5296 va_start(ap, format);
5297 proto_tree_set_representation_value(pi, format, ap);
5305 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5306 gint start, gint length, float value,
5307 const char *format, ...)
5312 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5314 TRY_TO_FAKE_THIS_REPR(pi);
5316 va_start(ap, format);
5317 proto_tree_set_representation(pi, format, ap);
5324 /* Set the FT_FLOAT value */
5326 proto_tree_set_float(field_info *fi, float value)
5328 fvalue_set_floating(&fi->value, value);
5331 /* Add a FT_DOUBLE to a proto_tree */
5333 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5334 gint length, double value)
5337 header_field_info *hfinfo;
5339 CHECK_FOR_NULL_TREE(tree);
5341 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5343 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
5345 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5346 proto_tree_set_double(PNODE_FINFO(pi), value);
5352 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5353 gint start, gint length, double value,
5354 const char *format, ...)
5359 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5361 va_start(ap, format);
5362 proto_tree_set_representation_value(pi, format, ap);
5370 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5371 gint start, gint length, double value,
5372 const char *format, ...)
5377 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5379 TRY_TO_FAKE_THIS_REPR(pi);
5381 va_start(ap, format);
5382 proto_tree_set_representation(pi, format, ap);
5389 /* Set the FT_DOUBLE value */
5391 proto_tree_set_double(field_info *fi, double value)
5393 fvalue_set_floating(&fi->value, value);
5396 /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5398 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5399 gint length, guint32 value)
5401 proto_item *pi = NULL;
5402 header_field_info *hfinfo;
5404 CHECK_FOR_NULL_TREE(tree);
5406 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5408 switch (hfinfo->type) {
5415 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5416 proto_tree_set_uint(PNODE_FINFO(pi), value);
5420 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",
5428 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5429 gint start, gint length, guint32 value,
5430 const char *format, ...)
5435 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5437 va_start(ap, format);
5438 proto_tree_set_representation_value(pi, format, ap);
5446 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5447 gint start, gint length, guint32 value,
5448 const char *format, ...)
5453 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5455 TRY_TO_FAKE_THIS_REPR(pi);
5457 va_start(ap, format);
5458 proto_tree_set_representation(pi, format, ap);
5465 /* Set the FT_UINT{8,16,24,32} value */
5467 proto_tree_set_uint(field_info *fi, guint32 value)
5469 header_field_info *hfinfo;
5472 hfinfo = fi->hfinfo;
5475 if (hfinfo->bitmask) {
5476 /* Mask out irrelevant portions */
5477 integer &= (guint32)(hfinfo->bitmask);
5480 integer >>= hfinfo_bitshift(hfinfo);
5482 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5483 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5486 fvalue_set_uinteger(&fi->value, integer);
5489 /* Add FT_UINT{40,48,56,64} to a proto_tree */
5491 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5492 gint length, guint64 value)
5494 proto_item *pi = NULL;
5495 header_field_info *hfinfo;
5497 CHECK_FOR_NULL_TREE(tree);
5499 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5501 switch (hfinfo->type) {
5507 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5508 proto_tree_set_uint64(PNODE_FINFO(pi), value);
5512 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",
5520 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5521 gint start, gint length, guint64 value,
5522 const char *format, ...)
5527 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5529 va_start(ap, format);
5530 proto_tree_set_representation_value(pi, format, ap);
5538 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5539 gint start, gint length, guint64 value,
5540 const char *format, ...)
5545 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5547 TRY_TO_FAKE_THIS_REPR(pi);
5549 va_start(ap, format);
5550 proto_tree_set_representation(pi, format, ap);
5557 /* Set the FT_UINT{40,48,56,64} value */
5559 proto_tree_set_uint64(field_info *fi, guint64 value)
5561 header_field_info *hfinfo;
5564 hfinfo = fi->hfinfo;
5567 if (hfinfo->bitmask) {
5568 /* Mask out irrelevant portions */
5569 integer &= hfinfo->bitmask;
5572 integer >>= hfinfo_bitshift(hfinfo);
5574 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5575 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5578 fvalue_set_uinteger64(&fi->value, integer);
5581 /* Add FT_INT{8,16,24,32} to a proto_tree */
5583 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5584 gint length, gint32 value)
5586 proto_item *pi = NULL;
5587 header_field_info *hfinfo;
5589 CHECK_FOR_NULL_TREE(tree);
5591 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5593 switch (hfinfo->type) {
5598 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5599 proto_tree_set_int(PNODE_FINFO(pi), value);
5603 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
5611 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5612 gint start, gint length, gint32 value,
5613 const char *format, ...)
5618 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
5620 va_start(ap, format);
5621 proto_tree_set_representation_value(pi, format, ap);
5629 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5630 gint start, gint length, gint32 value,
5631 const char *format, ...)
5636 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
5638 TRY_TO_FAKE_THIS_REPR(pi);
5640 va_start(ap, format);
5641 proto_tree_set_representation(pi, format, ap);
5648 /* Set the FT_INT{8,16,24,32} value */
5650 proto_tree_set_int(field_info *fi, gint32 value)
5652 header_field_info *hfinfo;
5656 hfinfo = fi->hfinfo;
5657 integer = (guint32) value;
5659 if (hfinfo->bitmask) {
5660 /* Mask out irrelevant portions */
5661 integer &= (guint32)(hfinfo->bitmask);
5664 integer >>= hfinfo_bitshift(hfinfo);
5666 no_of_bits = ws_count_ones(hfinfo->bitmask);
5667 integer = ws_sign_ext32(integer, no_of_bits);
5669 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5670 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5673 fvalue_set_sinteger(&fi->value, integer);
5676 /* Add FT_INT{40,48,56,64} to a proto_tree */
5678 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5679 gint length, gint64 value)
5681 proto_item *pi = NULL;
5682 header_field_info *hfinfo;
5684 CHECK_FOR_NULL_TREE(tree);
5686 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5688 switch (hfinfo->type) {
5693 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5694 proto_tree_set_int64(PNODE_FINFO(pi), value);
5698 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
5706 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5707 gint start, gint length, gint64 value,
5708 const char *format, ...)
5713 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
5715 va_start(ap, format);
5716 proto_tree_set_representation_value(pi, format, ap);
5723 /* Set the FT_INT{40,48,56,64} value */
5725 proto_tree_set_int64(field_info *fi, gint64 value)
5727 header_field_info *hfinfo;
5731 hfinfo = fi->hfinfo;
5734 if (hfinfo->bitmask) {
5735 /* Mask out irrelevant portions */
5736 integer &= hfinfo->bitmask;
5739 integer >>= hfinfo_bitshift(hfinfo);
5741 no_of_bits = ws_count_ones(hfinfo->bitmask);
5742 integer = ws_sign_ext64(integer, no_of_bits);
5744 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5745 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5748 fvalue_set_sinteger64(&fi->value, integer);
5752 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5753 gint start, gint length, gint64 value,
5754 const char *format, ...)
5759 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
5761 TRY_TO_FAKE_THIS_REPR(pi);
5763 va_start(ap, format);
5764 proto_tree_set_representation(pi, format, ap);
5771 /* Add a FT_EUI64 to a proto_tree */
5773 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5774 gint length, const guint64 value)
5777 header_field_info *hfinfo;
5779 CHECK_FOR_NULL_TREE(tree);
5781 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5783 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
5785 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5786 proto_tree_set_eui64(PNODE_FINFO(pi), value);
5792 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5793 gint start, gint length, const guint64 value,
5794 const char *format, ...)
5799 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5801 va_start(ap, format);
5802 proto_tree_set_representation_value(pi, format, ap);
5810 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5811 gint start, gint length, const guint64 value,
5812 const char *format, ...)
5817 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5819 TRY_TO_FAKE_THIS_REPR(pi);
5821 va_start(ap, format);
5822 proto_tree_set_representation(pi, format, ap);
5829 /* Set the FT_EUI64 value */
5831 proto_tree_set_eui64(field_info *fi, const guint64 value)
5833 fvalue_set_uinteger64(&fi->value, value);
5836 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
5840 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
5842 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
5846 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
5848 proto_tree_add_node(proto_tree *tree, field_info *fi)
5850 proto_node *pnode, *tnode, *sibling;
5855 * Restrict our depth. proto_tree_traverse_pre_order and
5856 * proto_tree_traverse_post_order (and possibly others) are recursive
5857 * so we need to be mindful of our stack size.
5859 if (tree->first_child == NULL) {
5860 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
5862 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)) {
5863 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
5864 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",
5865 prefs.gui_max_tree_depth,
5866 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
5872 * Make sure "tree" is ready to have subtrees under it, by
5873 * checking whether it's been given an ett_ value.
5875 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
5876 * node of the protocol tree. That node is not displayed,
5877 * so it doesn't need an ett_ value to remember whether it
5881 tfi = PNODE_FINFO(tnode);
5882 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
5883 REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
5884 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__);
5885 /* XXX - is it safe to continue here? */
5888 pnode = wmem_new(PNODE_POOL(tree), proto_node);
5889 PROTO_NODE_INIT(pnode);
5890 pnode->parent = tnode;
5891 PNODE_FINFO(pnode) = fi;
5892 pnode->tree_data = PTREE_DATA(tree);
5894 if (tnode->last_child != NULL) {
5895 sibling = tnode->last_child;
5896 DISSECTOR_ASSERT(sibling->next == NULL);
5897 sibling->next = pnode;
5899 tnode->first_child = pnode;
5900 tnode->last_child = pnode;
5902 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
5904 return (proto_item *)pnode;
5908 /* Generic way to allocate field_info and add to proto_tree.
5909 * Sets *pfi to address of newly-allocated field_info struct */
5911 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
5918 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA);
5919 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
5920 pi = proto_tree_add_node(tree, fi);
5927 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
5928 gint *item_length, const guint encoding)
5930 gint length_remaining;
5933 * We only allow a null tvbuff if the item has a zero length,
5934 * i.e. if there's no data backing it.
5936 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
5939 * XXX - in some protocols, there are 32-bit unsigned length
5940 * fields, so lengths in protocol tree and tvbuff routines
5941 * should really be unsigned. We should have, for those
5942 * field types for which "to the end of the tvbuff" makes sense,
5943 * additional routines that take no length argument and
5944 * add fields that run to the end of the tvbuff.
5946 if (*length == -1) {
5948 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
5949 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
5950 * of -1 means "set the length to what remains in the
5953 * The assumption is either that
5955 * 1) the length of the item can only be determined
5956 * by dissection (typically true of items with
5957 * subitems, which are probably FT_NONE or
5962 * 2) if the tvbuff is "short" (either due to a short
5963 * snapshot length or due to lack of reassembly of
5964 * fragments/segments/whatever), we want to display
5965 * what's available in the field (probably FT_BYTES
5966 * or FT_STRING) and then throw an exception later
5970 * 3) the field is defined to be "what's left in the
5973 * so we set the length to what remains in the tvbuff so
5974 * that, if we throw an exception while dissecting, it
5975 * has what is probably the right value.
5977 * For FT_STRINGZ, it means "the string is null-terminated,
5978 * not null-padded; set the length to the actual length
5979 * of the string", and if the tvbuff if short, we just
5980 * throw an exception.
5982 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG, it means "find the end of the string",
5983 * and if the tvbuff if short, we just throw an exception.
5985 * It's not valid for any other type of field. For those
5986 * fields, we treat -1 the same way we treat other
5987 * negative values - we assume the length is a Really
5988 * Big Positive Number, and throw a ReportedBoundsError
5989 * exception, under the assumption that the Really Big
5990 * Length would run past the end of the packet.
5992 if ((IS_FT_INT(hfinfo->type)) || (IS_FT_UINT(hfinfo->type))) {
5993 if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
5995 * Leave the length as -1, so our caller knows
5998 *item_length = *length;
6000 } else if (encoding & ENC_VARINT_QUIC) {
6001 switch (tvb_get_guint8(tvb, start) >> 6)
6003 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6006 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6009 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6012 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6019 switch (hfinfo->type) {
6026 case FT_STRINGZTRUNC:
6028 * We allow FT_PROTOCOLs to be zero-length -
6029 * for example, an ONC RPC NULL procedure has
6030 * neither arguments nor reply, so the
6031 * payload for that protocol is empty.
6033 * We also allow the others to be zero-length -
6034 * because that's the way the code has been for a
6037 * However, we want to ensure that the start
6038 * offset is not *past* the byte past the end
6039 * of the tvbuff: we throw an exception in that
6042 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6043 DISSECTOR_ASSERT(*length >= 0);
6048 * Leave the length as -1, so our caller knows
6054 THROW(ReportedBoundsError);
6055 DISSECTOR_ASSERT_NOT_REACHED();
6057 *item_length = *length;
6059 *item_length = *length;
6060 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6062 * These types are for interior nodes of the
6063 * tree, and don't have data associated with
6064 * them; if the length is negative (XXX - see
6065 * above) or goes past the end of the tvbuff,
6066 * cut it short at the end of the tvbuff.
6067 * That way, if this field is selected in
6068 * Wireshark, we don't highlight stuff past
6069 * the end of the data.
6071 /* XXX - what to do, if we don't have a tvb? */
6073 length_remaining = tvb_captured_length_remaining(tvb, start);
6074 if (*item_length < 0 ||
6075 (*item_length > 0 &&
6076 (length_remaining < *item_length)))
6077 *item_length = length_remaining;
6080 if (*item_length < 0) {
6081 THROW(ReportedBoundsError);
6087 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
6088 gint length, guint item_length, const gint encoding)
6093 * We need to get the correct item length here.
6094 * That's normally done by proto_tree_new_item(),
6095 * but we won't be calling it.
6097 switch (hfinfo->type) {
6103 * The length is the specified length.
6108 n = get_uint_value(NULL, tvb, start, length, encoding);
6112 /* XXX - make these just FT_UINT? */
6121 /* XXX - make these just FT_INT? */
6130 if (encoding & (ENC_VARIANT_MASK)) {
6132 report_type_length_mismatch(NULL, "a FT_[U]INT", length, TRUE);
6136 /* This can throw an exception */
6137 /* XXX - do this without fetching the varint? */
6138 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN, &dummy, encoding);
6140 THROW(ReportedBoundsError);
6143 item_length = length;
6148 * The length is the specified length.
6170 * The length is the specified length.
6176 report_type_length_mismatch(NULL, "a string", length, TRUE);
6179 /* This can throw an exception */
6180 /* XXX - do this without fetching the string? */
6181 tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
6183 item_length = length;
6186 case FT_UINT_STRING:
6187 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
6192 case FT_STRINGZTRUNC:
6193 case FT_ABSOLUTE_TIME:
6194 case FT_RELATIVE_TIME:
6195 case FT_IEEE_11073_SFLOAT:
6196 case FT_IEEE_11073_FLOAT:
6198 * The length is the specified length.
6203 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in gset_full_length()",
6206 ftype_name(hfinfo->type));
6213 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6214 const gint start, const gint item_length)
6218 FIELD_INFO_NEW(PNODE_POOL(tree), fi);
6220 fi->hfinfo = hfinfo;
6222 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6223 fi->length = item_length;
6226 if (!PTREE_DATA(tree)->visible)
6227 FI_SET_FLAG(fi, FI_HIDDEN);
6228 fvalue_init(&fi->value, fi->hfinfo->type);
6231 /* add the data source tvbuff */
6232 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
6234 fi->appendix_start = 0;
6235 fi->appendix_length = 0;
6240 /* If the protocol tree is to be visible, set the representation of a
6241 proto_tree entry with the name of the field for the item and with
6242 the value formatted with the supplied printf-style format and
6245 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6249 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6250 * items string representation */
6251 if (PTREE_DATA(pi)->visible && !proto_item_is_hidden(pi)) {
6253 field_info *fi = PITEM_FINFO(pi);
6254 header_field_info *hf;
6256 DISSECTOR_ASSERT(fi);
6260 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6261 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
6265 if (IS_FT_UINT32(hf->type))
6266 val = fvalue_get_uinteger(&fi->value);
6268 val = fvalue_get_uinteger64(&fi->value);
6270 val <<= hfinfo_bitshift(hf);
6272 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6273 ret = (int) (p - fi->rep->representation);
6276 /* put in the hf name */
6277 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
6279 /* If possible, Put in the value of the string */
6280 if (ret < ITEM_LABEL_LENGTH) {
6281 ret += g_vsnprintf(fi->rep->representation + ret,
6282 ITEM_LABEL_LENGTH - ret, format, ap);
6284 if (ret >= ITEM_LABEL_LENGTH) {
6285 /* Uh oh, we don't have enough room. Tell the user
6286 * that the field is truncated.
6288 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
6293 /* If the protocol tree is to be visible, set the representation of a
6294 proto_tree entry with the representation formatted with the supplied
6295 printf-style format and argument list. */
6297 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6299 int ret; /*tmp return value */
6300 field_info *fi = PITEM_FINFO(pi);
6302 DISSECTOR_ASSERT(fi);
6304 if (!proto_item_is_hidden(pi)) {
6305 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6306 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
6308 if (ret >= ITEM_LABEL_LENGTH) {
6309 /* Uh oh, we don't have enough room. Tell the user
6310 * that the field is truncated.
6312 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
6318 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
6320 gsize res = g_strlcpy(dest, src, dest_size);
6322 if (res > dest_size)
6327 static header_field_info *
6328 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
6330 header_field_info *dup_hfinfo;
6332 if (hfinfo->same_name_prev_id == -1)
6334 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
6339 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
6341 g_free(last_field_name);
6342 last_field_name = NULL;
6344 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
6345 /* No hfinfo with the same name */
6346 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
6350 if (hfinfo->same_name_next) {
6351 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
6354 if (hfinfo->same_name_prev_id != -1) {
6355 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
6356 same_name_prev->same_name_next = hfinfo->same_name_next;
6357 if (!hfinfo->same_name_next) {
6358 /* It's always the latest added hfinfo which is stored in gpa_name_map */
6359 g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
6365 proto_item_fill_display_label(field_info *finfo, gchar *display_label_str, const int label_str_size)
6367 header_field_info *hfinfo = finfo->hfinfo;
6373 const true_false_string *tfstring;
6374 const char *hf_str_val;
6375 char number_buf[48];
6376 const char *number_out;
6381 switch (hfinfo->type) {
6385 return protoo_strlcpy(display_label_str, UTF8_CHECK_MARK, label_str_size);
6389 tmp_str = hfinfo_format_bytes(NULL,
6391 (guint8 *)fvalue_get(&finfo->value),
6392 fvalue_length(&finfo->value));
6393 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6394 wmem_free(NULL, tmp_str);
6397 case FT_ABSOLUTE_TIME:
6398 tmp_str = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
6399 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6400 wmem_free(NULL, tmp_str);
6403 case FT_RELATIVE_TIME:
6404 tmp_str = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
6405 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6406 wmem_free(NULL, tmp_str);
6410 number64 = fvalue_get_uinteger64(&finfo->value);
6411 tfstring = &tfs_true_false;
6412 if (hfinfo->strings) {
6413 tfstring = (const struct true_false_string*) hfinfo->strings;
6415 label_len = protoo_strlcpy(display_label_str,
6416 tfs_get_string(!!number64, tfstring), label_str_size);
6420 number = fvalue_get_uinteger(&finfo->value);
6422 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6423 gchar tmp[ITEM_LABEL_LENGTH];
6424 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
6426 DISSECTOR_ASSERT(fmtfunc);
6427 fmtfunc(tmp, number);
6429 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
6431 } else if (hfinfo->strings) {
6432 number_out = hf_try_val_to_str(number, hfinfo);
6435 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
6438 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6441 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
6443 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6448 /* XXX - make these just FT_NUMBER? */
6459 number = IS_FT_INT(hfinfo->type) ?
6460 (guint32) fvalue_get_sinteger(&finfo->value) :
6461 fvalue_get_uinteger(&finfo->value);
6463 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6464 gchar tmp[ITEM_LABEL_LENGTH];
6465 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
6467 DISSECTOR_ASSERT(fmtfunc);
6468 fmtfunc(tmp, number);
6470 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
6472 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
6473 if (hfinfo->display & BASE_UNIT_STRING) {
6474 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
6475 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6476 hf_str_val = hf_try_val_to_str(number, hfinfo);
6477 label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
6479 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
6482 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
6485 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6488 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
6490 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6504 number64 = IS_FT_INT(hfinfo->type) ?
6505 (guint64) fvalue_get_sinteger64(&finfo->value) :
6506 fvalue_get_uinteger64(&finfo->value);
6508 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6509 gchar tmp[ITEM_LABEL_LENGTH];
6510 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
6512 DISSECTOR_ASSERT(fmtfunc64);
6513 fmtfunc64(tmp, number64);
6515 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
6516 } else if (hfinfo->strings) {
6517 if (hfinfo->display & BASE_UNIT_STRING) {
6518 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
6519 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6520 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6521 label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
6523 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6526 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
6528 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6531 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
6533 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6539 tmp_str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
6540 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6541 wmem_free(NULL, tmp_str);
6545 ipv4 = fvalue_get_uinteger(&finfo->value);
6546 set_address (&addr, AT_IPv4, 4, &ipv4);
6547 address_to_str_buf(&addr, display_label_str, label_str_size);
6548 label_len = (int)strlen(display_label_str);
6552 ipv6 = (ws_in6_addr *)fvalue_get(&finfo->value);
6553 set_address (&addr, AT_IPv6, sizeof(ws_in6_addr), ipv6);
6554 address_to_str_buf(&addr, display_label_str, label_str_size);
6555 label_len = (int)strlen(display_label_str);
6559 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
6560 address_to_str_buf(&addr, display_label_str, label_str_size);
6561 label_len = (int)strlen(display_label_str);
6565 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
6566 address_to_str_buf(&addr, display_label_str, label_str_size);
6567 label_len = (int)strlen(display_label_str);
6571 tmp_str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
6572 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6573 wmem_free(NULL, tmp_str);
6577 bytes = (guint8 *)fvalue_get(&finfo->value);
6578 tmp_str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
6579 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6580 wmem_free(NULL, tmp_str);
6584 bytes = (guint8 *)fvalue_get(&finfo->value);
6585 tmp_str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
6586 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6587 wmem_free(NULL, tmp_str);
6591 bytes = (guint8 *)fvalue_get(&finfo->value);
6592 tmp_str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
6593 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6594 wmem_free(NULL, tmp_str);
6598 if (hfinfo->display & BASE_UNIT_STRING) {
6599 double d_value = fvalue_get_floating(&finfo->value);
6600 g_snprintf(display_label_str, label_str_size,
6601 "%." G_STRINGIFY(FLT_DIG) "g%s", d_value,
6602 unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
6604 g_snprintf(display_label_str, label_str_size,
6605 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
6607 label_len = (int)strlen(display_label_str);
6611 if (hfinfo->display & BASE_UNIT_STRING) {
6612 double d_value = fvalue_get_floating(&finfo->value);
6613 g_snprintf(display_label_str, label_str_size,
6614 "%." G_STRINGIFY(DBL_DIG) "g%s", d_value,
6615 unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
6617 g_snprintf(display_label_str, label_str_size,
6618 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
6620 label_len = (int)strlen(display_label_str);
6625 case FT_UINT_STRING:
6627 case FT_STRINGZTRUNC:
6628 bytes = (guint8 *)fvalue_get(&finfo->value);
6629 tmp_str = hfinfo_format_text(NULL, hfinfo, bytes);
6630 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6631 wmem_free(NULL, tmp_str);
6635 /* First try ftype string representation */
6636 tmp_str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
6638 /* Default to show as bytes */
6639 bytes = (guint8 *)fvalue_get(&finfo->value);
6640 tmp_str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
6642 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6643 wmem_free(NULL, tmp_str);
6649 /* -------------------------- */
6651 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
6652 gchar *result, gchar *expr, const int size)
6658 int len, prev_len, last, i, offset_r = 0, offset_e = 0, label_len;
6660 field_info *finfo = NULL;
6661 header_field_info* hfinfo;
6662 const gchar *abbrev = NULL;
6664 const char *hf_str_val;
6665 char number_buf[48];
6666 const char *number_out;
6672 g_assert(field_ids != NULL);
6673 while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
6674 field_id = *field_idx;
6675 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
6677 /* do we need to rewind ? */
6681 if (occurrence < 0) {
6682 /* Search other direction */
6683 while (hfinfo->same_name_prev_id != -1) {
6684 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
6688 prev_len = 0; /* Reset handled occurrences */
6691 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
6693 if (!finfos || !(len = g_ptr_array_len(finfos))) {
6694 if (occurrence < 0) {
6695 hfinfo = hfinfo->same_name_next;
6697 hfinfo = hfinfo_same_name_get_prev(hfinfo);
6702 /* Are there enough occurrences of the field? */
6703 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
6704 if (occurrence < 0) {
6705 hfinfo = hfinfo->same_name_next;
6707 hfinfo = hfinfo_same_name_get_prev(hfinfo);
6713 /* Calculate single index or set outer bounderies */
6714 if (occurrence < 0) {
6715 i = occurrence + len + prev_len;
6717 } else if (occurrence > 0) {
6718 i = occurrence - 1 - prev_len;
6725 prev_len += len; /* Count handled occurrences */
6728 finfo = (field_info *)g_ptr_array_index(finfos, i);
6730 if (offset_r && (offset_r < (size - 2)))
6731 result[offset_r++] = ',';
6733 if (offset_e && (offset_e < (size - 2)))
6734 expr[offset_e++] = ',';
6736 switch (hfinfo->type) {
6740 /* Prevent multiple check marks */
6741 if (strstr(result, UTF8_CHECK_MARK ",") == NULL) {
6742 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6744 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
6749 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6751 number64 = fvalue_get_uinteger64(&finfo->value);
6752 offset_e += protoo_strlcpy(expr+offset_e,
6753 number64 ? "1" : "0", size-offset_e);
6757 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6759 number = fvalue_get_uinteger(&finfo->value);
6761 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6762 hf_str_val = hf_try_val_to_str(number, hfinfo);
6763 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6765 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
6767 (void) g_strlcpy(expr+offset_e, number_out, size-offset_e);
6770 offset_e = (int)strlen(expr);
6773 /* XXX - make these just FT_NUMBER? */
6783 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6786 number = IS_FT_INT(hfinfo->type) ?
6787 (guint32) fvalue_get_sinteger(&finfo->value) :
6788 fvalue_get_uinteger(&finfo->value);
6790 if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
6791 hf_str_val = hf_try_val_to_str(number, hfinfo);
6794 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6796 hf_str_val = hf_try_val_to_str(number, hfinfo);
6797 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6799 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
6801 (void) g_strlcpy(expr+offset_e, number_out, size-offset_e);
6804 offset_e = (int)strlen(expr);
6815 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6818 number64 = IS_FT_INT(hfinfo->type) ?
6819 (guint64) fvalue_get_sinteger64(&finfo->value) :
6820 fvalue_get_uinteger64(&finfo->value);
6822 if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
6823 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6826 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6827 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6829 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
6831 (void) g_strlcpy(expr+offset_e, number_out, size-offset_e);
6834 offset_e = (int)strlen(expr);
6838 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6840 bytes = (guint8 *)fvalue_get(&finfo->value);
6841 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
6842 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6843 wmem_free(NULL, str);
6847 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6849 bytes = (guint8 *)fvalue_get(&finfo->value);
6850 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
6851 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6852 wmem_free(NULL, str);
6856 label_len = proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6858 offset_e += protoo_strlcpy(expr+offset_e, result+offset_r, size-offset_e);
6860 offset_r += label_len;
6864 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6870 switch (hfinfo->type) {
6894 /* for these types, "expr" is filled in the loop above */
6898 /* for all others, just copy "result" to "expr" */
6899 (void) g_strlcpy(expr, result, size);
6904 /* Store abbrev for return value */
6905 abbrev = hfinfo->abbrev;
6908 if (occurrence == 0) {
6909 /* Fetch next hfinfo with same name (abbrev) */
6910 hfinfo = hfinfo_same_name_get_prev(hfinfo);
6917 return abbrev ? abbrev : "";
6921 /* Set text of proto_item after having already been created. */
6923 proto_item_set_text(proto_item *pi, const char *format, ...)
6925 field_info *fi = NULL;
6928 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6930 fi = PITEM_FINFO(pi);
6935 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
6939 va_start(ap, format);
6940 proto_tree_set_representation(pi, format, ap);
6944 /* Append to text of proto_item after having already been created. */
6946 proto_item_append_text(proto_item *pi, const char *format, ...)
6948 field_info *fi = NULL;
6952 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6954 fi = PITEM_FINFO(pi);
6959 if (!proto_item_is_hidden(pi)) {
6961 * If we don't already have a representation,
6962 * generate the default representation.
6964 if (fi->rep == NULL) {
6965 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6966 proto_item_fill_label(fi, fi->rep->representation);
6969 curlen = strlen(fi->rep->representation);
6970 if (ITEM_LABEL_LENGTH > curlen) {
6971 va_start(ap, format);
6972 g_vsnprintf(fi->rep->representation + curlen,
6973 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
6979 /* Prepend to text of proto_item after having already been created. */
6981 proto_item_prepend_text(proto_item *pi, const char *format, ...)
6983 field_info *fi = NULL;
6984 char representation[ITEM_LABEL_LENGTH];
6987 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6989 fi = PITEM_FINFO(pi);
6994 if (!proto_item_is_hidden(pi)) {
6996 * If we don't already have a representation,
6997 * generate the default representation.
6999 if (fi->rep == NULL) {
7000 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
7001 proto_item_fill_label(fi, representation);
7003 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
7005 va_start(ap, format);
7006 g_vsnprintf(fi->rep->representation,
7007 ITEM_LABEL_LENGTH, format, ap);
7009 (void) g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
7014 finfo_set_len(field_info *fi, const gint length)
7016 gint length_remaining;
7018 DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev);
7019 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7020 if (length > length_remaining)
7021 fi->length = length_remaining;
7023 fi->length = length;
7026 * You cannot just make the "len" field of a GByteArray
7027 * larger, if there's no data to back that length;
7028 * you can only make it smaller.
7030 if (fi->value.ftype->ftype == FT_BYTES && fi->length <= (gint)fi->value.value.bytes->len)
7031 fi->value.value.bytes->len = fi->length;
7035 proto_item_set_len(proto_item *pi, const gint length)
7039 TRY_TO_FAKE_THIS_REPR_VOID(pi);
7041 fi = PITEM_FINFO(pi);
7045 finfo_set_len(fi, length);
7049 * Sets the length of the item based on its start and on the specified
7050 * offset, which is the offset past the end of the item; as the start
7051 * in the item is relative to the beginning of the data source tvbuff,
7052 * we need to pass in a tvbuff - the end offset is relative to the beginning
7056 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
7061 TRY_TO_FAKE_THIS_REPR_VOID(pi);
7063 fi = PITEM_FINFO(pi);
7067 end += tvb_raw_offset(tvb);
7068 DISSECTOR_ASSERT(end >= fi->start);
7069 length = end - fi->start;
7071 finfo_set_len(fi, length);
7075 proto_item_get_len(const proto_item *pi)
7081 fi = PITEM_FINFO(pi);
7082 return fi ? fi->length : -1;
7086 proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7090 FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_OFFSET(bits_offset));
7091 FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_SIZE(bits_len));
7095 proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7101 fi = PITEM_FINFO(pi);
7102 DISSECTOR_ASSERT(fi->hfinfo != NULL);
7103 return fvalue_to_string_repr(scope, &fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7107 proto_tree_create_root(packet_info *pinfo)
7111 /* Initialize the proto_node */
7112 pnode = g_slice_new(proto_tree);
7113 PROTO_NODE_INIT(pnode);
7114 pnode->parent = NULL;
7115 PNODE_FINFO(pnode) = NULL;
7116 pnode->tree_data = g_slice_new(tree_data_t);
7118 /* Make sure we can access pinfo everywhere */
7119 pnode->tree_data->pinfo = pinfo;
7121 /* Don't initialize the tree_data_t. Wait until we know we need it */
7122 pnode->tree_data->interesting_hfids = NULL;
7124 /* Set the default to FALSE so it's easier to
7125 * find errors; if we expect to see the protocol tree
7126 * but for some reason the default 'visible' is not
7127 * changed, then we'll find out very quickly. */
7128 pnode->tree_data->visible = FALSE;
7130 /* Make sure that we fake protocols (if possible) */
7131 pnode->tree_data->fake_protocols = TRUE;
7133 /* Keep track of the number of children */
7134 pnode->tree_data->count = 0;
7136 return (proto_tree *)pnode;
7140 /* "prime" a proto_tree with a single hfid that a dfilter
7141 * is interested in. */
7143 proto_tree_prime_with_hfid(proto_tree *tree _U_, const gint hfid)
7145 header_field_info *hfinfo;
7147 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
7148 /* this field is referenced by a filter so increase the refcount.
7149 also increase the refcount for the parent, i.e the protocol.
7151 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
7152 /* only increase the refcount if there is a parent.
7153 if this is a protocol and not a field then parent will be -1
7154 and there is no parent to add any refcounting for.
7156 if (hfinfo->parent != -1) {
7157 header_field_info *parent_hfinfo;
7158 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
7160 /* Mark parent as indirectly referenced unless it is already directly
7161 * referenced, i.e. the user has specified the parent in a filter.
7163 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
7164 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
7169 proto_item_add_subtree(proto_item *pi, const gint idx) {
7175 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
7177 fi = PITEM_FINFO(pi);
7179 return (proto_tree *)pi;
7181 fi->tree_type = idx;
7183 return (proto_tree *)pi;
7187 proto_item_get_subtree(proto_item *pi) {
7192 fi = PITEM_FINFO(pi);
7193 if ( (!fi) || (fi->tree_type == -1) )
7195 return (proto_tree *)pi;
7199 proto_item_get_parent(const proto_item *ti) {
7206 proto_item_get_parent_nth(proto_item *ti, int gen) {
7219 proto_tree_get_parent(proto_tree *tree) {
7222 return (proto_item *)tree;
7226 proto_tree_get_parent_tree(proto_tree *tree) {
7230 /* we're the root tree, there's no parent
7231 return ourselves so the caller has at least a tree to attach to */
7235 return (proto_tree *)tree->parent;
7239 proto_tree_get_root(proto_tree *tree) {
7242 while (tree->parent) {
7243 tree = tree->parent;
7249 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
7250 proto_item *item_to_move)
7252 /* This function doesn't generate any values. It only reorganizes the prococol tree
7253 * so we can bail out immediately if it isn't visible. */
7254 if (!tree || !PTREE_DATA(tree)->visible)
7257 DISSECTOR_ASSERT(item_to_move->parent == tree);
7258 DISSECTOR_ASSERT(fixed_item->parent == tree);
7260 /*** cut item_to_move out ***/
7262 /* is item_to_move the first? */
7263 if (tree->first_child == item_to_move) {
7264 /* simply change first child to next */
7265 tree->first_child = item_to_move->next;
7267 DISSECTOR_ASSERT(tree->last_child != item_to_move);
7269 proto_item *curr_item;
7270 /* find previous and change it's next */
7271 for (curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
7272 if (curr_item->next == item_to_move) {
7277 DISSECTOR_ASSERT(curr_item);
7279 curr_item->next = item_to_move->next;
7281 /* fix last_child if required */
7282 if (tree->last_child == item_to_move) {
7283 tree->last_child = curr_item;
7287 /*** insert to_move after fixed ***/
7288 item_to_move->next = fixed_item->next;
7289 fixed_item->next = item_to_move;
7290 if (tree->last_child == fixed_item) {
7291 tree->last_child = item_to_move;
7296 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
7304 fi = PTREE_FINFO(tree);
7308 start += tvb_raw_offset(tvb);
7309 DISSECTOR_ASSERT(start >= 0);
7310 DISSECTOR_ASSERT(length >= 0);
7312 fi->appendix_start = start;
7313 fi->appendix_length = length;
7317 check_valid_filter_name_or_fail(const char *filter_name)
7319 gboolean found_invalid = proto_check_field_name(filter_name);
7321 /* Additionally forbid upper case characters. */
7322 if (!found_invalid) {
7323 for (guint i = 0; filter_name[i]; i++) {
7324 if (g_ascii_isupper(filter_name[i])) {
7325 found_invalid = TRUE;
7331 if (found_invalid) {
7332 ws_error("Protocol filter name \"%s\" has one or more invalid characters."
7333 " Allowed are lower characters, digits, '-', '_' and non-repeating '.'."
7334 " This might be caused by an inappropriate plugin or a development error.", filter_name);
7339 proto_register_protocol(const char *name, const char *short_name,
7340 const char *filter_name)
7342 protocol_t *protocol;
7343 header_field_info *hfinfo;
7346 * Make sure there's not already a protocol with any of those
7347 * names. Crash if there is, as that's an error in the code
7348 * or an inappropriate plugin.
7349 * This situation has to be fixed to not register more than one
7350 * protocol with the same name.
7353 if (g_hash_table_lookup(proto_names, name)) {
7354 /* g_error will terminate the program */
7355 ws_error("Duplicate protocol name \"%s\"!"
7356 " This might be caused by an inappropriate plugin or a development error.", name);
7359 if (g_hash_table_lookup(proto_short_names, short_name)) {
7360 ws_error("Duplicate protocol short_name \"%s\"!"
7361 " This might be caused by an inappropriate plugin or a development error.", short_name);
7364 check_valid_filter_name_or_fail(filter_name);
7366 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
7367 ws_error("Duplicate protocol filter_name \"%s\"!"
7368 " This might be caused by an inappropriate plugin or a development error.", filter_name);
7372 * Add this protocol to the list of known protocols;
7373 * the list is sorted by protocol short name.
7375 protocol = g_new(protocol_t, 1);
7376 protocol->name = name;
7377 protocol->short_name = short_name;
7378 protocol->filter_name = filter_name;
7379 protocol->fields = NULL; /* Delegate until actually needed */
7380 protocol->is_enabled = TRUE; /* protocol is enabled by default */
7381 protocol->enabled_by_default = TRUE; /* see previous comment */
7382 protocol->can_toggle = TRUE;
7383 protocol->parent_proto_id = -1;
7384 protocol->heur_list = NULL;
7386 /* List will be sorted later by name, when all protocols completed registering */
7387 protocols = g_list_prepend(protocols, protocol);
7388 g_hash_table_insert(proto_names, (gpointer)name, protocol);
7389 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
7390 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
7392 /* Here we allocate a new header_field_info struct */
7393 hfinfo = g_slice_new(header_field_info);
7394 hfinfo->name = name;
7395 hfinfo->abbrev = filter_name;
7396 hfinfo->type = FT_PROTOCOL;
7397 hfinfo->display = BASE_NONE;
7398 hfinfo->strings = protocol;
7399 hfinfo->bitmask = 0;
7400 hfinfo->ref_type = HF_REF_TYPE_NONE;
7401 hfinfo->blurb = NULL;
7402 hfinfo->parent = -1; /* This field differentiates protos and fields */
7404 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
7405 return protocol->proto_id;
7409 proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
7411 protocol_t *protocol;
7412 header_field_info *hfinfo;
7415 * Helper protocols don't need the strict rules as a "regular" protocol
7416 * Just register it in a list and make a hf_ field from it
7418 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
7419 ws_error("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name);
7422 if (parent_proto < 0) {
7423 ws_error("Must have a valid parent protocol for helper protocol \"%s\"!"
7424 " This might be caused by an inappropriate plugin or a development error.", name);
7427 check_valid_filter_name_or_fail(filter_name);
7429 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
7430 protocol = g_new(protocol_t, 1);
7431 protocol->name = name;
7432 protocol->short_name = short_name;
7433 protocol->filter_name = filter_name;
7434 protocol->fields = NULL; /* Delegate until actually needed */
7436 /* Enabling and toggling is really determined by parent protocol,
7437 but provide default values here */
7438 protocol->is_enabled = TRUE;
7439 protocol->enabled_by_default = TRUE;
7440 protocol->can_toggle = TRUE;
7442 protocol->parent_proto_id = parent_proto;
7443 protocol->heur_list = NULL;
7445 /* List will be sorted later by name, when all protocols completed registering */
7446 protocols = g_list_prepend(protocols, protocol);
7448 /* Here we allocate a new header_field_info struct */
7449 hfinfo = g_slice_new(header_field_info);
7450 hfinfo->name = name;
7451 hfinfo->abbrev = filter_name;
7452 hfinfo->type = field_type;
7453 hfinfo->display = BASE_NONE;
7454 if (field_type == FT_BYTES) {
7455 hfinfo->display |= (BASE_NO_DISPLAY_VALUE|BASE_PROTOCOL_INFO);
7457 hfinfo->strings = protocol;
7458 hfinfo->bitmask = 0;
7459 hfinfo->ref_type = HF_REF_TYPE_NONE;
7460 hfinfo->blurb = NULL;
7461 hfinfo->parent = -1; /* This field differentiates protos and fields */
7463 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
7464 return protocol->proto_id;
7468 proto_deregister_protocol(const char *short_name)
7470 protocol_t *protocol;
7471 header_field_info *hfinfo;
7475 proto_id = proto_get_id_by_short_name(short_name);
7476 protocol = find_protocol_by_id(proto_id);
7477 if (protocol == NULL)
7480 g_hash_table_remove(proto_names, protocol->name);
7481 g_hash_table_remove(proto_short_names, (gpointer)short_name);
7482 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
7484 if (protocol->fields) {
7485 for (i = 0; i < protocol->fields->len; i++) {
7486 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
7487 hfinfo_remove_from_gpa_name_map(hfinfo);
7488 expert_deregister_expertinfo(hfinfo->abbrev);
7489 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
7491 g_ptr_array_free(protocol->fields, TRUE);
7492 protocol->fields = NULL;
7495 g_list_free(protocol->heur_list);
7497 /* Remove this protocol from the list of known protocols */
7498 protocols = g_list_remove(protocols, protocol);
7500 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
7501 g_hash_table_steal(gpa_name_map, protocol->filter_name);
7503 g_free(last_field_name);
7504 last_field_name = NULL;
7510 proto_register_alias(const int proto_id, const char *alias_name)
7512 protocol_t *protocol;
7514 protocol = find_protocol_by_id(proto_id);
7515 if (alias_name && protocol) {
7516 g_hash_table_insert(gpa_protocol_aliases, (gpointer) alias_name, (gpointer)protocol->filter_name);
7521 * Routines to use to iterate over the protocols.
7522 * The argument passed to the iterator routines is an opaque cookie to
7523 * their callers; it's the GList pointer for the current element in
7525 * The ID of the protocol is returned, or -1 if there is no protocol.
7528 proto_get_first_protocol(void **cookie)
7530 protocol_t *protocol;
7532 if (protocols == NULL)
7534 *cookie = protocols;
7535 protocol = (protocol_t *)protocols->data;
7536 return protocol->proto_id;
7540 proto_get_data_protocol(void *cookie)
7542 GList *list_item = (GList *)cookie;
7544 protocol_t *protocol = (protocol_t *)list_item->data;
7545 return protocol->proto_id;
7549 proto_get_next_protocol(void **cookie)
7551 GList *list_item = (GList *)*cookie;
7552 protocol_t *protocol;
7554 list_item = g_list_next(list_item);
7555 if (list_item == NULL)
7557 *cookie = list_item;
7558 protocol = (protocol_t *)list_item->data;
7559 return protocol->proto_id;
7562 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
7563 assume that the cookie stored by
7564 proto_get_(first|next)_protocol_field() will never have a
7565 value of NULL. So, to preserve this semantic, the cookie value
7566 below is adjusted so that the cookie value stored is 1 + the
7567 current (zero-based) array index.
7570 proto_get_first_protocol_field(const int proto_id, void **cookie)
7572 protocol_t *protocol = find_protocol_by_id(proto_id);
7574 if ((protocol == NULL) || (protocol->fields == NULL) || (protocol->fields->len == 0))
7577 *cookie = GUINT_TO_POINTER(0 + 1);
7578 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
7582 proto_get_next_protocol_field(const int proto_id, void **cookie)
7584 protocol_t *protocol = find_protocol_by_id(proto_id);
7585 guint i = GPOINTER_TO_UINT(*cookie) - 1;
7589 if ((protocol->fields == NULL) || (i >= protocol->fields->len))
7592 *cookie = GUINT_TO_POINTER(i + 1);
7593 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
7597 find_protocol_by_id(const int proto_id)
7599 header_field_info *hfinfo;
7604 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
7605 if (hfinfo->type != FT_PROTOCOL) {
7606 DISSECTOR_ASSERT(hfinfo->display & BASE_PROTOCOL_INFO);
7608 return (protocol_t *)hfinfo->strings;
7612 proto_get_id(const protocol_t *protocol)
7614 return protocol->proto_id;
7618 proto_name_already_registered(const gchar *name)
7620 DISSECTOR_ASSERT_HINT(name, "No name present");
7622 if (g_hash_table_lookup(proto_names, name) != NULL)
7628 proto_get_id_by_filter_name(const gchar *filter_name)
7630 const protocol_t *protocol = NULL;
7632 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
7634 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
7636 if (protocol == NULL)
7638 return protocol->proto_id;
7642 proto_get_id_by_short_name(const gchar *short_name)
7644 const protocol_t *protocol = NULL;
7646 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
7648 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
7650 if (protocol == NULL)
7652 return protocol->proto_id;
7656 proto_get_protocol_name(const int proto_id)
7658 protocol_t *protocol;
7660 protocol = find_protocol_by_id(proto_id);
7662 if (protocol == NULL)
7664 return protocol->name;
7668 proto_get_protocol_short_name(const protocol_t *protocol)
7670 if (protocol == NULL)
7672 return protocol->short_name;
7676 proto_get_protocol_long_name(const protocol_t *protocol)
7678 if (protocol == NULL)
7680 return protocol->name;
7684 proto_get_protocol_filter_name(const int proto_id)
7686 protocol_t *protocol;
7688 protocol = find_protocol_by_id(proto_id);
7689 if (protocol == NULL)
7691 return protocol->filter_name;
7694 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
7696 heur_dtbl_entry_t* heuristic_dissector;
7698 if (protocol == NULL)
7701 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
7702 if (heuristic_dissector != NULL)
7704 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
7708 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
7710 if (protocol == NULL)
7713 g_list_foreach(protocol->heur_list, func, user_data);
7717 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
7718 gboolean *is_tcp, gboolean *is_udp,
7719 gboolean *is_sctp, gboolean *is_tls,
7721 gboolean *is_lte_rlc)
7723 wmem_list_frame_t *protos = wmem_list_head(layers);
7725 const char *proto_name;
7727 /* Walk the list of a available protocols in the packet and
7728 attempt to find "major" ones. */
7729 /* It might make more sense to assemble and return a bitfield. */
7730 while (protos != NULL)
7732 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
7733 proto_name = proto_get_protocol_filter_name(proto_id);
7735 if (is_ip && ((!strcmp(proto_name, "ip")) ||
7736 (!strcmp(proto_name, "ipv6")))) {
7738 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
7740 } else if (is_udp && !strcmp(proto_name, "udp")) {
7742 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
7744 } else if (is_tls && !strcmp(proto_name, "tls")) {
7746 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
7748 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
7752 protos = wmem_list_frame_next(protos);
7757 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
7759 wmem_list_frame_t *protos = wmem_list_head(layers);
7763 /* Walk the list of a available protocols in the packet and
7764 attempt to find the specified protocol. */
7765 while (protos != NULL)
7767 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
7768 name = proto_get_protocol_filter_name(proto_id);
7770 if (!strcmp(name, proto_name))
7775 protos = wmem_list_frame_next(protos);
7782 proto_is_pino(const protocol_t *protocol)
7784 return (protocol->parent_proto_id != -1);
7788 proto_is_protocol_enabled(const protocol_t *protocol)
7790 if (protocol == NULL)
7793 //parent protocol determines enable/disable for helper dissectors
7794 if (proto_is_pino(protocol))
7795 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
7797 return protocol->is_enabled;
7801 proto_is_protocol_enabled_by_default(const protocol_t *protocol)
7803 //parent protocol determines enable/disable for helper dissectors
7804 if (proto_is_pino(protocol))
7805 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
7807 return protocol->enabled_by_default;
7811 proto_can_toggle_protocol(const int proto_id)
7813 protocol_t *protocol;
7815 protocol = find_protocol_by_id(proto_id);
7816 //parent protocol determines toggling for helper dissectors
7817 if (proto_is_pino(protocol))
7818 return proto_can_toggle_protocol(protocol->parent_proto_id);
7820 return protocol->can_toggle;
7824 proto_disable_by_default(const int proto_id)
7826 protocol_t *protocol;
7828 protocol = find_protocol_by_id(proto_id);
7829 DISSECTOR_ASSERT(protocol->can_toggle);
7830 DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
7831 protocol->is_enabled = FALSE;
7832 protocol->enabled_by_default = FALSE;
7836 proto_set_decoding(const int proto_id, const gboolean enabled)
7838 protocol_t *protocol;
7840 protocol = find_protocol_by_id(proto_id);
7841 DISSECTOR_ASSERT(protocol->can_toggle);
7842 DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
7843 protocol->is_enabled = enabled;
7847 proto_reenable_all(void)
7849 protocol_t *protocol;
7850 GList *list_item = protocols;
7852 if (protocols == NULL)
7856 protocol = (protocol_t *)list_item->data;
7857 if (protocol->can_toggle && protocol->enabled_by_default)
7858 protocol->is_enabled = TRUE;
7859 list_item = g_list_next(list_item);
7864 proto_set_cant_toggle(const int proto_id)
7866 protocol_t *protocol;
7868 protocol = find_protocol_by_id(proto_id);
7869 protocol->can_toggle = FALSE;
7873 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
7875 if (proto != NULL) {
7876 g_ptr_array_add(proto->fields, hfi);
7879 return proto_register_field_init(hfi, parent);
7882 /* for use with static arrays only, since we don't allocate our own copies
7883 of the header_field_info struct contained within the hf_register_info struct */
7885 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
7887 hf_register_info *ptr = hf;
7891 proto = find_protocol_by_id(parent);
7893 if (proto->fields == NULL) {
7894 proto->fields = g_ptr_array_sized_new(num_records);
7897 for (i = 0; i < num_records; i++, ptr++) {
7899 * Make sure we haven't registered this yet.
7900 * Most fields have variables associated with them
7901 * that are initialized to -1; some have array elements,
7902 * or possibly uninitialized variables, so we also allow
7903 * 0 (which is unlikely to be the field ID we get back
7904 * from "proto_register_field_init()").
7906 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
7908 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
7909 ptr->hfinfo.abbrev);
7913 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
7918 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
7923 proto = find_protocol_by_id(parent);
7925 if (proto->fields == NULL) {
7926 proto->fields = g_ptr_array_sized_new(num_records);
7929 for (i = 0; i < num_records; i++) {
7931 * Make sure we haven't registered this yet.
7933 if (hfi[i].id != -1) {
7935 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7940 proto_register_field_common(proto, &hfi[i], parent);
7945 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
7950 proto = find_protocol_by_id(parent);
7952 if (proto->fields == NULL) {
7953 proto->fields = g_ptr_array_sized_new(num_records);
7957 for (i = 0; i < num_records; i++) {
7959 * Make sure we haven't registered this yet.
7961 if (hfi[i]->id != -1) {
7963 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7968 proto_register_field_common(proto, hfi[i], parent);
7972 /* deregister already registered fields */
7974 proto_deregister_field (const int parent, gint hf_id)
7976 header_field_info *hfi;
7980 g_free(last_field_name);
7981 last_field_name = NULL;
7983 if (hf_id == -1 || hf_id == 0)
7986 proto = find_protocol_by_id (parent);
7987 if (!proto || proto->fields == NULL) {
7991 for (i = 0; i < proto->fields->len; i++) {
7992 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
7993 if (hfi->id == hf_id) {
7994 /* Found the hf_id in this protocol */
7995 g_hash_table_steal(gpa_name_map, hfi->abbrev);
7996 g_ptr_array_remove_index_fast(proto->fields, i);
7997 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8004 proto_add_deregistered_data (void *data)
8006 g_ptr_array_add(deregistered_data, data);
8009 void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8011 if (field_strings == NULL) {
8015 switch (field_type) {
8017 /* This is just an integer represented as a pointer */
8020 protocol_t *protocol = (protocol_t *)field_strings;
8021 g_free((gchar *)protocol->short_name);
8025 true_false_string *tf = (true_false_string *)field_strings;
8026 g_free((gchar *)tf->true_string);
8027 g_free((gchar *)tf->false_string);
8039 * XXX - if it's BASE_RANGE_STRING, or
8040 * BASE_EXT_STRING, should we free it?
8042 if (field_display & BASE_UNIT_STRING) {
8043 unit_name_string *unit = (unit_name_string *)field_strings;
8044 g_free((gchar *)unit->singular);
8045 g_free((gchar *)unit->plural);
8047 val64_string *vs64 = (val64_string *)field_strings;
8048 while (vs64->strptr) {
8049 g_free((gchar *)vs64->strptr);
8067 * XXX - if it's BASE_RANGE_STRING, or
8068 * BASE_EXT_STRING, should we free it?
8070 if (field_display & BASE_UNIT_STRING) {
8071 unit_name_string *unit = (unit_name_string *)field_strings;
8072 g_free((gchar *)unit->singular);
8073 g_free((gchar *)unit->plural);
8074 } else if (field_display & BASE_RANGE_STRING) {
8075 range_string *rs = (range_string *)field_strings;
8076 while (rs->strptr) {
8077 g_free((gchar *)rs->strptr);
8081 value_string *vs = (value_string *)field_strings;
8082 while (vs->strptr) {
8083 g_free((gchar *)vs->strptr);
8093 if (field_type != FT_FRAMENUM) {
8094 g_free((void *)field_strings);
8099 free_deregistered_field (gpointer data, gpointer user_data _U_)
8101 header_field_info *hfi = (header_field_info *) data;
8102 gint hf_id = hfi->id;
8104 g_free((char *)hfi->name);
8105 g_free((char *)hfi->abbrev);
8106 g_free((char *)hfi->blurb);
8108 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
8110 if (hfi->parent == -1)
8111 g_slice_free(header_field_info, hfi);
8113 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
8117 free_deregistered_data (gpointer data, gpointer user_data _U_)
8122 /* free deregistered fields and data */
8124 proto_free_deregistered_fields (void)
8126 expert_free_deregistered_expertinfos();
8128 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
8129 g_ptr_array_free(deregistered_fields, TRUE);
8130 deregistered_fields = g_ptr_array_new();
8132 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
8133 g_ptr_array_free(deregistered_data, TRUE);
8134 deregistered_data = g_ptr_array_new();
8137 /* chars allowed in field abbrev: alphanumerics, '-', "_", and ".". */
8139 const guint8 fld_abbrev_chars[256] = {
8140 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
8141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
8142 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
8143 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
8144 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
8145 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
8146 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
8147 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
8148 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
8149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
8150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
8151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
8152 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
8153 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
8154 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
8155 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
8158 static const value_string hf_display[] = {
8159 { BASE_NONE, "BASE_NONE" },
8160 { BASE_DEC, "BASE_DEC" },
8161 { BASE_HEX, "BASE_HEX" },
8162 { BASE_OCT, "BASE_OCT" },
8163 { BASE_DEC_HEX, "BASE_DEC_HEX" },
8164 { BASE_HEX_DEC, "BASE_HEX_DEC" },
8165 { BASE_CUSTOM, "BASE_CUSTOM" },
8166 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
8167 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
8168 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
8169 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
8170 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
8171 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
8172 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
8173 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
8174 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
8175 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
8176 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
8177 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
8178 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
8179 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
8180 /* Alias: BASE_NONE { BASE_FLOAT, "BASE_FLOAT" }, */
8181 /* Alias: BASE_NONE { STR_ASCII, "STR_ASCII" }, */
8182 { STR_UNICODE, "STR_UNICODE" },
8183 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
8184 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
8185 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
8186 { BASE_PT_UDP, "BASE_PT_UDP" },
8187 { BASE_PT_TCP, "BASE_PT_TCP" },
8188 { BASE_PT_DCCP, "BASE_PT_DCCP" },
8189 { BASE_PT_SCTP, "BASE_PT_SCTP" },
8190 { BASE_OUI, "BASE_OUI" },
8193 const char* proto_field_display_to_string(int field_display)
8195 return val_to_str_const(field_display, hf_display, "Unknown");
8198 static inline port_type
8199 display_to_port_type(field_display_e e)
8216 /* temporary function containing assert part for easier profiling */
8218 tmp_fld_check_assert(header_field_info *hfinfo)
8222 /* The field must have a name (with length > 0) */
8223 if (!hfinfo->name || !hfinfo->name[0]) {
8225 /* Try to identify the field */
8226 ws_error("Field (abbrev='%s') does not have a name\n",
8230 ws_error("Field does not have a name (nor an abbreviation)\n");
8233 /* fields with an empty string for an abbreviation aren't filterable */
8234 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
8235 ws_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
8237 /* These types of fields are allowed to have value_strings,
8238 * true_false_strings or a protocol_t struct
8240 if (hfinfo->strings != NULL) {
8241 switch (hfinfo->type) {
8265 //allowed to support string if its a unit decsription
8266 if (hfinfo->display & BASE_UNIT_STRING)
8271 //allowed to support string if its a protocol (for pinos)
8272 if (hfinfo->display & BASE_PROTOCOL_INFO)
8277 ws_error("Field '%s' (%s) has a 'strings' value but is of type %s"
8278 " (which is not allowed to have strings)\n",
8279 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
8283 /* TODO: This check may slow down startup, and output quite a few warnings.
8284 It would be good to be able to enable this (and possibly other checks?)
8285 in non-release builds. */
8286 #ifdef ENABLE_CHECK_FILTER
8287 /* Check for duplicate value_string values.
8288 There are lots that have the same value *and* string, so for now only
8289 report those that have same value but different string. */
8290 if ((hfinfo->strings != NULL) &&
8291 !(hfinfo->display & BASE_RANGE_STRING) &&
8292 !(hfinfo->display & BASE_UNIT_STRING) &&
8293 !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
8295 (hfinfo->type == FT_CHAR) ||
8296 (hfinfo->type == FT_UINT8) ||
8297 (hfinfo->type == FT_UINT16) ||
8298 (hfinfo->type == FT_UINT24) ||
8299 (hfinfo->type == FT_UINT32) ||
8300 (hfinfo->type == FT_INT8) ||
8301 (hfinfo->type == FT_INT16) ||
8302 (hfinfo->type == FT_INT24) ||
8303 (hfinfo->type == FT_INT32) )) {
8305 if (hfinfo->display & BASE_EXT_STRING) {
8306 if (hfinfo->display & BASE_VAL64_STRING) {
8307 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings);
8308 CHECK_HF_VALUE(val64_string, G_GINT64_MODIFIER, start_values);
8310 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings);
8311 CHECK_HF_VALUE(value_string, "", start_values);
8314 const value_string *start_values = (const value_string*)hfinfo->strings;
8315 CHECK_HF_VALUE(value_string, "", start_values);
8319 if (hfinfo->type == FT_BOOLEAN) {
8320 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
8322 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
8323 ws_warning("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",
8324 hfinfo->name, hfinfo->abbrev,
8325 tfs->false_string, tfs->true_string);
8330 if (hfinfo->display & BASE_RANGE_STRING) {
8331 const range_string *rs = (const range_string*)(hfinfo->strings);
8333 const range_string *this_it = rs;
8336 if (this_it->value_max < this_it->value_min) {
8337 ws_warning("value_range_string error: %s (%s) entry for \"%s\" - max(%u 0x%x) is less than min(%u 0x%x)",
8338 hfinfo->name, hfinfo->abbrev,
8340 this_it->value_max, this_it->value_max,
8341 this_it->value_min, this_it->value_min);
8346 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
8347 /* Not OK if this one is completely hidden by an earlier one! */
8348 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
8349 ws_warning("value_range_string error: %s (%s) hidden by earlier entry "
8350 "(prev=\"%s\": %u 0x%x -> %u 0x%x) (this=\"%s\": %u 0x%x -> %u 0x%x)",
8351 hfinfo->name, hfinfo->abbrev,
8352 prev_it->strptr, prev_it->value_min, prev_it->value_min,
8353 prev_it->value_max, prev_it->value_max,
8354 this_it->strptr, this_it->value_min, this_it->value_min,
8355 this_it->value_max, this_it->value_max);
8359 } while (this_it->strptr);
8364 switch (hfinfo->type) {
8367 /* Require the char type to have BASE_HEX, BASE_OCT,
8368 * BASE_CUSTOM, or BASE_NONE as its base.
8370 * If the display value is BASE_NONE and there is a
8371 * strings conversion then the dissector writer is
8372 * telling us that the field's numerical value is
8373 * meaningless; we'll avoid showing the value to the
8376 switch (FIELD_DISPLAY(hfinfo->display)) {
8379 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
8382 if (hfinfo->strings == NULL)
8383 ws_error("Field '%s' (%s) is an integral value (%s)"
8384 " but is being displayed as BASE_NONE but"
8385 " without a strings conversion",
8386 hfinfo->name, hfinfo->abbrev,
8387 ftype_name(hfinfo->type));
8390 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8391 ws_error("Field '%s' (%s) is a character value (%s)"
8392 " but is being displayed as %s\n",
8393 hfinfo->name, hfinfo->abbrev,
8394 ftype_name(hfinfo->type), tmp_str);
8395 wmem_free(NULL, tmp_str);
8397 if (hfinfo->display & BASE_UNIT_STRING) {
8398 ws_error("Field '%s' (%s) is a character value (%s) but has a unit string\n",
8399 hfinfo->name, hfinfo->abbrev,
8400 ftype_name(hfinfo->type));
8411 /* Hexadecimal and octal are, in printf() and everywhere
8412 * else, unsigned so don't allow dissectors to register a
8413 * signed field to be displayed unsigned. (Else how would
8414 * we display negative values?)
8416 switch (FIELD_DISPLAY(hfinfo->display)) {
8421 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8422 ws_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
8423 hfinfo->name, hfinfo->abbrev,
8424 ftype_name(hfinfo->type), tmp_str);
8425 wmem_free(NULL, tmp_str);
8436 if (IS_BASE_PORT(hfinfo->display)) {
8437 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8438 if (hfinfo->type != FT_UINT16) {
8439 ws_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
8440 hfinfo->name, hfinfo->abbrev,
8441 tmp_str, ftype_name(hfinfo->type));
8443 if (hfinfo->strings != NULL) {
8444 ws_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
8445 hfinfo->name, hfinfo->abbrev,
8446 ftype_name(hfinfo->type), tmp_str);
8448 if (hfinfo->bitmask != 0) {
8449 ws_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
8450 hfinfo->name, hfinfo->abbrev,
8451 ftype_name(hfinfo->type), tmp_str);
8453 wmem_free(NULL, tmp_str);
8457 if (hfinfo->display == BASE_OUI) {
8458 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8459 if (hfinfo->type != FT_UINT24) {
8460 ws_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s\n",
8461 hfinfo->name, hfinfo->abbrev,
8462 tmp_str, ftype_name(hfinfo->type));
8464 if (hfinfo->strings != NULL) {
8465 ws_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
8466 hfinfo->name, hfinfo->abbrev,
8467 ftype_name(hfinfo->type), tmp_str);
8469 if (hfinfo->bitmask != 0) {
8470 ws_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
8471 hfinfo->name, hfinfo->abbrev,
8472 ftype_name(hfinfo->type), tmp_str);
8474 wmem_free(NULL, tmp_str);
8478 /* Require integral types (other than frame number,
8479 * which is always displayed in decimal) to have a
8482 * If the display value is BASE_NONE and there is a
8483 * strings conversion then the dissector writer is
8484 * telling us that the field's numerical value is
8485 * meaningless; we'll avoid showing the value to the
8488 switch (FIELD_DISPLAY(hfinfo->display)) {
8494 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
8497 if (hfinfo->strings == NULL) {
8498 ws_error("Field '%s' (%s) is an integral value (%s)"
8499 " but is being displayed as BASE_NONE but"
8500 " without a strings conversion",
8501 hfinfo->name, hfinfo->abbrev,
8502 ftype_name(hfinfo->type));
8504 if (hfinfo->display & BASE_SPECIAL_VALS) {
8505 ws_error("Field '%s' (%s) is an integral value (%s)"
8506 " that is being displayed as BASE_NONE but"
8507 " with BASE_SPECIAL_VALS",
8508 hfinfo->name, hfinfo->abbrev,
8509 ftype_name(hfinfo->type));
8514 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8515 ws_error("Field '%s' (%s) is an integral value (%s)"
8516 " but is being displayed as %s\n",
8517 hfinfo->name, hfinfo->abbrev,
8518 ftype_name(hfinfo->type), tmp_str);
8519 wmem_free(NULL, tmp_str);
8524 /* Require bytes to have a "display type" that could
8525 * add a character between displayed bytes.
8527 switch (FIELD_DISPLAY(hfinfo->display)) {
8535 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8536 ws_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",
8537 hfinfo->name, hfinfo->abbrev, tmp_str);
8538 wmem_free(NULL, tmp_str);
8540 if (hfinfo->bitmask != 0)
8541 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8542 hfinfo->name, hfinfo->abbrev,
8543 ftype_name(hfinfo->type));
8544 //allowed to support string if its a protocol (for pinos)
8545 if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_PROTOCOL_INFO)))
8546 ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8547 hfinfo->name, hfinfo->abbrev,
8548 ftype_name(hfinfo->type));
8553 if (hfinfo->display != BASE_NONE) {
8554 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8555 ws_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
8556 hfinfo->name, hfinfo->abbrev,
8557 ftype_name(hfinfo->type), tmp_str);
8558 wmem_free(NULL, tmp_str);
8560 if (hfinfo->bitmask != 0)
8561 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8562 hfinfo->name, hfinfo->abbrev,
8563 ftype_name(hfinfo->type));
8569 case FT_ABSOLUTE_TIME:
8570 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
8571 hfinfo->display == ABSOLUTE_TIME_UTC ||
8572 hfinfo->display == ABSOLUTE_TIME_NTP_UTC ||
8573 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
8574 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8575 ws_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
8576 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
8577 wmem_free(NULL, tmp_str);
8579 if (hfinfo->bitmask != 0)
8580 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8581 hfinfo->name, hfinfo->abbrev,
8582 ftype_name(hfinfo->type));
8587 case FT_UINT_STRING:
8589 case FT_STRINGZTRUNC:
8590 switch (hfinfo->display) {
8596 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8597 ws_error("Field '%s' (%s) is an string value (%s)"
8598 " but is being displayed as %s\n",
8599 hfinfo->name, hfinfo->abbrev,
8600 ftype_name(hfinfo->type), tmp_str);
8601 wmem_free(NULL, tmp_str);
8604 if (hfinfo->bitmask != 0)
8605 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8606 hfinfo->name, hfinfo->abbrev,
8607 ftype_name(hfinfo->type));
8608 if (hfinfo->strings != NULL)
8609 ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8610 hfinfo->name, hfinfo->abbrev,
8611 ftype_name(hfinfo->type));
8615 switch (hfinfo->display) {
8621 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8622 ws_error("Field '%s' (%s) is an IPv4 value (%s)"
8623 " but is being displayed as %s\n",
8624 hfinfo->name, hfinfo->abbrev,
8625 ftype_name(hfinfo->type), tmp_str);
8626 wmem_free(NULL, tmp_str);
8632 if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
8633 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8634 ws_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
8635 hfinfo->name, hfinfo->abbrev,
8636 ftype_name(hfinfo->type),
8638 wmem_free(NULL, tmp_str);
8640 if (hfinfo->bitmask != 0)
8641 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8642 hfinfo->name, hfinfo->abbrev,
8643 ftype_name(hfinfo->type));
8644 if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_UNIT_STRING)))
8645 ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8646 hfinfo->name, hfinfo->abbrev,
8647 ftype_name(hfinfo->type));
8650 if (hfinfo->display != BASE_NONE) {
8651 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8652 ws_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
8653 hfinfo->name, hfinfo->abbrev,
8654 ftype_name(hfinfo->type),
8656 wmem_free(NULL, tmp_str);
8658 if (hfinfo->bitmask != 0)
8659 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8660 hfinfo->name, hfinfo->abbrev,
8661 ftype_name(hfinfo->type));
8662 if (hfinfo->strings != NULL)
8663 ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8664 hfinfo->name, hfinfo->abbrev,
8665 ftype_name(hfinfo->type));
8670 #ifdef ENABLE_CHECK_FILTER
8672 _ftype_common(enum ftenum type)
8696 case FT_UINT_STRING:
8709 case FT_ABSOLUTE_TIME:
8710 case FT_RELATIVE_TIME:
8711 return FT_ABSOLUTE_TIME;
8720 register_type_length_mismatch(void)
8722 static ei_register_info ei[] = {
8723 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
8724 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
8727 expert_module_t* expert_type_length_mismatch;
8729 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
8731 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
8732 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
8734 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
8735 disabling them makes no sense. */
8736 proto_set_cant_toggle(proto_type_length_mismatch);
8740 register_number_string_decodinws_error(void)
8742 static ei_register_info ei[] = {
8743 { &ei_number_string_decoding_failed_error,
8744 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
8745 "Failed to decode number from string", EXPFILL
8748 { &ei_number_string_decoding_erange_error,
8749 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
8750 "Decoded number from string is out of valid range", EXPFILL
8755 expert_module_t* expert_number_string_decoding_error;
8757 proto_number_string_decoding_error =
8758 proto_register_protocol("Number-String Decoding Error",
8759 "Number-string decoding error",
8760 "_ws.number_string.decoding_error");
8762 expert_number_string_decoding_error =
8763 expert_register_protocol(proto_number_string_decoding_error);
8764 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
8766 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
8767 disabling them makes no sense. */
8768 proto_set_cant_toggle(proto_number_string_decoding_error);
8772 register_string_errors(void)
8774 static ei_register_info ei[] = {
8775 { &ei_string_trailing_characters,
8776 { "_ws.string.trailing_stray_characters", PI_UNDECODED, PI_WARN, "Trailing stray characters", EXPFILL }
8780 expert_module_t* expert_string_errors;
8782 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
8784 expert_string_errors = expert_register_protocol(proto_string_errors);
8785 expert_register_field_array(expert_string_errors, ei, array_length(ei));
8787 /* "String Errors" isn't really a protocol, it's an error indication;
8788 disabling them makes no sense. */
8789 proto_set_cant_toggle(proto_string_errors);
8792 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (235000+PRE_ALLOC_EXPERT_FIELDS_MEM)
8794 proto_register_field_init(header_field_info *hfinfo, const int parent)
8797 tmp_fld_check_assert(hfinfo);
8799 hfinfo->parent = parent;
8800 hfinfo->same_name_next = NULL;
8801 hfinfo->same_name_prev_id = -1;
8803 /* if we always add and never delete, then id == len - 1 is correct */
8804 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
8805 if (!gpa_hfinfo.hfi) {
8806 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
8807 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8809 gpa_hfinfo.allocated_len += 1000;
8810 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
8811 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
8812 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
8815 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
8817 hfinfo->id = gpa_hfinfo.len - 1;
8819 /* if we have real names, enter this field in the name tree */
8820 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
8822 header_field_info *same_name_next_hfinfo;
8825 /* Check that the filter name (abbreviation) is legal;
8826 * it must contain only alphanumerics, '-', "_", and ".". */
8827 c = proto_check_field_name(hfinfo->abbrev);
8830 fprintf(stderr, "Invalid leading, duplicated or trailing '.' found in filter name '%s'\n", hfinfo->abbrev);
8831 } else if (g_ascii_isprint(c)) {
8832 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
8834 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
8836 DISSECTOR_ASSERT_NOT_REACHED();
8839 /* We allow multiple hfinfo's to be registered under the same
8840 * abbreviation. This was done for X.25, as, depending
8841 * on whether it's modulo-8 or modulo-128 operation,
8842 * some bitfield fields may be in different bits of
8843 * a byte, and we want to be able to refer to that field
8844 * with one name regardless of whether the packets
8845 * are modulo-8 or modulo-128 packets. */
8847 same_name_hfinfo = NULL;
8849 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
8850 /* GLIB 2.x - if it is already present
8851 * the previous hfinfo with the same name is saved
8852 * to same_name_hfinfo by value destroy callback */
8853 if (same_name_hfinfo) {
8854 /* There's already a field with this name.
8855 * Put the current field *before* that field
8856 * in the list of fields with this name, Thus,
8857 * we end up with an effectively
8858 * doubly-linked-list of same-named hfinfo's,
8859 * with the head of the list (stored in the
8860 * hash) being the last seen hfinfo.
8862 same_name_next_hfinfo =
8863 same_name_hfinfo->same_name_next;
8865 hfinfo->same_name_next = same_name_next_hfinfo;
8866 if (same_name_next_hfinfo)
8867 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
8869 same_name_hfinfo->same_name_next = hfinfo;
8870 hfinfo->same_name_prev_id = same_name_hfinfo->id;
8871 #ifdef ENABLE_CHECK_FILTER
8872 while (same_name_hfinfo) {
8873 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
8874 ws_warning("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type));
8875 same_name_hfinfo = same_name_hfinfo->same_name_next;
8885 proto_register_subtree_array(gint * const *indices, const int num_indices)
8888 gint *const *ptr = indices;
8891 * If we've already allocated the array of tree types, expand
8892 * it; this lets plugins such as mate add tree types after
8893 * the initial startup. (If we haven't already allocated it,
8894 * we don't allocate it; on the first pass, we just assign
8895 * ett values and keep track of how many we've assigned, and
8896 * when we're finished registering all dissectors we allocate
8897 * the array, so that we do only one allocation rather than
8898 * wasting CPU time and memory by growing the array for each
8899 * dissector that registers ett values.)
8901 if (tree_is_expanded != NULL) {
8902 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
8904 /* set new items to 0 */
8905 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
8906 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
8907 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
8911 * Assign "num_indices" subtree numbers starting at "num_tree_types",
8912 * returning the indices through the pointers in the array whose
8913 * first element is pointed to by "indices", and update
8914 * "num_tree_types" appropriately.
8916 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
8918 /* g_error will terminate the program */
8919 ws_error("register_subtree_array: subtree item type (ett_...) not -1 !"
8920 " This is a development error:"
8921 " Either the subtree item type has already been assigned or"
8922 " was not initialized to -1.");
8924 **ptr = num_tree_types;
8929 label_concat(char *label_str, gsize pos, const char *str)
8931 if (pos < ITEM_LABEL_LENGTH)
8932 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
8938 label_mark_truncated(char *label_str, gsize name_pos)
8940 static const char trunc_str[] = " [truncated]";
8941 const size_t trunc_len = sizeof(trunc_str)-1;
8944 /* ..... field_name: dataaaaaaaaaaaaa
8948 * ..... field_name [truncated]: dataaaaaaaaaaaaa
8950 * name_pos==0 means that we have only data or only a field_name
8953 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
8954 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
8955 memcpy(label_str + name_pos, trunc_str, trunc_len);
8957 /* in general, label_str is UTF-8
8958 we can truncate it only at the beginning of a new character
8959 we go backwards from the byte right after our buffer and
8960 find the next starting byte of a UTF-8 character, this is
8962 there's no need to use g_utf8_find_prev_char(), the search
8963 will always succeed since we copied trunc_str into the
8965 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH - 1]);
8968 } else if (name_pos < ITEM_LABEL_LENGTH)
8969 (void) g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
8973 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
8977 /* "%s: %s", hfinfo->name, text */
8978 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
8979 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
8980 pos = label_concat(label_str, pos, ": ");
8981 pos = label_concat(label_str, pos, text ? text : "(null)");
8984 if (pos >= ITEM_LABEL_LENGTH) {
8985 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8986 label_mark_truncated(label_str, name_pos);
8993 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
8997 /* "%s: %s (%s)", hfinfo->name, text, descr */
8998 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
8999 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
9000 pos = label_concat(label_str, pos, ": ");
9001 if (hfinfo->display & BASE_UNIT_STRING) {
9002 pos = label_concat(label_str, pos, descr ? descr : "(null)");
9003 pos = label_concat(label_str, pos, text ? text : "(null)");
9005 pos = label_concat(label_str, pos, text ? text : "(null)");
9006 pos = label_concat(label_str, pos, " (");
9007 pos = label_concat(label_str, pos, descr ? descr : "(null)");
9008 pos = label_concat(label_str, pos, ")");
9012 if (pos >= ITEM_LABEL_LENGTH) {
9013 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9014 label_mark_truncated(label_str, name_pos);
9021 proto_item_fill_label(field_info *fi, gchar *label_str)
9023 header_field_info *hfinfo;
9037 /* XXX: Check validity of hfinfo->type */
9041 hfinfo = fi->hfinfo;
9043 switch (hfinfo->type) {
9046 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
9050 fill_label_boolean(fi, label_str);
9055 tmp = hfinfo_format_bytes(NULL, hfinfo,
9056 (guint8 *)fvalue_get(&fi->value),
9057 fvalue_length(&fi->value));
9058 label_fill(label_str, 0, hfinfo, tmp);
9059 wmem_free(NULL, tmp);
9063 if (hfinfo->bitmask) {
9064 fill_label_bitfield_char(fi, label_str);
9066 fill_label_char(fi, label_str);
9070 /* Four types of integers to take care of:
9071 * Bitfield, with val_string
9072 * Bitfield, w/o val_string
9073 * Non-bitfield, with val_string
9074 * Non-bitfield, w/o val_string
9080 if (hfinfo->bitmask) {
9081 if (fi->flags & FI_VARINT) {
9082 fill_label_bitfield_varint(fi, label_str, FALSE);
9084 fill_label_bitfield(fi, label_str, FALSE);
9087 fill_label_number(fi, label_str, FALSE);
9092 fill_label_number(fi, label_str, FALSE);
9099 if (hfinfo->bitmask) {
9100 if (fi->flags & FI_VARINT) {
9101 fill_label_bitfield_varint64(fi, label_str, FALSE);
9103 fill_label_bitfield64(fi, label_str, FALSE);
9106 fill_label_number64(fi, label_str, FALSE);
9114 if (hfinfo->bitmask) {
9115 if (fi->flags & FI_VARINT) {
9116 fill_label_bitfield_varint(fi, label_str, TRUE);
9118 fill_label_bitfield(fi, label_str, TRUE);
9121 fill_label_number(fi, label_str, TRUE);
9129 if (hfinfo->bitmask) {
9130 if (fi->flags & FI_VARINT) {
9131 fill_label_bitfield_varint64(fi, label_str, TRUE);
9133 fill_label_bitfield64(fi, label_str, TRUE);
9136 fill_label_number64(fi, label_str, TRUE);
9142 double d_value = fvalue_get_floating(&fi->value);
9143 if (hfinfo->display & BASE_UNIT_STRING) {
9144 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9145 "%s: %." G_STRINGIFY(FLT_DIG) "g%s",
9146 hfinfo->name, d_value,
9147 unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
9149 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9150 "%s: %." G_STRINGIFY(FLT_DIG) "g",
9151 hfinfo->name, d_value);
9158 double d_value = fvalue_get_floating(&fi->value);
9159 if (hfinfo->display & BASE_UNIT_STRING) {
9160 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9161 "%s: %." G_STRINGIFY(DBL_DIG) "g%s",
9162 hfinfo->name, d_value,
9163 unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
9165 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9166 "%s: %." G_STRINGIFY(DBL_DIG) "g",
9167 hfinfo->name, d_value);
9172 case FT_ABSOLUTE_TIME:
9173 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
9174 label_fill(label_str, 0, hfinfo, tmp);
9175 wmem_free(NULL, tmp);
9178 case FT_RELATIVE_TIME:
9179 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
9180 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9181 "%s: %s seconds", hfinfo->name, tmp);
9182 wmem_free(NULL, tmp);
9186 integer = fvalue_get_uinteger(&fi->value);
9187 tmp = get_ipxnet_name(NULL, integer);
9188 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9189 "%s: %s (0x%08X)", hfinfo->name,
9191 wmem_free(NULL, tmp);
9195 addr.type = AT_AX25;
9196 addr.len = AX25_ADDR_LEN;
9197 addr.data = (guint8 *)fvalue_get(&fi->value);
9199 addr_str = (char*)address_to_str(NULL, &addr);
9200 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9201 "%s: %s", hfinfo->name, addr_str);
9202 wmem_free(NULL, addr_str);
9206 addr.type = AT_VINES;
9207 addr.len = VINES_ADDR_LEN;
9208 addr.data = (guint8 *)fvalue_get(&fi->value);
9210 addr_str = (char*)address_to_str(NULL, &addr);
9211 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9212 "%s: %s", hfinfo->name, addr_str);
9213 wmem_free(NULL, addr_str);
9217 bytes = (guint8 *)fvalue_get(&fi->value);
9219 addr.type = AT_ETHER;
9223 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9224 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9225 "%s: %s", hfinfo->name, addr_str);
9226 wmem_free(NULL, addr_str);
9230 ipv4 = fvalue_get_uinteger(&fi->value);
9232 addr.type = AT_IPv4;
9236 if (hfinfo->display == BASE_NETMASK) {
9237 addr_str = (char*)address_to_str(NULL, &addr);
9239 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9241 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9242 "%s: %s", hfinfo->name, addr_str);
9243 wmem_free(NULL, addr_str);
9247 bytes = (guint8 *)fvalue_get(&fi->value);
9249 addr.type = AT_IPv6;
9253 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9254 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9255 "%s: %s", hfinfo->name, addr_str);
9256 wmem_free(NULL, addr_str);
9260 addr.type = AT_FCWWN;
9261 addr.len = FCWWN_ADDR_LEN;
9262 addr.data = (guint8 *)fvalue_get(&fi->value);
9264 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9265 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9266 "%s: %s", hfinfo->name, addr_str);
9267 wmem_free(NULL, addr_str);
9271 guid = (e_guid_t *)fvalue_get(&fi->value);
9272 tmp = guid_to_str(NULL, guid);
9273 label_fill(label_str, 0, hfinfo, tmp);
9274 wmem_free(NULL, tmp);
9278 bytes = (guint8 *)fvalue_get(&fi->value);
9279 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
9280 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
9282 label_fill_descr(label_str, 0, hfinfo, tmp, name);
9283 wmem_free(NULL, name);
9285 label_fill(label_str, 0, hfinfo, tmp);
9287 wmem_free(NULL, tmp);
9291 bytes = (guint8 *)fvalue_get(&fi->value);
9292 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
9293 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
9295 label_fill_descr(label_str, 0, hfinfo, tmp, name);
9296 wmem_free(NULL, name);
9298 label_fill(label_str, 0, hfinfo, tmp);
9300 wmem_free(NULL, tmp);
9304 bytes = (guint8 *)fvalue_get(&fi->value);
9305 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
9306 label_fill(label_str, 0, hfinfo, tmp);
9307 wmem_free(NULL, tmp);
9311 integer64 = fvalue_get_uinteger64(&fi->value);
9312 addr_str = eui64_to_str(NULL, integer64);
9313 tmp = (char*)eui64_to_display(NULL, integer64);
9314 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
9315 wmem_free(NULL, tmp);
9316 wmem_free(NULL, addr_str);
9320 case FT_UINT_STRING:
9322 case FT_STRINGZTRUNC:
9323 bytes = (guint8 *)fvalue_get(&fi->value);
9324 tmp = hfinfo_format_text(NULL, hfinfo, bytes);
9325 label_fill(label_str, 0, hfinfo, tmp);
9326 wmem_free(NULL, tmp);
9329 case FT_IEEE_11073_SFLOAT:
9330 case FT_IEEE_11073_FLOAT:
9331 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
9332 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9335 wmem_free(NULL, tmp);
9339 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_fill_label()",
9342 ftype_name(hfinfo->type));
9348 fill_label_boolean(field_info *fi, gchar *label_str)
9350 char *p = label_str;
9351 int bitfield_byte_length = 0, bitwidth;
9352 guint64 unshifted_value;
9355 header_field_info *hfinfo = fi->hfinfo;
9356 const true_false_string *tfstring = &tfs_true_false;
9358 if (hfinfo->strings) {
9359 tfstring = (const struct true_false_string*) hfinfo->strings;
9362 value = fvalue_get_uinteger64(&fi->value);
9363 if (hfinfo->bitmask) {
9364 /* Figure out the bit width */
9365 bitwidth = hfinfo_container_bitwidth(hfinfo);
9368 unshifted_value = value;
9369 unshifted_value <<= hfinfo_bitshift(hfinfo);
9371 /* Create the bitfield first */
9372 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9373 bitfield_byte_length = (int) (p - label_str);
9376 /* Fill in the textual info */
9377 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, tfstring));
9381 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
9383 if (hfinfo->display & BASE_RANGE_STRING)
9384 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
9386 if (hfinfo->display & BASE_EXT_STRING) {
9387 if (hfinfo->display & BASE_VAL64_STRING)
9388 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
9390 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
9393 if (hfinfo->display & BASE_VAL64_STRING)
9394 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
9396 if (hfinfo->display & BASE_UNIT_STRING)
9397 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
9399 return try_val_to_str(value, (const value_string *) hfinfo->strings);
9403 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
9405 if (hfinfo->display & BASE_VAL64_STRING) {
9406 if (hfinfo->display & BASE_EXT_STRING)
9407 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
9409 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
9412 if (hfinfo->display & BASE_RANGE_STRING)
9413 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
9415 if (hfinfo->display & BASE_UNIT_STRING)
9416 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
9418 /* If this is reached somebody registered a 64-bit field with a 32-bit
9419 * value-string, which isn't right. */
9420 REPORT_DISSECTOR_BUG("field %s is a 64-bit field with a 32-bit value_string",
9423 /* This is necessary to squelch MSVC errors; is there
9424 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
9430 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
9432 const char *str = hf_try_val_to_str(value, hfinfo);
9434 return (str) ? str : unknown_str;
9438 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
9440 const char *str = hf_try_val64_to_str(value, hfinfo);
9442 return (str) ? str : unknown_str;
9445 /* Fills data for bitfield chars with val_strings */
9447 fill_label_bitfield_char(field_info *fi, gchar *label_str)
9450 int bitfield_byte_length, bitwidth;
9451 guint32 unshifted_value;
9457 header_field_info *hfinfo = fi->hfinfo;
9459 /* Figure out the bit width */
9460 bitwidth = hfinfo_container_bitwidth(hfinfo);
9463 value = fvalue_get_uinteger(&fi->value);
9465 unshifted_value = value;
9466 if (hfinfo->bitmask) {
9467 unshifted_value <<= hfinfo_bitshift(hfinfo);
9470 /* Create the bitfield first */
9471 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9472 bitfield_byte_length = (int) (p - label_str);
9474 /* Fill in the textual info using stored (shifted) value */
9475 if (hfinfo->display == BASE_CUSTOM) {
9476 gchar tmp[ITEM_LABEL_LENGTH];
9477 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9479 DISSECTOR_ASSERT(fmtfunc);
9480 fmtfunc(tmp, value);
9481 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9483 else if (hfinfo->strings) {
9484 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9486 out = hfinfo_char_vals_format(hfinfo, buf, value);
9487 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9488 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9490 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9493 out = hfinfo_char_value_format(hfinfo, buf, value);
9495 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9499 /* Fills data for bitfield ints with val_strings */
9501 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
9504 int bitfield_byte_length, bitwidth;
9505 guint32 unshifted_value;
9511 header_field_info *hfinfo = fi->hfinfo;
9513 /* Figure out the bit width */
9514 bitwidth = hfinfo_container_bitwidth(hfinfo);
9518 value = fvalue_get_sinteger(&fi->value);
9520 value = fvalue_get_uinteger(&fi->value);
9522 unshifted_value = value;
9523 if (hfinfo->bitmask) {
9524 unshifted_value <<= hfinfo_bitshift(hfinfo);
9527 /* Create the bitfield first */
9528 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9529 bitfield_byte_length = (int) (p - label_str);
9531 /* Fill in the textual info using stored (shifted) value */
9532 if (hfinfo->display == BASE_CUSTOM) {
9533 gchar tmp[ITEM_LABEL_LENGTH];
9534 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9536 DISSECTOR_ASSERT(fmtfunc);
9537 fmtfunc(tmp, value);
9538 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9540 else if (hfinfo->strings) {
9541 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9543 out = hfinfo_number_vals_format(hfinfo, buf, value);
9544 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9545 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9547 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9550 out = hfinfo_number_value_format(hfinfo, buf, value);
9552 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9557 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
9560 int bitfield_byte_length, bitwidth;
9561 guint64 unshifted_value;
9567 header_field_info *hfinfo = fi->hfinfo;
9569 /* Figure out the bit width */
9570 bitwidth = hfinfo_container_bitwidth(hfinfo);
9574 value = fvalue_get_sinteger64(&fi->value);
9576 value = fvalue_get_uinteger64(&fi->value);
9578 unshifted_value = value;
9579 if (hfinfo->bitmask) {
9580 unshifted_value <<= hfinfo_bitshift(hfinfo);
9583 /* Create the bitfield first */
9584 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9585 bitfield_byte_length = (int) (p - label_str);
9587 /* Fill in the textual info using stored (shifted) value */
9588 if (hfinfo->display == BASE_CUSTOM) {
9589 gchar tmp[ITEM_LABEL_LENGTH];
9590 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9592 DISSECTOR_ASSERT(fmtfunc64);
9593 fmtfunc64(tmp, value);
9594 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9596 else if (hfinfo->strings) {
9597 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
9599 out = hfinfo_number_vals_format64(hfinfo, buf, value);
9600 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9601 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9603 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9606 out = hfinfo_number_value_format64(hfinfo, buf, value);
9608 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9613 fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed)
9616 int bitfield_byte_length;
9617 guint32 value, unshifted_value;
9621 header_field_info *hfinfo = fi->hfinfo;
9625 value = fvalue_get_sinteger(&fi->value);
9627 value = fvalue_get_uinteger(&fi->value);
9629 unshifted_value = value;
9630 if (hfinfo->bitmask) {
9631 unshifted_value <<= hfinfo_bitshift(hfinfo);
9634 /* Create the bitfield first */
9635 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
9636 bitfield_byte_length = (int) (p - label_str);
9638 /* Fill in the textual info using stored (shifted) value */
9639 if (hfinfo->display == BASE_CUSTOM) {
9640 gchar tmp[ITEM_LABEL_LENGTH];
9641 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9643 DISSECTOR_ASSERT(fmtfunc);
9644 fmtfunc(tmp, value);
9645 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9647 else if (hfinfo->strings) {
9648 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9650 out = hfinfo_number_vals_format(hfinfo, buf, value);
9651 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9652 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9654 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9657 out = hfinfo_number_value_format(hfinfo, buf, value);
9659 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9664 fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed)
9667 int bitfield_byte_length;
9668 guint64 unshifted_value;
9674 header_field_info *hfinfo = fi->hfinfo;
9678 value = fvalue_get_sinteger64(&fi->value);
9680 value = fvalue_get_uinteger64(&fi->value);
9682 unshifted_value = value;
9683 if (hfinfo->bitmask) {
9684 unshifted_value <<= hfinfo_bitshift(hfinfo);
9687 /* Create the bitfield first */
9688 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
9689 bitfield_byte_length = (int) (p - label_str);
9691 /* Fill in the textual info using stored (shifted) value */
9692 if (hfinfo->display == BASE_CUSTOM) {
9693 gchar tmp[ITEM_LABEL_LENGTH];
9694 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9696 DISSECTOR_ASSERT(fmtfunc64);
9697 fmtfunc64(tmp, value);
9698 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9700 else if (hfinfo->strings) {
9701 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
9703 out = hfinfo_number_vals_format64(hfinfo, buf, value);
9704 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9705 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9707 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9710 out = hfinfo_number_value_format64(hfinfo, buf, value);
9712 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9717 fill_label_char(field_info *fi, gchar *label_str)
9719 header_field_info *hfinfo = fi->hfinfo;
9725 value = fvalue_get_uinteger(&fi->value);
9727 /* Fill in the textual info */
9728 if (hfinfo->display == BASE_CUSTOM) {
9729 gchar tmp[ITEM_LABEL_LENGTH];
9730 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9732 DISSECTOR_ASSERT(fmtfunc);
9733 fmtfunc(tmp, value);
9734 label_fill(label_str, 0, hfinfo, tmp);
9736 else if (hfinfo->strings) {
9737 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9739 out = hfinfo_char_vals_format(hfinfo, buf, value);
9740 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9743 out = hfinfo_char_value_format(hfinfo, buf, value);
9745 label_fill(label_str, 0, hfinfo, out);
9750 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
9752 header_field_info *hfinfo = fi->hfinfo;
9759 value = fvalue_get_sinteger(&fi->value);
9761 value = fvalue_get_uinteger(&fi->value);
9763 /* Fill in the textual info */
9764 if (hfinfo->display == BASE_CUSTOM) {
9765 gchar tmp[ITEM_LABEL_LENGTH];
9766 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9768 DISSECTOR_ASSERT(fmtfunc);
9769 fmtfunc(tmp, value);
9770 label_fill(label_str, 0, hfinfo, tmp);
9772 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
9774 * It makes no sense to have a value-string table for a
9775 * frame-number field - they're just integers giving
9776 * the ordinal frame number.
9778 const char *val_str = hf_try_val_to_str(value, hfinfo);
9780 out = hfinfo_number_vals_format(hfinfo, buf, value);
9781 if (hfinfo->display & BASE_SPECIAL_VALS) {
9783 * Unique values only display value_string string
9784 * if there is a match. Otherwise it's just a number
9787 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9789 label_fill(label_str, 0, hfinfo, out);
9792 if (val_str == NULL)
9793 val_str = "Unknown";
9795 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9796 label_fill(label_str, 0, hfinfo, val_str);
9798 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9801 else if (IS_BASE_PORT(hfinfo->display)) {
9802 gchar tmp[ITEM_LABEL_LENGTH];
9804 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
9805 display_to_port_type((field_display_e)hfinfo->display), value);
9806 label_fill(label_str, 0, hfinfo, tmp);
9809 out = hfinfo_number_value_format(hfinfo, buf, value);
9811 label_fill(label_str, 0, hfinfo, out);
9816 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
9818 header_field_info *hfinfo = fi->hfinfo;
9825 value = fvalue_get_sinteger64(&fi->value);
9827 value = fvalue_get_uinteger64(&fi->value);
9829 /* Fill in the textual info */
9830 if (hfinfo->display == BASE_CUSTOM) {
9831 gchar tmp[ITEM_LABEL_LENGTH];
9832 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9834 DISSECTOR_ASSERT(fmtfunc64);
9835 fmtfunc64(tmp, value);
9836 label_fill(label_str, 0, hfinfo, tmp);
9838 else if (hfinfo->strings) {
9839 const char *val_str = hf_try_val64_to_str(value, hfinfo);
9841 out = hfinfo_number_vals_format64(hfinfo, buf, value);
9842 if (hfinfo->display & BASE_SPECIAL_VALS) {
9844 * Unique values only display value_string string
9845 * if there is a match. Otherwise it's just a number
9848 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9850 label_fill(label_str, 0, hfinfo, out);
9853 if (val_str == NULL)
9854 val_str = "Unknown";
9856 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9857 label_fill(label_str, 0, hfinfo, val_str);
9859 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9863 out = hfinfo_number_value_format64(hfinfo, buf, value);
9865 label_fill(label_str, 0, hfinfo, out);
9870 hfinfo_bitshift(const header_field_info *hfinfo)
9872 return ws_ctz(hfinfo->bitmask);
9877 hfinfo_bitoffset(const header_field_info *hfinfo)
9879 if (!hfinfo->bitmask) {
9883 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
9884 * as the first bit */
9885 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
9889 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
9891 if (!hfinfo->bitmask) {
9895 /* ilog2 = first set bit, ctz = last set bit */
9896 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
9900 hfinfo_type_bitwidth(enum ftenum type)
9939 DISSECTOR_ASSERT_NOT_REACHED();
9947 hfinfo_container_bitwidth(const header_field_info *hfinfo)
9949 if (!hfinfo->bitmask) {
9953 if (hfinfo->type == FT_BOOLEAN) {
9954 return hfinfo->display; /* hacky? :) */
9957 return hfinfo_type_bitwidth(hfinfo->type);
9961 hfinfo_hex_digits(const header_field_info *hfinfo)
9965 /* If we have a bitmask, hfinfo->type is the width of the container, so not
9966 * appropriate to determine the number of hex digits for the field.
9967 * So instead, we compute it from the bitmask.
9969 if (hfinfo->bitmask != 0) {
9970 bitwidth = hfinfo_mask_bitwidth(hfinfo);
9972 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
9975 /* Divide by 4, rounding up, to get number of hex digits. */
9976 return (bitwidth + 3) / 4;
9980 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
9982 char *ptr = &buf[6];
9983 static const gchar hex_digits[16] =
9984 { '0', '1', '2', '3', '4', '5', '6', '7',
9985 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
9989 /* Properly format value */
9990 if (g_ascii_isprint(value)) {
9992 * Printable, so just show the character, and, if it needs
9993 * to be escaped, escape it.
9996 if (value == '\\' || value == '\'')
10000 * Non-printable; show it as an escape sequence.
10006 * Show a NUL with only one digit.
10040 switch (FIELD_DISPLAY(display)) {
10043 *(--ptr) = (value & 0x7) + '0';
10045 *(--ptr) = (value & 0x7) + '0';
10047 *(--ptr) = (value & 0x7) + '0';
10051 *(--ptr) = hex_digits[value & 0x0F];
10053 *(--ptr) = hex_digits[value & 0x0F];
10058 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
10067 static const char *
10068 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
10070 char *ptr = &buf[31];
10071 gboolean isint = IS_FT_INT(hfinfo->type);
10074 /* Properly format value */
10075 switch (FIELD_DISPLAY(display)) {
10077 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
10081 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10084 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
10088 return oct_to_str_back(ptr, value);
10091 return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10095 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
10098 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10105 port_with_resolution_to_str_buf(buf, 32,
10106 display_to_port_type((field_display_e)display), value);
10111 const gchar *manuf_name;
10113 p_oui[0] = value >> 16 & 0xFF;
10114 p_oui[1] = value >> 8 & 0xFF;
10115 p_oui[2] = value & 0xFF;
10117 /* Attempt an OUI lookup. */
10118 manuf_name = uint_get_manuf_name_if_known(value);
10119 if (manuf_name == NULL) {
10120 /* Could not find an OUI. */
10121 g_snprintf(buf, 32, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
10124 /* Found an address string. */
10125 g_snprintf(buf, 32, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
10131 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
10136 static const char *
10137 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
10139 char *ptr = &buf[47];
10140 gboolean isint = IS_FT_INT(hfinfo->type);
10143 /* Properly format value */
10144 switch (FIELD_DISPLAY(display)) {
10146 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
10150 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10153 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
10157 return oct64_to_str_back(ptr, value);
10160 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10164 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
10167 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10171 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
10177 static const char *
10178 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10180 int display = hfinfo->display;
10182 if (hfinfo->type == FT_FRAMENUM) {
10184 * Frame numbers are always displayed in decimal.
10186 display = BASE_DEC;
10189 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
10192 static const char *
10193 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value)
10195 int display = hfinfo->display;
10197 if (hfinfo->type == FT_FRAMENUM) {
10199 * Frame numbers are always displayed in decimal.
10201 display = BASE_DEC;
10204 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
10207 static const char *
10208 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10210 /* Get the underlying BASE_ value */
10211 int display = FIELD_DISPLAY(hfinfo->display);
10213 return hfinfo_char_value_format_display(display, buf, value);
10216 static const char *
10217 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10219 /* Get the underlying BASE_ value */
10220 int display = FIELD_DISPLAY(hfinfo->display);
10222 if (hfinfo->type == FT_FRAMENUM) {
10224 * Frame numbers are always displayed in decimal.
10226 display = BASE_DEC;
10229 if (IS_BASE_PORT(display)) {
10230 display = BASE_DEC;
10231 } else if (display == BASE_OUI) {
10232 display = BASE_HEX;
10237 /* case BASE_DEC: */
10239 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
10241 display = BASE_DEC;
10244 /* case BASE_HEX: */
10246 display = BASE_HEX;
10250 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
10253 static const char *
10254 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value)
10256 /* Get the underlying BASE_ value */
10257 int display = FIELD_DISPLAY(hfinfo->display);
10259 if (hfinfo->type == FT_FRAMENUM) {
10261 * Frame numbers are always displayed in decimal.
10263 display = BASE_DEC;
10268 /* case BASE_DEC: */
10270 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
10272 display = BASE_DEC;
10275 /* case BASE_HEX: */
10277 display = BASE_HEX;
10281 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
10284 static const char *
10285 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10287 /* Get the underlying BASE_ value */
10288 int display = FIELD_DISPLAY(hfinfo->display);
10290 return hfinfo_char_value_format_display(display, buf, value);
10293 static const char *
10294 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10296 /* Get the underlying BASE_ value */
10297 int display = FIELD_DISPLAY(hfinfo->display);
10299 if (display == BASE_NONE)
10302 if (display == BASE_DEC_HEX)
10303 display = BASE_DEC;
10304 if (display == BASE_HEX_DEC)
10305 display = BASE_HEX;
10307 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
10310 static const char *
10311 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value)
10313 /* Get the underlying BASE_ value */
10314 int display = FIELD_DISPLAY(hfinfo->display);
10316 if (display == BASE_NONE)
10319 if (display == BASE_DEC_HEX)
10320 display = BASE_DEC;
10321 if (display == BASE_HEX_DEC)
10322 display = BASE_HEX;
10324 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
10328 proto_registrar_get_name(const int n)
10330 header_field_info *hfinfo;
10332 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10333 return hfinfo->name;
10337 proto_registrar_get_abbrev(const int n)
10339 header_field_info *hfinfo;
10341 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10342 return hfinfo->abbrev;
10346 proto_registrar_get_ftype(const int n)
10348 header_field_info *hfinfo;
10350 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10351 return hfinfo->type;
10355 proto_registrar_get_parent(const int n)
10357 header_field_info *hfinfo;
10359 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10360 return hfinfo->parent;
10364 proto_registrar_is_protocol(const int n)
10366 header_field_info *hfinfo;
10368 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10369 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
10372 /* Returns length of field in packet (not necessarily the length
10373 * in our internal representation, as in the case of IPv4).
10374 * 0 means undeterminable at time of registration
10375 * -1 means the field is not registered. */
10377 proto_registrar_get_length(const int n)
10379 header_field_info *hfinfo;
10381 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10382 return ftype_length(hfinfo->type);
10385 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
10386 * it exists anywhere, or FALSE if it exists nowhere. */
10388 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
10390 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
10392 if (g_ptr_array_len(ptrs) > 0) {
10400 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
10401 * This only works if the hfindex was "primed" before the dissection
10402 * took place, as we just pass back the already-created GPtrArray*.
10403 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
10406 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
10411 if (PTREE_DATA(tree)->interesting_hfids != NULL)
10412 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
10413 GINT_TO_POINTER(id));
10419 proto_tracking_interesting_fields(const proto_tree *tree)
10421 GHashTable *interesting_hfids;
10426 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
10428 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
10431 /* Helper struct for proto_find_info() and proto_all_finfos() */
10437 /* Helper function for proto_find_info() */
10439 find_finfo(proto_node *node, gpointer data)
10441 field_info *fi = PNODE_FINFO(node);
10442 if (fi && fi->hfinfo) {
10443 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
10444 g_ptr_array_add(((ffdata_t*)data)->array, fi);
10448 /* Don't stop traversing. */
10452 /* Helper function for proto_find_first_info() */
10454 find_first_finfo(proto_node *node, gpointer data)
10456 field_info *fi = PNODE_FINFO(node);
10457 if (fi && fi->hfinfo) {
10458 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
10459 g_ptr_array_add(((ffdata_t*)data)->array, fi);
10461 /* Stop traversing. */
10466 /* Continue traversing. */
10470 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
10471 * This works on any proto_tree, primed or unprimed, but actually searches
10472 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
10473 * The caller does need to free the returned GPtrArray with
10474 * g_ptr_array_free(<array>, TRUE).
10477 proto_find_finfo(proto_tree *tree, const int id)
10481 ffdata.array = g_ptr_array_new();
10484 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
10486 return ffdata.array;
10489 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
10490 * This works on any proto_tree, primed or unprimed, but actually searches
10491 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
10492 * The caller does need to free the returned GPtrArray with
10493 * g_ptr_array_free(<array>, TRUE).
10496 proto_find_first_finfo(proto_tree *tree, const int id)
10500 ffdata.array = g_ptr_array_new();
10503 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
10505 return ffdata.array;
10508 /* Helper function for proto_all_finfos() */
10510 every_finfo(proto_node *node, gpointer data)
10512 field_info *fi = PNODE_FINFO(node);
10513 if (fi && fi->hfinfo) {
10514 g_ptr_array_add(((ffdata_t*)data)->array, fi);
10517 /* Don't stop traversing. */
10521 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
10523 proto_all_finfos(proto_tree *tree)
10527 /* Pre allocate enough space to hold all fields in most cases */
10528 ffdata.array = g_ptr_array_sized_new(512);
10531 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
10533 return ffdata.array;
10544 check_for_offset(proto_node *node, gpointer data)
10546 field_info *fi = PNODE_FINFO(node);
10547 offset_search_t *offsearch = (offset_search_t *)data;
10549 /* !fi == the top most container node which holds nothing */
10550 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
10551 if (offsearch->offset >= (guint) fi->start &&
10552 offsearch->offset < (guint) (fi->start + fi->length)) {
10554 offsearch->finfo = fi;
10555 return FALSE; /* keep traversing */
10558 return FALSE; /* keep traversing */
10561 /* Search a proto_tree backwards (from leaves to root) looking for the field
10562 * whose start/length occupies 'offset' */
10563 /* XXX - I couldn't find an easy way to search backwards, so I search
10564 * forwards, w/o stopping. Therefore, the last finfo I find will the be
10565 * the one I want to return to the user. This algorithm is inefficient
10566 * and could be re-done, but I'd have to handle all the children and
10567 * siblings of each node myself. When I have more time I'll do that.
10570 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
10572 offset_search_t offsearch;
10574 offsearch.offset = offset;
10575 offsearch.finfo = NULL;
10576 offsearch.tvb = tvb;
10578 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
10580 return offsearch.finfo;
10589 check_for_undecoded(proto_node *node, gpointer data)
10591 field_info *fi = PNODE_FINFO(node);
10592 decoded_data_t* decoded = (decoded_data_t*)data;
10597 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
10598 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
10601 decoded->buf[byte] |= (1 << bit);
10609 proto_find_undecoded_data(proto_tree *tree, guint length)
10611 decoded_data_t decoded;
10612 decoded.length = length;
10613 decoded.buf = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
10615 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
10616 return decoded.buf;
10619 /* Dumps the protocols in the registration database to stdout. An independent
10620 * program can take this output and format it into nice tables or HTML or
10623 * There is one record per line. The fields are tab-delimited.
10625 * Field 1 = protocol name
10626 * Field 2 = protocol short name
10627 * Field 3 = protocol filter name
10630 proto_registrar_dump_protocols(void)
10632 protocol_t *protocol;
10634 void *cookie = NULL;
10637 i = proto_get_first_protocol(&cookie);
10639 protocol = find_protocol_by_id(i);
10640 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
10641 protocol->filter_name);
10642 i = proto_get_next_protocol(&cookie);
10646 /* Dumps the value_strings, extended value string headers, range_strings
10647 * or true/false strings for fields that have them.
10648 * There is one record per line. Fields are tab-delimited.
10649 * There are four types of records: Value String, Extended Value String Header,
10650 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
10651 * the type of record.
10653 * Note that a record will be generated only if the value_string,... is referenced
10654 * in a registered hfinfo entry.
10660 * Field 2 = Field abbreviation to which this value string corresponds
10661 * Field 3 = Integer value
10664 * Extended Value String Headers
10665 * -----------------------------
10667 * Field 2 = Field abbreviation to which this extended value string header corresponds
10668 * Field 3 = Extended Value String "Name"
10669 * Field 4 = Number of entries in the associated value_string array
10670 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
10675 * Field 2 = Field abbreviation to which this range string corresponds
10676 * Field 3 = Integer value: lower bound
10677 * Field 4 = Integer value: upper bound
10680 * True/False Strings
10681 * ------------------
10683 * Field 2 = Field abbreviation to which this true/false string corresponds
10684 * Field 3 = True String
10685 * Field 4 = False String
10688 proto_registrar_dump_values(void)
10690 header_field_info *hfinfo;
10692 const value_string *vals;
10693 const val64_string *vals64;
10694 const range_string *range;
10695 const true_false_string *tfs;
10696 const unit_name_string *units;
10698 len = gpa_hfinfo.len;
10699 for (i = 0; i < len ; i++) {
10700 if (gpa_hfinfo.hfi[i] == NULL)
10701 continue; /* This is a deregistered protocol or field */
10703 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10705 if (hfinfo->id == hf_text_only) {
10709 /* ignore protocols */
10710 if (proto_registrar_is_protocol(i)) {
10713 /* process header fields */
10714 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
10716 * If this field isn't at the head of the list of
10717 * fields with this name, skip this field - all
10718 * fields with the same name are really just versions
10719 * of the same field stored in different bits, and
10720 * should have the same type/radix/value list, and
10721 * just differ in their bit masks. (If a field isn't
10722 * a bitfield, but can be, say, 1 or 2 bytes long,
10723 * it can just be made FT_UINT16, meaning the
10724 * *maximum* length is 2 bytes, and be used
10725 * for all lengths.)
10727 if (hfinfo->same_name_prev_id != -1)
10736 if (hfinfo->strings != NULL) {
10737 if (FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM &&
10738 (hfinfo->type == FT_CHAR ||
10739 hfinfo->type == FT_UINT8 ||
10740 hfinfo->type == FT_UINT16 ||
10741 hfinfo->type == FT_UINT24 ||
10742 hfinfo->type == FT_UINT32 ||
10743 hfinfo->type == FT_UINT40 ||
10744 hfinfo->type == FT_UINT48 ||
10745 hfinfo->type == FT_UINT56 ||
10746 hfinfo->type == FT_UINT64 ||
10747 hfinfo->type == FT_INT8 ||
10748 hfinfo->type == FT_INT16 ||
10749 hfinfo->type == FT_INT24 ||
10750 hfinfo->type == FT_INT32 ||
10751 hfinfo->type == FT_INT40 ||
10752 hfinfo->type == FT_INT48 ||
10753 hfinfo->type == FT_INT56 ||
10754 hfinfo->type == FT_INT64 ||
10755 hfinfo->type == FT_FLOAT ||
10756 hfinfo->type == FT_DOUBLE)) {
10758 if (hfinfo->display & BASE_RANGE_STRING) {
10759 range = (const range_string *)hfinfo->strings;
10760 } else if (hfinfo->display & BASE_EXT_STRING) {
10761 if (hfinfo->display & BASE_VAL64_STRING) {
10762 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings);
10764 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
10766 } else if (hfinfo->display & BASE_VAL64_STRING) {
10767 vals64 = (const val64_string *)hfinfo->strings;
10768 } else if (hfinfo->display & BASE_UNIT_STRING) {
10769 units = (const unit_name_string *)hfinfo->strings;
10771 vals = (const value_string *)hfinfo->strings;
10774 else if (hfinfo->type == FT_BOOLEAN) {
10775 tfs = (const struct true_false_string *)hfinfo->strings;
10779 /* Print value strings? */
10781 if (hfinfo->display & BASE_EXT_STRING) {
10782 if (hfinfo->display & BASE_VAL64_STRING) {
10783 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
10784 if (!val64_string_ext_validate(vse_p)) {
10785 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev);
10788 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
10789 printf("E\t%s\t%u\t%s\t%s\n",
10791 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p),
10792 VAL64_STRING_EXT_VS_NAME(vse_p),
10793 val64_string_ext_match_type_str(vse_p));
10795 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
10796 if (!value_string_ext_validate(vse_p)) {
10797 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
10800 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
10801 printf("E\t%s\t%u\t%s\t%s\n",
10803 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
10804 VALUE_STRING_EXT_VS_NAME(vse_p),
10805 value_string_ext_match_type_str(vse_p));
10809 while (vals[vi].strptr) {
10810 /* Print in the proper base */
10811 if (hfinfo->type == FT_CHAR) {
10812 if (g_ascii_isprint(vals[vi].value)) {
10813 printf("V\t%s\t'%c'\t%s\n",
10818 if (hfinfo->display == BASE_HEX) {
10819 printf("V\t%s\t'\\x%02x'\t%s\n",
10825 printf("V\t%s\t'\\%03o'\t%s\n",
10832 if (hfinfo->display == BASE_HEX) {
10833 printf("V\t%s\t0x%x\t%s\n",
10839 printf("V\t%s\t%u\t%s\n",
10850 while (vals64[vi].strptr) {
10851 printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
10854 vals64[vi].strptr);
10859 /* print range strings? */
10862 while (range[vi].strptr) {
10863 /* Print in the proper base */
10864 if (FIELD_DISPLAY(hfinfo->display) == BASE_HEX) {
10865 printf("R\t%s\t0x%x\t0x%x\t%s\n",
10867 range[vi].value_min,
10868 range[vi].value_max,
10872 printf("R\t%s\t%u\t%u\t%s\n",
10874 range[vi].value_min,
10875 range[vi].value_max,
10882 /* Print true/false strings? */
10884 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
10885 tfs->true_string, tfs->false_string);
10887 /* Print unit strings? */
10889 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
10890 units->singular, units->plural ? units->plural : "(no plural)");
10895 /* Prints the number of registered fields.
10896 * Useful for determining an appropriate value for
10897 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
10899 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
10900 * the number of fields, TRUE otherwise.
10903 proto_registrar_dump_fieldcount(void)
10906 header_field_info *hfinfo;
10907 guint32 deregistered_count = 0;
10908 guint32 same_name_count = 0;
10909 guint32 protocol_count = 0;
10911 for (i = 0; i < gpa_hfinfo.len; i++) {
10912 if (gpa_hfinfo.hfi[i] == NULL) {
10913 deregistered_count++;
10914 continue; /* This is a deregistered protocol or header field */
10917 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10919 if (proto_registrar_is_protocol(i))
10922 if (hfinfo->same_name_prev_id != -1)
10926 printf("There are %u header fields registered, of which:\n"
10927 "\t%u are deregistered\n"
10928 "\t%u are protocols\n"
10929 "\t%u have the same name as another field\n\n",
10930 gpa_hfinfo.len, deregistered_count, protocol_count,
10933 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
10934 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
10935 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
10938 printf("The header field table consumes %u KiB of memory.\n",
10939 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
10940 printf("The fields themselves consume %u KiB of memory.\n",
10941 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
10943 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
10947 elastic_add_base_mapping(json_dumper *dumper)
10949 json_dumper_set_member_name(dumper, "index_patterns");
10950 json_dumper_value_string(dumper, "packets-*");
10952 json_dumper_set_member_name(dumper, "settings");
10953 json_dumper_begin_object(dumper);
10954 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
10955 json_dumper_value_anyf(dumper, "%d", 1000000);
10956 json_dumper_end_object(dumper);
10960 ws_type_to_elastic(guint type _U_)
10977 case FT_UINT64: // Actually it's not handled by 'long' elastic type.
10987 case FT_ABSOLUTE_TIME:
10988 case FT_RELATIVE_TIME:
10991 case FT_UINT_BYTES:
11001 dot_to_underscore(gchar* str)
11004 for (i = 0; i < strlen(str); i++) {
11011 /* Dumps a mapping file for ElasticSearch
11014 proto_registrar_dump_elastic(const gchar* filter)
11016 header_field_info *hfinfo;
11017 header_field_info *parent_hfinfo;
11019 gboolean open_object = TRUE;
11020 const char* prev_proto = NULL;
11022 gchar** protos = NULL;
11028 /* We have filtering protocols. Extract them. */
11030 protos = g_strsplit(filter, ",", -1);
11034 * To help tracking down the json tree, objects have been appended with a comment:
11035 * n.label -> where n is the indentation level and label the name of the object
11038 json_dumper dumper = {
11039 .output_file = stdout,
11040 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT,
11042 json_dumper_begin_object(&dumper); // 1.root
11043 elastic_add_base_mapping(&dumper);
11045 json_dumper_set_member_name(&dumper, "mappings");
11046 json_dumper_begin_object(&dumper); // 2.mappings
11047 json_dumper_set_member_name(&dumper, "doc");
11049 json_dumper_begin_object(&dumper); // 3.doc
11050 json_dumper_set_member_name(&dumper, "dynamic");
11051 json_dumper_value_anyf(&dumper, "false");
11053 json_dumper_set_member_name(&dumper, "properties");
11054 json_dumper_begin_object(&dumper); // 4.properties
11055 json_dumper_set_member_name(&dumper, "timestamp");
11056 json_dumper_begin_object(&dumper); // 5.timestamp
11057 json_dumper_set_member_name(&dumper, "type");
11058 json_dumper_value_string(&dumper, "date");
11059 json_dumper_end_object(&dumper); // 5.timestamp
11061 json_dumper_set_member_name(&dumper, "layers");
11062 json_dumper_begin_object(&dumper); // 5.layers
11063 json_dumper_set_member_name(&dumper, "properties");
11064 json_dumper_begin_object(&dumper); // 6.properties
11066 for (i = 0; i < gpa_hfinfo.len; i++) {
11067 if (gpa_hfinfo.hfi[i] == NULL)
11068 continue; /* This is a deregistered protocol or header field */
11070 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
11073 * Skip the pseudo-field for "proto_tree_add_text()" since
11074 * we don't want it in the list of filterable protocols.
11076 if (hfinfo->id == hf_text_only)
11079 if (!proto_registrar_is_protocol(i)) {
11080 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
11083 * Skip the field if filter protocols have been set and this one's
11084 * parent is not listed.
11091 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
11102 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
11103 json_dumper_end_object(&dumper); // 8.properties
11104 json_dumper_end_object(&dumper); // 7.parent_hfinfo->abbrev
11105 open_object = TRUE;
11108 prev_proto = parent_hfinfo->abbrev;
11111 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
11112 json_dumper_begin_object(&dumper); // 7.parent_hfinfo->abbrev
11113 json_dumper_set_member_name(&dumper, "properties");
11114 json_dumper_begin_object(&dumper); // 8.properties
11115 open_object = FALSE;
11117 /* Skip the fields that would map into string. This is the default in elasticsearch. */
11118 type = ws_type_to_elastic(hfinfo->type);
11120 str = g_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev);
11121 json_dumper_set_member_name(&dumper, dot_to_underscore(str));
11123 json_dumper_begin_object(&dumper); // 9.hfinfo->abbrev
11124 json_dumper_set_member_name(&dumper, "type");
11125 json_dumper_value_string(&dumper, type);
11126 json_dumper_end_object(&dumper); // 9.hfinfo->abbrev
11132 json_dumper_end_object(&dumper); // 8.properties
11133 json_dumper_end_object(&dumper); // 7.parent_hfinfo->abbrev
11136 json_dumper_end_object(&dumper); // 6.properties
11137 json_dumper_end_object(&dumper); // 5.layers
11138 json_dumper_end_object(&dumper); // 4.properties
11139 json_dumper_end_object(&dumper); // 3.doc
11140 json_dumper_end_object(&dumper); // 2.mappings
11141 json_dumper_end_object(&dumper); // 1.root
11142 gboolean ret = json_dumper_finish(&dumper);
11143 DISSECTOR_ASSERT(ret);
11145 g_strfreev(protos);
11148 /* Dumps the contents of the registration database to stdout. An independent
11149 * program can take this output and format it into nice tables or HTML or
11152 * There is one record per line. Each record is either a protocol or a header
11153 * field, differentiated by the first field. The fields are tab-delimited.
11158 * Field 2 = descriptive protocol name
11159 * Field 3 = protocol abbreviation
11164 * Field 2 = descriptive field name
11165 * Field 3 = field abbreviation
11166 * Field 4 = type ( textual representation of the the ftenum type )
11167 * Field 5 = parent protocol abbreviation
11168 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
11169 * Field 7 = bitmask: format: hex: 0x....
11170 * Field 8 = blurb describing field
11173 proto_registrar_dump_fields(void)
11175 header_field_info *hfinfo, *parent_hfinfo;
11177 const char *enum_name;
11178 const char *base_name;
11182 len = gpa_hfinfo.len;
11183 for (i = 0; i < len ; i++) {
11184 if (gpa_hfinfo.hfi[i] == NULL)
11185 continue; /* This is a deregistered protocol or header field */
11187 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
11190 * Skip the pseudo-field for "proto_tree_add_text()" since
11191 * we don't want it in the list of filterable fields.
11193 if (hfinfo->id == hf_text_only)
11196 /* format for protocols */
11197 if (proto_registrar_is_protocol(i)) {
11198 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
11200 /* format for header fields */
11203 * If this field isn't at the head of the list of
11204 * fields with this name, skip this field - all
11205 * fields with the same name are really just versions
11206 * of the same field stored in different bits, and
11207 * should have the same type/radix/value list, and
11208 * just differ in their bit masks. (If a field isn't
11209 * a bitfield, but can be, say, 1 or 2 bytes long,
11210 * it can just be made FT_UINT16, meaning the
11211 * *maximum* length is 2 bytes, and be used
11212 * for all lengths.)
11214 if (hfinfo->same_name_prev_id != -1)
11217 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
11219 enum_name = ftype_name(hfinfo->type);
11222 if (hfinfo->type == FT_CHAR ||
11223 hfinfo->type == FT_UINT8 ||
11224 hfinfo->type == FT_UINT16 ||
11225 hfinfo->type == FT_UINT24 ||
11226 hfinfo->type == FT_UINT32 ||
11227 hfinfo->type == FT_UINT40 ||
11228 hfinfo->type == FT_UINT48 ||
11229 hfinfo->type == FT_UINT56 ||
11230 hfinfo->type == FT_UINT64 ||
11231 hfinfo->type == FT_INT8 ||
11232 hfinfo->type == FT_INT16 ||
11233 hfinfo->type == FT_INT24 ||
11234 hfinfo->type == FT_INT32 ||
11235 hfinfo->type == FT_INT40 ||
11236 hfinfo->type == FT_INT48 ||
11237 hfinfo->type == FT_INT56 ||
11238 hfinfo->type == FT_INT64) {
11240 switch (FIELD_DISPLAY(hfinfo->display)) {
11253 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
11256 base_name = "????";
11259 } else if (hfinfo->type == FT_BOOLEAN) {
11260 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
11261 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
11265 blurb = hfinfo->blurb;
11268 else if (strlen(blurb) == 0)
11271 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
11272 hfinfo->name, hfinfo->abbrev, enum_name,
11273 parent_hfinfo->abbrev, base_name,
11274 hfinfo->bitmask, blurb);
11279 /* Dumps field types and descriptive names to stdout. An independent
11280 * program can take this output and format it into nice tables or HTML or
11283 * There is one record per line. The fields are tab-delimited.
11285 * Field 1 = field type name, e.g. FT_UINT8
11286 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
11289 proto_registrar_dump_ftypes(void)
11293 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
11294 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
11298 /* This function indicates whether it's possible to construct a
11299 * "match selected" display filter string for the specified field,
11300 * returns an indication of whether it's possible, and, if it's
11301 * possible and "filter" is non-null, constructs the filter and
11302 * sets "*filter" to point to it.
11303 * You do not need to [g_]free() this string since it will be automatically
11304 * freed once the next packet is dissected.
11307 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
11310 header_field_info *hfinfo;
11314 int dfilter_len, i;
11315 gint start, length, length_remaining;
11317 gchar is_signed_num = FALSE;
11322 hfinfo = finfo->hfinfo;
11323 DISSECTOR_ASSERT(hfinfo);
11324 abbrev_len = (int) strlen(hfinfo->abbrev);
11326 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
11327 const gchar *str = NULL;
11329 switch (hfinfo->type) {
11335 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
11343 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
11350 if (str != NULL && filter != NULL) {
11351 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
11357 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
11358 * functions for FT_UINT and FT_INT types, as we choose the base in
11359 * the string expression based on the display base of the field.
11361 * Note that the base does matter, as this is also used for
11362 * the protocolinfo tap.
11364 * It might be nice to use them in "proto_item_fill_label()"
11365 * as well, although, there, you'd have to deal with the base
11366 * *and* with resolved values for addresses.
11368 * Perhaps we need two different val_to_string routines, one
11369 * to generate items for display filters and one to generate
11370 * strings for display, and pass to both of them the
11371 * "display" and "strings" values in the header_field_info
11372 * structure for the field, so they can get the base and,
11373 * if the field is Boolean or an enumerated integer type,
11374 * the tables used to generate human-readable values.
11376 switch (hfinfo->type) {
11379 if (filter != NULL) {
11385 number = fvalue_get_uinteger(&finfo->value);
11387 out = hfinfo_char_value_format(hfinfo, buf, number);
11389 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
11397 is_signed_num = TRUE;
11404 if (filter != NULL) {
11411 number = fvalue_get_sinteger(&finfo->value);
11413 number = fvalue_get_uinteger(&finfo->value);
11415 out = hfinfo_numeric_value_format(hfinfo, buf, number);
11417 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
11425 is_signed_num = TRUE;
11431 if (filter != NULL) {
11438 number = fvalue_get_sinteger64(&finfo->value);
11440 number = fvalue_get_uinteger64(&finfo->value);
11442 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
11444 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
11449 if (filter != NULL)
11450 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
11455 * If the length is 0, just match the name of the
11458 * (Also check for negative values, just in case,
11459 * as we'll cast it to an unsigned value later.)
11461 length = finfo->length;
11463 if (filter != NULL)
11464 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
11471 * This doesn't have a value, so we'd match
11472 * on the raw bytes at this address.
11474 * Should we be allowed to access to the raw bytes?
11475 * If "edt" is NULL, the answer is "no".
11481 * Is this field part of the raw frame tvbuff?
11482 * If not, we can't use "frame[N:M]" to match
11485 * XXX - should this be frame-relative, or
11486 * protocol-relative?
11488 * XXX - does this fallback for non-registered
11489 * fields even make sense?
11491 if (finfo->ds_tvb != edt->tvb)
11492 return FALSE; /* you lose */
11495 * Don't go past the end of that tvbuff.
11497 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
11498 if (length > length_remaining)
11499 length = length_remaining;
11503 if (filter != NULL) {
11504 start = finfo->start;
11505 buf_len = 32 + length * 3;
11506 *filter = (char *)wmem_alloc0(NULL, buf_len);
11509 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
11510 "frame[%d:%d] == ", finfo->start, length);
11511 for (i=0; i<length; i++) {
11512 c = tvb_get_guint8(finfo->ds_tvb, start);
11515 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
11518 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
11524 /* By default, use the fvalue's "to_string_repr" method. */
11526 /* Figure out the string length needed.
11527 * The ft_repr length.
11528 * 4 bytes for " == ".
11529 * 1 byte for trailing NUL.
11531 if (filter != NULL) {
11533 dfilter_len = fvalue_string_repr_len(&finfo->value,
11534 FTREPR_DFILTER, finfo->hfinfo->display);
11535 dfilter_len += abbrev_len + 4 + 1;
11536 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
11538 /* Create the string */
11539 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
11540 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
11541 wmem_free(NULL, str);
11550 * Returns TRUE if we can do a "match selected" on the field, FALSE
11554 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
11556 return construct_match_selected_string(finfo, edt, NULL);
11559 /* This function attempts to construct a "match selected" display filter
11560 * string for the specified field; if it can do so, it returns a pointer
11561 * to the string, otherwise it returns NULL.
11563 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
11566 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
11568 char *filter = NULL;
11570 if (!construct_match_selected_string(finfo, edt, &filter))
11572 wmem_free(NULL, filter);
11578 /* This function is common code for all proto_tree_add_bitmask... functions.
11582 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
11583 const int len, const gint ett, int * const *fields,
11584 const int flags, gboolean first,
11585 gboolean use_parent_tree,
11586 proto_tree* tree, guint64 value)
11588 guint64 available_bits = G_MAXUINT64;
11589 guint64 bitmask = 0;
11591 header_field_info *hf;
11597 REPORT_DISSECTOR_BUG("Illegal call of proto_item_add_bitmask_tree without fields");
11599 if (len < 0 || len > 8)
11600 REPORT_DISSECTOR_BUG("Invalid len: %d", len);
11602 * packet-frame.c uses len=0 since the value is taken from the packet
11603 * metadata, not the packet bytes. In that case, assume that all bits
11604 * in the provided value are valid.
11607 available_bits >>= (8 - (guint)len)*8;
11610 if (use_parent_tree == FALSE)
11611 tree = proto_item_add_subtree(item, ett);
11614 guint64 present_bits;
11615 PROTO_REGISTRAR_GET_NTH(**fields,hf);
11616 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
11618 bitmask |= hf->bitmask;
11620 /* Skip fields that aren't fully present */
11621 present_bits = available_bits & hf->bitmask;
11622 if (present_bits != hf->bitmask) {
11627 switch (hf->type) {
11633 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
11640 proto_tree_add_int(tree, **fields, tvb, offset, len, (gint32)value);
11647 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
11654 proto_tree_add_int64(tree, **fields, tvb, offset, len, (gint64)value);
11658 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
11662 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
11665 ftype_name(hf->type));
11668 if (flags & BMT_NO_APPEND) {
11672 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
11674 switch (hf->type) {
11676 if (hf->display == BASE_CUSTOM) {
11677 gchar lbl[ITEM_LABEL_LENGTH];
11678 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11680 DISSECTOR_ASSERT(fmtfunc);
11681 fmtfunc(lbl, (guint32) tmpval);
11682 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11686 else if (hf->strings) {
11687 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11688 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
11691 else if (!(flags & BMT_NO_INT)) {
11696 proto_item_append_text(item, ", ");
11699 out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
11700 proto_item_append_text(item, "%s: %s", hf->name, out);
11710 if (hf->display == BASE_CUSTOM) {
11711 gchar lbl[ITEM_LABEL_LENGTH];
11712 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11714 DISSECTOR_ASSERT(fmtfunc);
11715 fmtfunc(lbl, (guint32) tmpval);
11716 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11720 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11721 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11722 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
11725 else if (!(flags & BMT_NO_INT)) {
11730 proto_item_append_text(item, ", ");
11733 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
11734 if (hf->display & BASE_UNIT_STRING) {
11735 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
11737 proto_item_append_text(item, "%s: %s", hf->name, out);
11748 integer32 = (guint32) tmpval;
11750 no_of_bits = ws_count_ones(hf->bitmask);
11751 integer32 = ws_sign_ext32(integer32, no_of_bits);
11753 if (hf->display == BASE_CUSTOM) {
11754 gchar lbl[ITEM_LABEL_LENGTH];
11755 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11757 DISSECTOR_ASSERT(fmtfunc);
11758 fmtfunc(lbl, (gint32) integer32);
11759 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11763 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11764 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11765 hf->name, hf_try_val_to_str_const((gint32) integer32, hf, "Unknown"));
11768 else if (!(flags & BMT_NO_INT)) {
11773 proto_item_append_text(item, ", ");
11776 out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
11777 if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11778 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
11780 proto_item_append_text(item, "%s: %s", hf->name, out);
11791 if (hf->display == BASE_CUSTOM) {
11792 gchar lbl[ITEM_LABEL_LENGTH];
11793 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
11795 DISSECTOR_ASSERT(fmtfunc);
11796 fmtfunc(lbl, tmpval);
11797 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11801 else if (hf->strings) {
11802 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11803 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
11806 else if (!(flags & BMT_NO_INT)) {
11811 proto_item_append_text(item, ", ");
11814 out = hfinfo_number_value_format64(hf, buf, tmpval);
11815 proto_item_append_text(item, "%s: %s", hf->name, out);
11826 no_of_bits = ws_count_ones(hf->bitmask);
11827 tmpval = ws_sign_ext64(tmpval, no_of_bits);
11829 if (hf->display == BASE_CUSTOM) {
11830 gchar lbl[ITEM_LABEL_LENGTH];
11831 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
11833 DISSECTOR_ASSERT(fmtfunc);
11834 fmtfunc(lbl, (gint64) tmpval);
11835 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11839 else if (hf->strings) {
11840 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11841 hf->name, hf_try_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
11844 else if (!(flags & BMT_NO_INT)) {
11849 proto_item_append_text(item, ", ");
11852 out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
11853 proto_item_append_text(item, "%s: %s", hf->name, out);
11860 if (hf->strings && !(flags & BMT_NO_TFS)) {
11861 /* If we have true/false strings, emit full - otherwise messages
11862 might look weird */
11863 const struct true_false_string *tfs =
11864 (const struct true_false_string *)hf->strings;
11867 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11868 hf->name, tfs->true_string);
11870 } else if (!(flags & BMT_NO_FALSE)) {
11871 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11872 hf->name, tfs->false_string);
11875 } else if (hf->bitmask & value) {
11876 /* If the flag is set, show the name */
11877 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
11882 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
11885 ftype_name(hf->type));
11892 /* XXX: We don't pass the hfi into this function. Perhaps we should,
11893 * but then again most dissectors don't set the bitmask field for
11894 * the higher level bitmask hfi, so calculate the bitmask from the
11895 * fields present. */
11897 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
11898 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
11899 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
11900 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
11905 /* This function will dissect a sequence of bytes that describe a
11906 * bitmask and supply the value of that sequence through a pointer.
11907 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
11909 * This field will form an expansion under which the individual fields of the
11910 * bitmask is dissected and displayed.
11911 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
11913 * fields is an array of pointers to int that lists all the fields of the
11914 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
11915 * or another integer of the same type/size as hf_hdr with a mask specified.
11916 * This array is terminated by a NULL entry.
11918 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
11919 * FT_integer fields that have a value_string attached will have the
11920 * matched string displayed on the expansion line.
11923 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
11924 const guint offset, const int hf_hdr,
11925 const gint ett, int * const *fields,
11926 const guint encoding, guint64 *retval)
11928 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);
11931 /* This function will dissect a sequence of bytes that describe a
11933 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
11935 * This field will form an expansion under which the individual fields of the
11936 * bitmask is dissected and displayed.
11937 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
11939 * fields is an array of pointers to int that lists all the fields of the
11940 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
11941 * or another integer of the same type/size as hf_hdr with a mask specified.
11942 * This array is terminated by a NULL entry.
11944 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
11945 * FT_integer fields that have a value_string attached will have the
11946 * matched string displayed on the expansion line.
11949 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
11950 const guint offset, const int hf_hdr,
11951 const gint ett, int * const *fields,
11952 const guint encoding)
11954 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
11957 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
11958 * what data is appended to the header.
11961 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11962 const int hf_hdr, const gint ett, int * const *fields, const guint encoding, const int flags,
11965 proto_item *item = NULL;
11966 header_field_info *hf;
11970 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
11971 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
11972 len = ftype_length(hf->type);
11973 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
11976 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
11977 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
11978 flags, FALSE, FALSE, NULL, value);
11983 /* Mask out irrelevant portions */
11984 *retval &= hf->bitmask;
11986 *retval >>= hfinfo_bitshift(hf);
11992 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
11993 * what data is appended to the header.
11996 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11997 const int hf_hdr, const gint ett, int * const *fields, const guint encoding, const int flags)
11999 proto_item *item = NULL;
12000 header_field_info *hf;
12004 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
12005 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
12008 len = ftype_length(hf->type);
12009 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12010 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12011 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12012 flags, FALSE, FALSE, NULL, value);
12018 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
12019 can't be retrieved directly from tvb) */
12021 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
12022 const int hf_hdr, const gint ett, int * const *fields, const guint64 value)
12024 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
12025 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
12028 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
12029 WS_DLL_PUBLIC proto_item *
12030 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
12031 const int hf_hdr, const gint ett, int * const *fields, const guint64 value, const int flags)
12033 proto_item *item = NULL;
12034 header_field_info *hf;
12037 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
12038 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
12039 /* the proto_tree_add_uint/_uint64() calls below
12040 will fail if tvb==NULL and len!=0 */
12041 len = tvb ? ftype_length(hf->type) : 0;
12045 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
12047 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
12049 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12050 flags, FALSE, FALSE, NULL, value);
12056 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
12058 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
12059 const int len, int * const *fields, const guint encoding)
12064 value = get_uint64_value(tree, tvb, offset, len, encoding);
12065 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
12066 BMT_NO_APPEND, FALSE, TRUE, tree, value);
12071 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
12072 const int len, int * const *fields, const guint64 value)
12075 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
12076 BMT_NO_APPEND, FALSE, TRUE, tree, value);
12081 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
12082 * This is intended to support bitmask fields whose lengths can vary, perhaps
12083 * as the underlying standard evolves over time.
12084 * With this API there is the possibility of being called to display more or
12085 * less data than the dissector was coded to support.
12086 * In such cases, it is assumed that bitmasks are extended on the MSb end.
12087 * Thus when presented with "too much" or "too little" data, MSbits will be
12088 * ignored or MSfields sacrificed.
12090 * Only fields for which all defined bits are available are displayed.
12093 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
12094 const guint offset, const guint len, const int hf_hdr,
12095 const gint ett, int * const *fields, struct expert_field* exp,
12096 const guint encoding)
12098 proto_item *item = NULL;
12099 header_field_info *hf;
12100 guint decodable_len;
12101 guint decodable_offset;
12102 guint32 decodable_value;
12105 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
12106 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
12108 decodable_offset = offset;
12109 decodable_len = MIN(len, (guint) ftype_length(hf->type));
12111 /* If we are ftype_length-limited,
12112 * make sure we decode as many LSBs as possible.
12114 if (encoding == ENC_BIG_ENDIAN) {
12115 decodable_offset += (len - decodable_len);
12119 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
12120 decodable_len, encoding);
12122 /* The root item covers all the bytes even if we can't decode them all */
12123 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
12127 if (decodable_len < len) {
12128 /* Dissector likely requires updating for new protocol revision */
12129 expert_add_info_format(NULL, item, exp,
12130 "Only least-significant %d of %d bytes decoded",
12131 decodable_len, len);
12135 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
12136 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
12137 ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
12143 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
12145 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
12146 const guint offset, const guint len,
12147 const char *name, const char *fallback,
12148 const gint ett, int * const *fields,
12149 const guint encoding, const int flags)
12151 proto_item *item = NULL;
12155 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
12156 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12157 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12158 flags, TRUE, FALSE, NULL, value) && fallback) {
12159 /* Still at first item - append 'fallback' text if any */
12160 proto_item_append_text(item, "%s", fallback);
12168 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12169 const guint bit_offset, const gint no_of_bits,
12170 const guint encoding)
12172 header_field_info *hfinfo;
12176 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
12178 octet_length = (no_of_bits + 7) >> 3;
12179 octet_offset = bit_offset >> 3;
12180 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
12182 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
12183 * but only after doing a bunch more work (which we can, in the common
12184 * case, shortcut here).
12186 CHECK_FOR_NULL_TREE(tree);
12187 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12189 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
12193 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
12194 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
12195 * Offset should be given in bits from the start of the tvb.
12198 static proto_item *
12199 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12200 const guint bit_offset, const gint no_of_bits,
12201 guint64 *return_value, const guint encoding)
12205 guint8 tot_no_bits;
12207 char lbl_str[ITEM_LABEL_LENGTH];
12209 guint8 *bytes = NULL;
12210 size_t bytes_length = 0;
12213 header_field_info *hf_field;
12215 const true_false_string *tfstring;
12217 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
12218 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
12220 if (hf_field->bitmask != 0) {
12221 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_ret_val"
12222 " with field '%s' (%s) with bitmask != 0",
12223 hf_field->abbrev, hf_field->name);
12226 if (no_of_bits == 0) {
12227 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0",
12231 /* Byte align offset */
12232 offset = bit_offset>>3;
12235 * Calculate the number of octets used to hold the bits
12237 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
12238 length = (tot_no_bits + 7) >> 3;
12240 if (no_of_bits < 65) {
12241 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
12242 } else if (hf_field->type != FT_BYTES) {
12243 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 65",
12244 hf_field->abbrev, no_of_bits);
12248 /* Sign extend for signed types */
12249 switch (hf_field->type) {
12258 value = ws_sign_ext64(value, no_of_bits);
12265 if (return_value) {
12266 *return_value = value;
12269 /* Coast clear. Try and fake it */
12270 CHECK_FOR_NULL_TREE(tree);
12271 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12273 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
12275 switch (hf_field->type) {
12277 /* Boolean field */
12278 tfstring = &tfs_true_false;
12279 if (hf_field->strings)
12280 tfstring = (const true_false_string *)hf_field->strings;
12281 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
12283 bf_str, hf_field->name, tfs_get_string(!!value, tfstring));
12287 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
12288 fill_label_char(PITEM_FINFO(pi), lbl_str);
12295 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
12296 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
12303 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
12304 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
12311 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
12312 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
12319 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
12320 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
12324 bytes = tvb_get_bits_array(wmem_packet_scope(), tvb, bit_offset, no_of_bits, &bytes_length);
12325 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (gint) bytes_length);
12326 proto_item_fill_label(PITEM_FINFO(pi), lbl_str);
12327 proto_item_set_text(pi, "%s", lbl_str);
12332 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()",
12335 ftype_name(hf_field->type));
12340 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
12345 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12346 const guint bit_offset, const crumb_spec_t *crumb_spec,
12347 guint64 *return_value)
12352 guint mask_initial_bit_offset;
12353 guint mask_greatest_bit_offset;
12354 guint octet_length;
12357 char lbl_str[ITEM_LABEL_LENGTH];
12359 guint64 composite_bitmask;
12360 guint64 composite_bitmap;
12362 header_field_info *hf_field;
12363 const true_false_string *tfstring;
12365 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
12366 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
12368 if (hf_field->bitmask != 0) {
12369 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_split_bits_item_ret_val"
12370 " with field '%s' (%s) with bitmask != 0",
12371 hf_field->abbrev, hf_field->name);
12374 mask_initial_bit_offset = bit_offset % 8;
12379 mask_greatest_bit_offset = 0;
12380 composite_bitmask = 0;
12381 composite_bitmap = 0;
12383 while (crumb_spec[i].crumb_bit_length != 0) {
12384 guint64 crumb_mask, crumb_value;
12385 guint8 crumb_end_bit_offset;
12387 crumb_value = tvb_get_bits64(tvb,
12388 bit_offset + crumb_spec[i].crumb_bit_offset,
12389 crumb_spec[i].crumb_bit_length,
12391 value += crumb_value;
12392 no_of_bits += crumb_spec[i].crumb_bit_length;
12393 DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "a value larger than 64 bits cannot be represented");
12395 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
12396 octet containing the initial offset.
12397 If the mask is beyond 32 bits, then give up on bit map display.
12398 This could be improved in future, probably showing a table
12399 of 32 or 64 bits per row */
12400 if (mask_greatest_bit_offset < 32) {
12401 crumb_end_bit_offset = mask_initial_bit_offset
12402 + crumb_spec[i].crumb_bit_offset
12403 + crumb_spec[i].crumb_bit_length;
12404 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
12406 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
12407 mask_greatest_bit_offset = crumb_end_bit_offset;
12409 /* Currently the bitmap of the crumbs are only shown if
12410 * smaller than 32 bits. Do not bother calculating the
12411 * mask if it is larger than that. */
12412 if (crumb_end_bit_offset <= 32) {
12413 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
12414 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
12417 /* Shift left for the next segment */
12418 value <<= crumb_spec[++i].crumb_bit_length;
12421 /* Sign extend for signed types */
12422 switch (hf_field->type) {
12431 value = ws_sign_ext64(value, no_of_bits);
12437 if (return_value) {
12438 *return_value = value;
12441 /* Coast clear. Try and fake it */
12442 CHECK_FOR_NULL_TREE(tree);
12443 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12445 /* initialise the format string */
12448 octet_offset = bit_offset >> 3;
12450 /* Round up mask length to nearest octet */
12451 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
12452 mask_greatest_bit_offset = octet_length << 3;
12454 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
12455 It would be a useful enhancement to eliminate this restriction. */
12456 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
12457 other_decode_bitfield_value(bf_str,
12458 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
12459 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
12460 mask_greatest_bit_offset);
12462 /* If the bitmask is too large, try to describe its contents. */
12463 g_snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
12466 switch (hf_field->type) {
12467 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
12468 /* Boolean field */
12469 tfstring = &tfs_true_false;
12470 if (hf_field->strings)
12471 tfstring = (const true_false_string *) hf_field->strings;
12472 return proto_tree_add_boolean_format(tree, hfindex,
12473 tvb, octet_offset, octet_length, (guint32)value,
12475 bf_str, hf_field->name, tfs_get_string(!!value, tfstring));
12479 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
12480 fill_label_char(PITEM_FINFO(pi), lbl_str);
12487 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
12488 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
12495 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
12496 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
12503 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
12504 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
12511 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
12512 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
12516 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()",
12519 ftype_name(hf_field->type));
12523 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
12528 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
12529 const crumb_spec_t *crumb_spec, guint16 crumb_index)
12531 header_field_info *hfinfo;
12533 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
12534 proto_tree_add_text_internal(tree, tvb,
12536 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
12537 "%s crumb %d of %s (decoded above)",
12538 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
12541 crumb_spec[crumb_index].crumb_bit_length,
12548 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12549 const guint bit_offset, const gint no_of_bits,
12550 guint64 *return_value, const guint encoding)
12554 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
12555 bit_offset, no_of_bits,
12556 return_value, encoding))) {
12557 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
12558 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
12563 static proto_item *
12564 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
12565 tvbuff_t *tvb, const guint bit_offset,
12566 const gint no_of_bits, void *value_ptr,
12571 guint8 tot_no_bits;
12574 header_field_info *hf_field;
12576 /* We do not have to return a value, try to fake it as soon as possible */
12577 CHECK_FOR_NULL_TREE(tree);
12578 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12580 if (hf_field->bitmask != 0) {
12581 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_format_value"
12582 " with field '%s' (%s) with bitmask != 0",
12583 hf_field->abbrev, hf_field->name);
12586 if (no_of_bits == 0) {
12587 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0",
12591 /* Byte align offset */
12592 offset = bit_offset>>3;
12595 * Calculate the number of octets used to hold the bits
12597 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
12598 length = tot_no_bits>>3;
12599 /* If we are using part of the next octet, increase length by 1 */
12600 if (tot_no_bits & 0x07)
12603 if (no_of_bits < 65) {
12604 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
12606 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65",
12607 hf_field->abbrev, no_of_bits);
12611 str = decode_bits_in_field(bit_offset, no_of_bits, value);
12613 (void) g_strlcat(str, " = ", 256+64);
12614 (void) g_strlcat(str, hf_field->name, 256+64);
12617 * This function does not receive an actual value but a dimensionless pointer to that value.
12618 * For this reason, the type of the header field is examined in order to determine
12619 * what kind of value we should read from this address.
12620 * The caller of this function must make sure that for the specific header field type the address of
12621 * a compatible value is provided.
12623 switch (hf_field->type) {
12625 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
12626 "%s: %s", str, value_str);
12634 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
12635 "%s: %s", str, value_str);
12642 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
12643 "%s: %s", str, value_str);
12650 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
12651 "%s: %s", str, value_str);
12658 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
12659 "%s: %s", str, value_str);
12663 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
12664 "%s: %s", str, value_str);
12668 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()",
12671 ftype_name(hf_field->type));
12677 static proto_item *
12678 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
12679 tvbuff_t *tvb, const guint bit_offset,
12680 const gint no_of_bits, void *value_ptr,
12685 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
12686 tvb, bit_offset, no_of_bits,
12687 value_ptr, value_str))) {
12688 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
12689 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
12694 #define CREATE_VALUE_STRING(dst,format,ap) \
12695 va_start(ap, format); \
12696 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
12700 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
12701 tvbuff_t *tvb, const guint bit_offset,
12702 const gint no_of_bits, guint32 value,
12703 const char *format, ...)
12707 header_field_info *hf_field;
12709 CHECK_FOR_NULL_TREE(tree);
12711 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12713 switch (hf_field->type) {
12721 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
12727 CREATE_VALUE_STRING(dst, format, ap);
12729 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12733 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
12734 tvbuff_t *tvb, const guint bit_offset,
12735 const gint no_of_bits, guint64 value,
12736 const char *format, ...)
12740 header_field_info *hf_field;
12742 CHECK_FOR_NULL_TREE(tree);
12744 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12746 switch (hf_field->type) {
12754 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
12760 CREATE_VALUE_STRING(dst, format, ap);
12762 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12766 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
12767 tvbuff_t *tvb, const guint bit_offset,
12768 const gint no_of_bits, float value,
12769 const char *format, ...)
12773 header_field_info *hf_field;
12775 CHECK_FOR_NULL_TREE(tree);
12777 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12779 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
12781 CREATE_VALUE_STRING(dst, format, ap);
12783 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12787 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
12788 tvbuff_t *tvb, const guint bit_offset,
12789 const gint no_of_bits, gint32 value,
12790 const char *format, ...)
12794 header_field_info *hf_field;
12796 CHECK_FOR_NULL_TREE(tree);
12798 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12800 switch (hf_field->type) {
12808 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
12814 CREATE_VALUE_STRING(dst, format, ap);
12816 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12820 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
12821 tvbuff_t *tvb, const guint bit_offset,
12822 const gint no_of_bits, gint64 value,
12823 const char *format, ...)
12827 header_field_info *hf_field;
12829 CHECK_FOR_NULL_TREE(tree);
12831 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12833 switch (hf_field->type) {
12841 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
12847 CREATE_VALUE_STRING(dst, format, ap);
12849 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12853 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
12854 tvbuff_t *tvb, const guint bit_offset,
12855 const gint no_of_bits, guint32 value,
12856 const char *format, ...)
12860 header_field_info *hf_field;
12862 CHECK_FOR_NULL_TREE(tree);
12864 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12866 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
12868 CREATE_VALUE_STRING(dst, format, ap);
12870 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12874 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
12875 tvbuff_t *tvb, const guint bit_offset,
12876 const gint no_of_bits, guint64 value,
12877 const char *format, ...)
12881 header_field_info *hf_field;
12883 CHECK_FOR_NULL_TREE(tree);
12885 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12887 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
12889 CREATE_VALUE_STRING(dst, format, ap);
12891 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12895 proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12896 const guint bit_offset, const gint no_of_chars)
12899 header_field_info *hfinfo;
12904 CHECK_FOR_NULL_TREE(tree);
12906 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12908 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
12910 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
12911 byte_offset = bit_offset >> 3;
12913 string = tvb_get_ts_23_038_7bits_string_packed(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
12915 if (hfinfo->display == STR_UNICODE) {
12916 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
12919 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
12920 DISSECTOR_ASSERT(byte_length >= 0);
12921 proto_tree_set_string(PNODE_FINFO(pi), string);
12927 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12928 const guint bit_offset, const gint no_of_chars)
12931 header_field_info *hfinfo;
12936 CHECK_FOR_NULL_TREE(tree);
12938 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12940 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
12942 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
12943 byte_offset = bit_offset >> 3;
12945 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
12947 if (hfinfo->display == STR_UNICODE) {
12948 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
12951 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
12952 DISSECTOR_ASSERT(byte_length >= 0);
12953 proto_tree_set_string(PNODE_FINFO(pi), string);
12958 const value_string proto_checksum_vals[] = {
12959 { PROTO_CHECKSUM_E_BAD, "Bad" },
12960 { PROTO_CHECKSUM_E_GOOD, "Good" },
12961 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
12962 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
12963 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
12969 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
12970 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
12971 packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
12973 header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
12976 proto_item* ti = NULL;
12978 gboolean incorrect_checksum = TRUE;
12980 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
12982 switch (hfinfo->type) {
12996 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
13000 if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
13001 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
13002 proto_item_set_generated(ti);
13003 if (hf_checksum_status != -1) {
13004 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
13005 proto_item_set_generated(ti2);
13010 if (flags & PROTO_CHECKSUM_GENERATED) {
13011 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
13012 proto_item_set_generated(ti);
13014 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
13015 if (flags & PROTO_CHECKSUM_VERIFY) {
13016 if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
13017 if (computed_checksum == 0) {
13018 proto_item_append_text(ti, " [correct]");
13019 if (hf_checksum_status != -1) {
13020 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13021 proto_item_set_generated(ti2);
13023 incorrect_checksum = FALSE;
13024 } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
13025 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
13028 if (checksum == computed_checksum) {
13029 proto_item_append_text(ti, " [correct]");
13030 if (hf_checksum_status != -1) {
13031 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13032 proto_item_set_generated(ti2);
13034 incorrect_checksum = FALSE;
13038 if (incorrect_checksum) {
13039 if (hf_checksum_status != -1) {
13040 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
13041 proto_item_set_generated(ti2);
13043 if (flags & PROTO_CHECKSUM_ZERO) {
13044 proto_item_append_text(ti, " [incorrect]");
13045 if (bad_checksum_expert != NULL)
13046 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
13048 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
13049 if (bad_checksum_expert != NULL)
13050 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);
13054 if (hf_checksum_status != -1) {
13055 proto_item_append_text(ti, " [unverified]");
13056 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
13057 proto_item_set_generated(ti2);
13066 proto_check_field_name(const gchar *field_name)
13068 const char *p = field_name;
13069 guchar c = '.', lastc;
13074 /* Leading '.' or substring ".." are disallowed. */
13075 if (c == '.' && lastc == '.') {
13078 } while (fld_abbrev_chars[c]);
13080 /* Trailing '.' is disallowed. */
13081 if (lastc == '.') {
13088 tree_expanded(int tree_type)
13090 if (tree_type == -1) {
13093 g_assert(tree_type >= 0 && tree_type < num_tree_types);
13094 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
13098 tree_expanded_set(int tree_type, gboolean value)
13100 g_assert(tree_type >= 0 && tree_type < num_tree_types);
13103 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
13105 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
13109 * Editor modelines - https://www.wireshark.org/tools/modelines.html
13112 * c-basic-offset: 8
13114 * indent-tabs-mode: t
13117 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
13118 * :indentSize=8:tabSize=8:noTabs=false: