2 * Routines for protocol tree
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include <wsutil/bits_ctz.h>
32 #include <wsutil/bits_count_ones.h>
33 #include <wsutil/sign_ext.h>
34 #include <wsutil/utf8_entities.h>
36 #include <ftypes/ftypes-int.h>
39 #include "exceptions.h"
40 #include "ptvcursor.h"
42 #include "addr_resolv.h"
43 #include "address_types.h"
46 #include "epan_dissect.h"
48 #include "wmem/wmem.h"
50 #include "column-utils.h"
51 #include "to_str-int.h"
53 #include "osi-utils.h"
55 #include "show_exception.h"
58 #include <wsutil/ws_printf.h> /* ws_debug_printf/ws_g_warning */
59 #include <wsutil/glib-compat.h>
61 /* Ptvcursor limits */
62 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
63 #define SUBTREE_MAX_LEVELS 256
65 /* Throw an exception if our tree exceeds these. */
66 /* XXX - These should probably be preferences */
67 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
68 #define MAX_TREE_LEVELS (5 * 100)
70 typedef struct __subtree_lvl {
77 subtree_lvl *pushed_tree;
78 guint8 pushed_tree_index;
79 guint8 pushed_tree_max;
85 #define cVALS(x) (const value_string*)(x)
87 /** See inlined comments.
88 @param tree the tree to append this item to
89 @param free_block a code block to call to free resources if this returns
90 @return NULL if 'tree' is null */
91 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block) \
97 /** See inlined comments.
98 @param tree the tree to append this item to
99 @param free_block a code block to call to free resources if this returns
100 @return NULL if 'tree' is null */
101 #define CHECK_FOR_NULL_TREE(tree) \
102 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
104 /** See inlined comments.
105 @param tree the tree to append this item to
106 @param hfindex field index
107 @param hfinfo header_field
108 @param free_block a code block to call to free resources if this returns
109 @return the header field matching 'hfinfo' */
110 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
111 /* If this item is not referenced we don't have to do much work \
112 at all but we should still return a node so that field items \
113 below this node (think proto_item_add_subtree()) will still \
114 have somewhere to attach to or else filtering will not work \
115 (they would be ignored since tree would be NULL). \
116 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
117 since dissectors that want to do proto_item_set_len() or \
118 other operations that dereference this would crash. \
119 We fake FT_PROTOCOL unless some clients have requested us \
122 PTREE_DATA(tree)->count++; \
123 if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) { \
125 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
126 g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
127 /* Let the exception handler add items to the tree */ \
128 PTREE_DATA(tree)->count = 0; \
129 THROW_MESSAGE(DissectorError, \
130 wmem_strdup_printf(wmem_packet_scope(), "More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
132 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo); \
133 if (!(PTREE_DATA(tree)->visible)) { \
134 if (PTREE_FINFO(tree)) { \
135 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
136 && (hfinfo->type != FT_PROTOCOL || \
137 PTREE_DATA(tree)->fake_protocols)) { \
139 /* just return tree back to the caller */\
145 /** See inlined comments.
146 @param tree the tree to append this item to
147 @param hfindex field index
148 @param hfinfo header_field
149 @return the header field matching 'hfinfo' */
150 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
151 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
154 /** See inlined comments.
155 @param pi the created protocol item we're about to return */
156 #define TRY_TO_FAKE_THIS_REPR(pi) \
158 if (!(PTREE_DATA(pi)->visible)) { \
159 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
160 * items string representation */ \
163 /* Same as above but returning void */
164 #define TRY_TO_FAKE_THIS_REPR_VOID(pi) \
167 if (!(PTREE_DATA(pi)->visible)) { \
168 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
169 * items string representation */ \
172 /* Similar to above, but allows a NULL tree */
173 #define TRY_TO_FAKE_THIS_REPR_NESTED(pi) \
174 if ((pi == NULL) || (!(PTREE_DATA(pi)->visible))) { \
175 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
176 * items string representation */ \
180 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
181 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
182 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
184 static void label_mark_truncated(char *label_str, gsize name_pos);
185 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
187 static void fill_label_boolean(field_info *fi, gchar *label_str);
188 static void fill_label_bitfield_char(field_info *fi, gchar *label_str);
189 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
190 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
191 static void fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed);
192 static void fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed);
193 static void fill_label_char(field_info *fi, gchar *label_str);
194 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
195 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
197 static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value);
198 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
199 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
200 static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
201 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
202 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
203 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
204 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
205 static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
206 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
207 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
209 static void proto_cleanup_base(void);
212 proto_tree_add_node(proto_tree *tree, field_info *fi);
215 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
216 gint *item_length, const guint encoding);
219 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
220 gint length, guint item_length, const gint encoding);
223 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
224 const gint start, const gint item_length);
227 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
228 gint start, gint *length);
231 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
233 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
236 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
238 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
240 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
242 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
244 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
246 proto_tree_set_string(field_info *fi, const char* value);
248 proto_tree_set_ax25(field_info *fi, const guint8* value);
250 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
252 proto_tree_set_vines(field_info *fi, const guint8* value);
254 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
256 proto_tree_set_ether(field_info *fi, const guint8* value);
258 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
260 proto_tree_set_ipxnet(field_info *fi, guint32 value);
262 proto_tree_set_ipv4(field_info *fi, guint32 value);
264 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
266 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
268 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
270 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
272 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
274 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
276 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
278 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
280 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
282 proto_tree_set_boolean(field_info *fi, guint64 value);
284 proto_tree_set_float(field_info *fi, float value);
286 proto_tree_set_double(field_info *fi, double value);
288 proto_tree_set_uint(field_info *fi, guint32 value);
290 proto_tree_set_int(field_info *fi, gint32 value);
292 proto_tree_set_uint64(field_info *fi, guint64 value);
294 proto_tree_set_int64(field_info *fi, gint64 value);
296 proto_tree_set_eui64(field_info *fi, const guint64 value);
298 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
300 /* Handle type length mismatch (now filterable) expert info */
301 static int proto_type_length_mismatch = -1;
302 static expert_field ei_type_length_mismatch_error = EI_INIT;
303 static expert_field ei_type_length_mismatch_warn = EI_INIT;
304 static void register_type_length_mismatch(void);
306 /* Handle number string decoding errors with expert info */
307 static int proto_number_string_decoding_error = -1;
308 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
309 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
310 static void register_number_string_decoding_error(void);
312 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
314 /* special-case header field used within proto.c */
315 static header_field_info hfi_text_only =
316 { "Text item", "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
317 int hf_text_only = -1;
319 /* Structure for information about a protocol */
321 const char *name; /* long description */
322 const char *short_name; /* short description */
323 const char *filter_name; /* name of this protocol in filters */
324 GPtrArray *fields; /* fields for this protocol */
325 int proto_id; /* field ID for this protocol */
326 gboolean is_enabled; /* TRUE if protocol is enabled */
327 gboolean enabled_by_default; /* TRUE if protocol is enabled by default */
328 gboolean can_toggle; /* TRUE if is_enabled can be changed */
329 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
330 For dissectors that need a protocol name so they
331 can be added to a dissector table, but use the
332 parent_proto_id for things like enable/disable */
333 GList *heur_list; /* Heuristic dissectors associated with this protocol */
336 /* List of all protocols */
337 static GList *protocols = NULL;
338 static GList *pino_protocols = NULL;
340 /* Deregistered fields */
341 static GPtrArray *deregistered_fields = NULL;
342 static GPtrArray *deregistered_data = NULL;
344 /* indexed by prefix, contains initializers */
345 static GHashTable* prefixes = NULL;
347 /* Contains information about a field when a dissector calls
348 * proto_tree_add_item. */
349 #define FIELD_INFO_NEW(pool, fi) fi = wmem_new(pool, field_info)
350 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
352 /* Contains the space for proto_nodes. */
353 #define PROTO_NODE_INIT(node) \
354 node->first_child = NULL; \
355 node->last_child = NULL; \
358 #define PROTO_NODE_FREE(pool, node) \
359 wmem_free(pool, node)
361 /* String space for protocol and field items for the GUI */
362 #define ITEM_LABEL_NEW(pool, il) \
363 il = wmem_new(pool, item_label_t);
364 #define ITEM_LABEL_FREE(pool, il) \
367 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
368 if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG")) \
369 g_error("Unregistered hf! index=%d", hfindex); \
370 DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
371 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
372 hfinfo = gpa_hfinfo.hfi[hfindex];
374 /* List which stores protocols and fields that have been registered */
375 typedef struct _gpa_hfinfo_t {
377 guint32 allocated_len;
378 header_field_info **hfi;
381 static gpa_hfinfo_t gpa_hfinfo;
383 /* Hash table of abbreviations and IDs */
384 static GHashTable *gpa_name_map = NULL;
385 static header_field_info *same_name_hfinfo;
387 * We're called repeatedly with the same field name when sorting a column.
388 * Cache our last gpa_name_map hit for faster lookups.
390 static char *last_field_name = NULL;
391 static header_field_info *last_hfinfo;
393 static void save_same_name_hfinfo(gpointer data)
395 same_name_hfinfo = (header_field_info*)data;
398 /* Cached value for VINES address type (used for FT_VINES) */
399 static int vines_address_type = -1;
401 /* Points to the first element of an array of bits, indexed by
402 a subtree item type; that array element is TRUE if subtrees of
403 an item of that type are to be expanded. */
404 static guint32 *tree_is_expanded;
406 /* Number of elements in that array. */
409 /* Name hashtables for fast detection of duplicate names */
410 static GHashTable* proto_names = NULL;
411 static GHashTable* proto_short_names = NULL;
412 static GHashTable* proto_filter_names = NULL;
415 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
417 const protocol_t *p1 = (const protocol_t *)p1_arg;
418 const protocol_t *p2 = (const protocol_t *)p2_arg;
420 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
424 check_charset(const guint8 table[256], const char *str)
436 static GSList *dissector_plugins = NULL;
439 proto_register_plugin(const proto_plugin *plug)
442 /* XXX print useful warning */
445 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
449 call_plugin_register_protoinfo(gpointer data, gpointer user_data _U_)
451 proto_plugin *plug = (proto_plugin *)data;
453 if (plug->register_protoinfo) {
454 plug->register_protoinfo();
459 call_plugin_register_handoff(gpointer data, gpointer user_data _U_)
461 proto_plugin *plug = (proto_plugin *)data;
463 if (plug->register_handoff) {
464 plug->register_handoff();
467 #endif /* HAVE_PLUGINS */
469 /* initialize data structures and register protocols and fields */
471 proto_init(GSList *register_all_protocols_list,
472 GSList *register_all_handoffs_list,
474 gpointer client_data)
476 proto_cleanup_base();
478 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
479 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
480 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
483 gpa_hfinfo.allocated_len = 0;
484 gpa_hfinfo.hfi = NULL;
485 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
486 deregistered_fields = g_ptr_array_new();
487 deregistered_data = g_ptr_array_new();
489 /* Initialize the ftype subsystem */
492 /* Initialize the addres type subsystem */
493 address_types_initialize();
495 /* Register one special-case FT_TEXT_ONLY field for use when
496 converting wireshark to new-style proto_tree. These fields
497 are merely strings on the GUI tree; they are not filterable */
498 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
500 /* Register the pseudo-protocols used for exceptions. */
501 register_show_exception();
502 register_type_length_mismatch();
503 register_number_string_decoding_error();
505 /* Have each built-in dissector register its protocols, fields,
506 dissector tables, and dissectors to be called through a
507 handle, and do whatever one-time initialization it needs to
509 for (GSList *l = register_all_protocols_list; l != NULL; l = l->next) {
510 ((void (*)(register_cb, gpointer))l->data)(cb, client_data);
513 /* Now that the VINES dissector has registered it's address
514 type, grab the value for the field type */
515 vines_address_type = address_type_get_by_name("AT_VINES");
517 /* Now call the registration routines for all disssector
520 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
521 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL);
524 /* Now call the "handoff registration" routines of all built-in
525 dissectors; those routines register the dissector in other
526 dissectors' handoff tables, and fetch any dissector handles
528 for (GSList *l = register_all_handoffs_list; l != NULL; l = l->next) {
529 ((void (*)(register_cb, gpointer))l->data)(cb, client_data);
533 /* Now do the same with plugins. */
535 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
536 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL);
539 /* sort the protocols by protocol name */
540 protocols = g_list_sort(protocols, proto_compare_name);
542 /* We've assigned all the subtree type values; allocate the array
543 for them, and zero it out. */
544 tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
548 proto_cleanup_base(void)
550 protocol_t *protocol;
551 header_field_info *hfinfo;
553 /* Free the abbrev/ID hash table */
555 g_hash_table_destroy(gpa_name_map);
558 g_free(last_field_name);
559 last_field_name = NULL;
562 protocol = (protocol_t *)protocols->data;
563 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
564 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
566 g_slice_free(header_field_info, hfinfo);
567 if (protocol->fields) {
568 g_ptr_array_free(protocol->fields, TRUE);
570 g_list_free(protocol->heur_list);
571 protocols = g_list_remove(protocols, protocol);
575 while (pino_protocols) {
576 protocol = (protocol_t *)pino_protocols->data;
577 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
578 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
579 DISSECTOR_ASSERT(protocol->fields == NULL); //helpers should not have any registered fields
580 g_slice_free(header_field_info, hfinfo);
581 DISSECTOR_ASSERT(protocol->heur_list == NULL); //helpers should not have a heuristic list
582 pino_protocols = g_list_remove(pino_protocols, protocol);
587 g_hash_table_destroy(proto_names);
591 if (proto_short_names) {
592 g_hash_table_destroy(proto_short_names);
593 proto_short_names = NULL;
596 if (proto_filter_names) {
597 g_hash_table_destroy(proto_filter_names);
598 proto_filter_names = NULL;
601 if (gpa_hfinfo.allocated_len) {
603 gpa_hfinfo.allocated_len = 0;
604 g_free(gpa_hfinfo.hfi);
605 gpa_hfinfo.hfi = NULL;
608 if (deregistered_fields) {
609 g_ptr_array_free(deregistered_fields, FALSE);
610 deregistered_fields = NULL;
613 if (deregistered_data) {
614 g_ptr_array_free(deregistered_data, FALSE);
615 deregistered_data = NULL;
618 g_free(tree_is_expanded);
619 tree_is_expanded = NULL;
622 g_hash_table_destroy(prefixes);
628 proto_cleanup_base();
631 g_slist_free(dissector_plugins);
632 dissector_plugins = NULL;
637 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
640 proto_node *pnode = tree;
644 if (func(pnode, data))
647 child = pnode->first_child;
648 while (child != NULL) {
650 * The routine we call might modify the child, e.g. by
651 * freeing it, so we get the child's successor before
652 * calling that routine.
655 child = current->next;
656 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
664 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
667 proto_node *pnode = tree;
671 child = pnode->first_child;
672 while (child != NULL) {
674 * The routine we call might modify the child, e.g. by
675 * freeing it, so we get the child's successor before
676 * calling that routine.
679 child = current->next;
680 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
683 if (func(pnode, data))
690 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
693 proto_node *node = tree;
699 node = node->first_child;
700 while (node != NULL) {
702 node = current->next;
703 func((proto_tree *)current, data);
708 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
710 GPtrArray *ptrs = (GPtrArray *)value;
711 gint hfid = GPOINTER_TO_UINT(key);
712 header_field_info *hfinfo;
714 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
715 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
716 /* when a field is referenced by a filter this also
717 affects the refcount for the parent protocol so we need
718 to adjust the refcount for the parent as well
720 if (hfinfo->parent != -1) {
721 header_field_info *parent_hfinfo;
722 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
723 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
725 hfinfo->ref_type = HF_REF_TYPE_NONE;
728 g_ptr_array_free(ptrs, TRUE);
732 proto_tree_free_node(proto_node *node, gpointer data _U_)
734 field_info *finfo = PNODE_FINFO(node);
736 proto_tree_children_foreach(node, proto_tree_free_node, NULL);
738 FVALUE_CLEANUP(&finfo->value);
742 proto_tree_reset(proto_tree *tree)
744 tree_data_t *tree_data = PTREE_DATA(tree);
746 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
749 if (tree_data->interesting_hfids) {
750 /* Free all the GPtrArray's in the interesting_hfids hash. */
751 g_hash_table_foreach(tree_data->interesting_hfids,
752 free_GPtrArray_value, NULL);
754 /* And then remove all values. */
755 g_hash_table_remove_all(tree_data->interesting_hfids);
758 /* Reset track of the number of children */
759 tree_data->count = 0;
761 PROTO_NODE_INIT(tree);
764 /* frees the resources that the dissection a proto_tree uses */
766 proto_tree_free(proto_tree *tree)
768 tree_data_t *tree_data = PTREE_DATA(tree);
770 proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
773 if (tree_data->interesting_hfids) {
774 /* Free all the GPtrArray's in the interesting_hfids hash. */
775 g_hash_table_foreach(tree_data->interesting_hfids,
776 free_GPtrArray_value, NULL);
778 /* And then destroy the hash. */
779 g_hash_table_destroy(tree_data->interesting_hfids);
782 g_slice_free(tree_data_t, tree_data);
784 g_slice_free(proto_tree, tree);
787 /* Is the parsing being done for a visible proto_tree or an invisible one?
788 * By setting this correctly, the proto_tree creation is sped up by not
789 * having to call g_vsnprintf and copy strings around.
792 proto_tree_set_visible(proto_tree *tree, gboolean visible)
794 gboolean old_visible = PTREE_DATA(tree)->visible;
796 PTREE_DATA(tree)->visible = visible;
802 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
804 PTREE_DATA(tree)->fake_protocols = fake_protocols;
807 /* Assume dissector set only its protocol fields.
808 This function is called by dissectors and allows the speeding up of filtering
809 in wireshark; if this function returns FALSE it is safe to reset tree to NULL
810 and thus skip calling most of the expensive proto_tree_add_...()
812 If the tree is visible we implicitly assume the field is referenced.
815 proto_field_is_referenced(proto_tree *tree, int proto_id)
817 register header_field_info *hfinfo;
823 if (PTREE_DATA(tree)->visible)
826 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
827 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
830 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
837 /* Finds a record in the hfinfo array by id. */
839 proto_registrar_get_nth(guint hfindex)
841 register header_field_info *hfinfo;
843 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
848 /* Prefix initialization
849 * this allows for a dissector to register a display filter name prefix
850 * so that it can delay the initialization of the hf array as long as
854 /* compute a hash for the part before the dot of a display filter */
856 prefix_hash (gconstpointer key) {
857 /* end the string at the dot and compute its hash */
858 gchar* copy = g_strdup((const gchar *)key);
869 tmp = g_str_hash(copy);
874 /* are both strings equal up to the end or the dot? */
876 prefix_equal (gconstpointer ap, gconstpointer bp) {
877 const gchar* a = (const gchar *)ap;
878 const gchar* b = (const gchar *)bp;
884 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE;
886 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
887 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
889 if (ac != bc) return FALSE;
895 /* Register a new prefix for "delayed" initialization of field arrays */
897 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
899 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
902 g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
905 /* helper to call all prefix initializers */
907 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
908 ((prefix_initializer_t)v)((const char *)k);
912 /** Initialize every remaining uninitialized prefix. */
914 proto_initialize_all_prefixes(void) {
915 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
918 /* Finds a record in the hfinfo array by name.
919 * If it fails to find it in the already registered fields,
920 * it tries to find and call an initializer in the prefixes
921 * table and if so it looks again.
925 proto_registrar_get_byname(const char *field_name)
927 header_field_info *hfinfo;
928 prefix_initializer_t pi;
933 if (g_strcmp0(field_name, last_field_name) == 0) {
937 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
940 g_free(last_field_name);
941 last_field_name = g_strdup(field_name);
942 last_hfinfo = hfinfo;
949 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
951 g_hash_table_remove(prefixes, field_name);
956 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
959 g_free(last_field_name);
960 last_field_name = g_strdup(field_name);
961 last_hfinfo = hfinfo;
967 proto_registrar_get_id_byname(const char *field_name)
969 header_field_info *hfinfo;
971 hfinfo = proto_registrar_get_byname(field_name);
981 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
983 subtree_lvl *pushed_tree;
985 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
986 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
988 pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
989 DISSECTOR_ASSERT(pushed_tree != NULL);
990 if (ptvc->pushed_tree)
991 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
992 ptvc->pushed_tree = pushed_tree;
996 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
998 ptvc->pushed_tree = NULL;
999 ptvc->pushed_tree_max = 0;
1000 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1001 ptvc->pushed_tree_index = 0;
1004 /* Allocates an initializes a ptvcursor_t with 3 variables:
1005 * proto_tree, tvbuff, and offset. */
1007 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
1011 ptvc = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
1014 ptvc->offset = offset;
1015 ptvc->pushed_tree = NULL;
1016 ptvc->pushed_tree_max = 0;
1017 ptvc->pushed_tree_index = 0;
1022 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1024 ptvcursor_free(ptvcursor_t *ptvc)
1026 ptvcursor_free_subtree_levels(ptvc);
1030 /* Returns tvbuff. */
1032 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1037 /* Returns current offset. */
1039 ptvcursor_current_offset(ptvcursor_t *ptvc)
1041 return ptvc->offset;
1045 ptvcursor_tree(ptvcursor_t *ptvc)
1054 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1059 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1061 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1063 subtree_lvl *subtree;
1064 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1065 ptvcursor_new_subtree_levels(ptvc);
1067 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1068 subtree->tree = ptvc->tree;
1070 ptvc->pushed_tree_index++;
1071 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1074 /* pops a subtree */
1076 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1078 subtree_lvl *subtree;
1080 if (ptvc->pushed_tree_index <= 0)
1083 ptvc->pushed_tree_index--;
1084 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1085 if (subtree->it != NULL)
1086 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1088 ptvc->tree = subtree->tree;
1091 /* saves the current tvb offset and the item in the current subtree level */
1093 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1095 subtree_lvl *subtree;
1097 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1099 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1101 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1104 /* Creates a subtree and adds it to the cursor as the working tree but does not
1105 * save the old working tree */
1107 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1109 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1114 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1116 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1117 if (length == SUBTREE_UNDEFINED_LENGTH)
1118 ptvcursor_subtree_set_item(ptvc, it);
1119 return ptvcursor_tree(ptvc);
1122 /* Add an item to the tree and create a subtree
1123 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1124 * In this case, when the subtree will be closed, the parent item length will
1125 * be equal to the advancement of the cursor since the creation of the subtree.
1128 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1129 const guint encoding, gint ett_subtree)
1133 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1134 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1138 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1140 /* Add a text node to the tree and create a subtree
1141 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1142 * In this case, when the subtree will be closed, the item length will be equal
1143 * to the advancement of the cursor since the creation of the subtree.
1146 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1147 gint ett_subtree, const char *format, ...)
1151 header_field_info *hfinfo;
1154 tree = ptvcursor_tree(ptvc);
1156 CHECK_FOR_NULL_TREE(tree);
1158 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1160 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1161 ptvcursor_current_offset(ptvc), length);
1163 TRY_TO_FAKE_THIS_REPR(pi);
1165 va_start(ap, format);
1166 proto_tree_set_representation(pi, format, ap);
1169 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1172 /* Add a text-only node, leaving it to our caller to fill the text in */
1174 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1181 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1186 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1188 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1189 const char *format, ...)
1193 header_field_info *hfinfo;
1196 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1198 tvb_ensure_bytes_exist(tvb, start, length);
1201 CHECK_FOR_NULL_TREE(tree);
1203 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1205 pi = proto_tree_add_text_node(tree, tvb, start, length);
1207 TRY_TO_FAKE_THIS_REPR(pi);
1209 va_start(ap, format);
1210 proto_tree_set_representation(pi, format, ap);
1216 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1218 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1219 gint length, const char *format, va_list ap)
1222 header_field_info *hfinfo;
1225 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1227 tvb_ensure_bytes_exist(tvb, start, length);
1230 CHECK_FOR_NULL_TREE(tree);
1232 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1234 pi = proto_tree_add_text_node(tree, tvb, start, length);
1236 TRY_TO_FAKE_THIS_REPR(pi);
1238 proto_tree_set_representation(pi, format, ap);
1243 /* Add a text-only node that creates a subtree underneath.
1246 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1248 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1251 /* Add a text-only node that creates a subtree underneath.
1254 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1260 va_start(ap, format);
1261 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1264 if (tree_item != NULL)
1267 pt = proto_item_add_subtree(pi, idx);
1272 /* Add a text-only node for debugging purposes. The caller doesn't need
1273 * to worry about tvbuff, start, or length. Debug message gets sent to
1276 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1281 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1284 va_start(ap, format);
1285 proto_tree_set_representation(pi, format, ap);
1288 va_start(ap, format);
1289 vprintf(format, ap);
1291 ws_debug_printf("\n");
1297 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1300 header_field_info *hfinfo;
1302 CHECK_FOR_NULL_TREE(tree);
1304 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1306 pi = proto_tree_add_text_node(tree, tvb, start, length);
1308 TRY_TO_FAKE_THIS_REPR(pi);
1310 proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1316 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1319 header_field_info *hfinfo;
1322 CHECK_FOR_NULL_TREE(tree);
1324 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1326 pi = proto_tree_add_text_node(tree, tvb, start, length);
1328 TRY_TO_FAKE_THIS_REPR(pi);
1330 str = tvb_format_text_wsp(NULL, tvb, start, length);
1331 proto_item_set_text(pi, "%s", str);
1332 wmem_free(NULL, str);
1337 void proto_report_dissector_bug(const char *message)
1339 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1342 THROW_MESSAGE(DissectorError, message);
1345 /* We could probably get away with changing is_error to a minimum length value. */
1347 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1350 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1352 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1356 THROW(ReportedBoundsError);
1361 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1364 gboolean length_error;
1369 value = tvb_get_guint8(tvb, offset);
1370 if (encoding & ENC_ZIGBEE) {
1371 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1378 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1379 : tvb_get_ntohs(tvb, offset);
1380 if (encoding & ENC_ZIGBEE) {
1381 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1388 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1389 : tvb_get_ntoh24(tvb, offset);
1393 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1394 : tvb_get_ntohl(tvb, offset);
1399 length_error = TRUE;
1402 length_error = FALSE;
1403 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1404 : tvb_get_ntohl(tvb, offset);
1406 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1412 static inline guint64
1413 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1416 gboolean length_error;
1421 value = tvb_get_guint8(tvb, offset);
1425 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1426 : tvb_get_ntohs(tvb, offset);
1430 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1431 : tvb_get_ntoh24(tvb, offset);
1435 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1436 : tvb_get_ntohl(tvb, offset);
1440 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1441 : tvb_get_ntoh40(tvb, offset);
1445 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1446 : tvb_get_ntoh48(tvb, offset);
1450 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1451 : tvb_get_ntoh56(tvb, offset);
1455 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1456 : tvb_get_ntoh64(tvb, offset);
1461 length_error = TRUE;
1464 length_error = FALSE;
1465 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1466 : tvb_get_ntoh64(tvb, offset);
1468 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1475 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1478 gboolean length_error;
1483 value = (gint8)tvb_get_guint8(tvb, offset);
1487 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1488 : tvb_get_ntohs(tvb, offset));
1492 value = encoding ? tvb_get_letoh24(tvb, offset)
1493 : tvb_get_ntoh24(tvb, offset);
1494 if (value & 0x00800000) {
1495 /* Sign bit is set; sign-extend it. */
1496 value |= 0xFF000000;
1501 value = encoding ? tvb_get_letohl(tvb, offset)
1502 : tvb_get_ntohl(tvb, offset);
1507 length_error = TRUE;
1510 length_error = FALSE;
1511 value = encoding ? tvb_get_letohl(tvb, offset)
1512 : tvb_get_ntohl(tvb, offset);
1514 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1520 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1521 * be cast-able as a gint64. This is weird, but what the code has always done.
1523 static inline guint64
1524 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1526 guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1531 value = ws_sign_ext64(value, 56);
1534 value = ws_sign_ext64(value, 48);
1537 value = ws_sign_ext64(value, 40);
1540 value = ws_sign_ext64(value, 32);
1543 value = ws_sign_ext64(value, 24);
1546 value = ws_sign_ext64(value, 16);
1549 value = ws_sign_ext64(value, 8);
1557 static inline const guint8 *
1558 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1559 gint length, gint *ret_length, const guint encoding)
1562 length = tvb_ensure_captured_length_remaining(tvb, start);
1564 *ret_length = length;
1565 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1568 /* For FT_STRINGZ */
1569 static inline const guint8 *
1570 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1571 gint start, gint length, gint *ret_length, const guint encoding)
1573 const guint8 *value;
1576 report_type_length_mismatch(tree, "a string", length, TRUE);
1579 /* This can throw an exception */
1580 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1581 } else if (length == 0) {
1584 /* In this case, length signifies the length of the string.
1586 * This could either be a null-padded string, which doesn't
1587 * necessarily have a '\0' at the end, or a null-terminated
1588 * string, with a trailing '\0'. (Yes, there are cases
1589 * where you have a string that's both counted and null-
1592 * In the first case, we must allocate a buffer of length
1593 * "length+1", to make room for a trailing '\0'.
1595 * In the second case, we don't assume that there is a
1596 * trailing '\0' there, as the packet might be malformed.
1597 * (XXX - should we throw an exception if there's no
1598 * trailing '\0'?) Therefore, we allocate a buffer of
1599 * length "length+1", and put in a trailing '\0', just to
1602 * (XXX - this would change if we made string values counted
1603 * rather than null-terminated.)
1605 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1607 *ret_length = length;
1611 /* For FT_UINT_STRING */
1612 static inline const guint8 *
1613 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1614 tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1615 const guint encoding)
1618 const guint8 *value;
1620 /* I believe it's ok if this is called with a NULL tree */
1621 if (encoding & ENC_ZIGBEE) {
1622 n = get_uint_value(tree, tvb, start, length, encoding);
1624 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1626 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1628 *ret_length = length;
1632 /* For FT_STRINGZPAD */
1633 static inline const guint8 *
1634 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1635 gint length, gint *ret_length, const guint encoding)
1638 * XXX - currently, string values are null-
1639 * terminated, so a "zero-padded" string
1640 * isn't special. If we represent string
1641 * values as something that includes a counted
1642 * array of bytes, we'll need to strip
1646 length = tvb_ensure_captured_length_remaining(tvb, start);
1648 *ret_length = length;
1649 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1653 * Epochs for various non-UN*X time stamp formats.
1655 #define NTP_BASETIME G_GUINT64_CONSTANT(2208988800) /* NTP */
1656 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800) /* System/3x0 and z/Architecture TOD clock */
1658 /* this can be called when there is no tree, so tree may be null */
1660 get_time_value(proto_tree *tree, tvbuff_t *tvb, const gint start,
1661 const gint length, const guint encoding, nstime_t *time_stamp,
1662 const gboolean is_relative)
1669 case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1671 * 4-byte seconds, followed by 4-byte fractional
1672 * time in nanoseconds, both big-endian.
1673 * For absolute times, the seconds are seconds
1674 * since the UN*X epoch.
1676 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1678 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1679 else if (length == 4) {
1681 * Backwards compatibility.
1683 time_stamp->nsecs = 0;
1685 report_type_length_mismatch(tree, "a timespec", length, TRUE);
1688 case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1690 * 4-byte UNIX epoch, possibly followed by
1691 * 4-byte fractional time in nanoseconds,
1692 * both little-endian.
1693 * For absolute times, the seconds are seconds
1694 * since the UN*X epoch.
1696 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1698 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1699 else if (length == 4) {
1701 * Backwards compatibility.
1703 time_stamp->nsecs = 0;
1705 report_type_length_mismatch(tree, "a timespec", length, TRUE);
1708 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1710 * NTP time stamp, big-endian.
1711 * Only supported for absolute times.
1713 DISSECTOR_ASSERT(!is_relative);
1715 /* We need a temporary variable here so the unsigned math
1716 * works correctly (for years > 2036 according to RFC 2030
1719 tmpsecs = tvb_get_ntohl(tvb, start);
1721 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1723 time_stamp->secs = tmpsecs; /* 0 */
1727 * Convert 1/2^32s of a second to nanoseconds.
1729 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1730 } else if (length == 4) {
1732 * Backwards compatibility.
1734 time_stamp->nsecs = 0;
1736 report_type_length_mismatch(tree, "an NTP time stamp", length, TRUE);
1739 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1741 * NTP time stamp, little-endian.
1742 * Only supported for absolute times.
1744 DISSECTOR_ASSERT(!is_relative);
1746 tmpsecs = tvb_get_letohl(tvb, start);
1748 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1750 time_stamp->secs = tmpsecs; /* 0 */
1754 * Convert 1/2^32s of a second to nanoseconds.
1756 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1757 } else if (length == 4) {
1759 * Backwards compatibility.
1761 time_stamp->nsecs = 0;
1763 report_type_length_mismatch(tree, "an NTP time stamp", length, TRUE);
1766 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1768 * S/3x0 and z/Architecture TOD clock time stamp,
1770 * Only supported for absolute times.
1772 DISSECTOR_ASSERT(!is_relative);
1773 DISSECTOR_ASSERT(length == 8);
1776 todsecs = tvb_get_ntoh64(tvb, start) >> 12;
1777 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1778 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1780 report_type_length_mismatch(tree, "a TOD clock time stamp", length, TRUE);
1783 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1785 * S/3x0 and z/Architecture TOD clock time stamp,
1787 * Only supported for absolute times.
1789 DISSECTOR_ASSERT(!is_relative);
1792 todsecs = tvb_get_letoh64(tvb, start) >> 12 ;
1793 time_stamp->secs = (time_t)((todsecs / 1000000) - TOD_BASETIME);
1794 time_stamp->nsecs = (int)((todsecs % 1000000) * 1000);
1796 report_type_length_mismatch(tree, "a TOD clock time stamp", length, TRUE);
1799 case ENC_TIME_RTPS|ENC_BIG_ENDIAN:
1801 * Time stamp using the same seconds/fraction format
1802 * as NTP, but with the origin of the time stamp being
1803 * the UNIX epoch rather than the NTP epoch; big-
1806 * Only supported for absolute times.
1808 DISSECTOR_ASSERT(!is_relative);
1811 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1813 * Convert 1/2^32s of a second to nanoseconds.
1815 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1817 report_type_length_mismatch(tree, "an RTPS time stamp", length, TRUE);
1820 case ENC_TIME_RTPS|ENC_LITTLE_ENDIAN:
1822 * Time stamp using the same seconds/fraction format
1823 * as NTP, but with the origin of the time stamp being
1824 * the UNIX epoch rather than the NTP epoch; little-
1827 * Only supported for absolute times.
1829 DISSECTOR_ASSERT(!is_relative);
1832 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1834 * Convert 1/2^32s of a second to nanoseconds.
1836 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1838 report_type_length_mismatch(tree, "an RTPS time stamp", length, TRUE);
1841 case ENC_TIME_TIMEVAL|ENC_BIG_ENDIAN:
1843 * 4-byte seconds, followed by 4-byte fractional
1844 * time in microseconds, both big-endian.
1845 * For absolute times, the seconds are seconds
1846 * since the UN*X epoch.
1849 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1850 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
1852 report_type_length_mismatch(tree, "a timeval", length, TRUE);
1855 case ENC_TIME_TIMEVAL|ENC_LITTLE_ENDIAN:
1857 * 4-byte seconds, followed by 4-byte fractional
1858 * time in microseconds, both little-endian.
1859 * For absolute times, the seconds are seconds
1860 * since the UN*X epoch.
1863 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1864 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
1866 report_type_length_mismatch(tree, "a timeval", length, TRUE);
1869 case ENC_TIME_SECS|ENC_BIG_ENDIAN:
1870 case ENC_TIME_SECS|ENC_LITTLE_ENDIAN:
1872 * Seconds, 1 to 8 bytes.
1873 * For absolute times, it's seconds since the
1876 if (length >= 1 && length <= 8) {
1877 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
1878 time_stamp->nsecs = 0;
1880 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, TRUE);
1883 case ENC_TIME_MSECS|ENC_BIG_ENDIAN:
1885 * Milliseconds, 1 to 8 bytes.
1886 * For absolute times, it's milliseconds since the
1889 if (length >= 1 && length <= 8) {
1892 msecs = get_uint64_value(tree, tvb, start, length, encoding);
1893 time_stamp->secs = (time_t)(msecs / 1000);
1894 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
1896 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, TRUE);
1899 case ENC_TIME_RFC_3971|ENC_BIG_ENDIAN:
1901 * 1/64ths of a second since the UN*X epoch,
1904 * Only supported for absolute times.
1906 DISSECTOR_ASSERT(!is_relative);
1910 * The upper 48 bits are seconds since the
1913 time_stamp->secs = tvb_get_ntoh48(tvb, start);
1915 * The lower 16 bits are 1/2^16s of a second;
1916 * convert them to nanoseconds.
1918 * XXX - this may give the impression of higher
1919 * precision than you actually get.
1921 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
1923 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, TRUE);
1926 case ENC_TIME_RFC_3971|ENC_LITTLE_ENDIAN:
1928 * 1/64ths of a second since the UN*X epoch,
1931 * Only supported for absolute times.
1933 DISSECTOR_ASSERT(!is_relative);
1937 * XXX - this is assuming that, if anybody
1938 * were ever to use this format - RFC 3971
1939 * doesn't, because that's an Internet
1940 * protocol, and those use network byte
1941 * order, i.e. big-endian - they'd treat it
1942 * as a 64-bit count of 1/2^16s of a second,
1943 * putting the upper 48 bits at the end.
1945 * The lower 48 bits are seconds since the
1948 time_stamp->secs = tvb_get_letoh48(tvb, start+2);
1950 * The upper 16 bits are 1/2^16s of a second;
1951 * convert them to nanoseconds.
1953 * XXX - this may give the impression of higher
1954 * precision than you actually get.
1956 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
1958 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, TRUE);
1961 case ENC_TIME_SECS_NTP|ENC_BIG_ENDIAN:
1963 * NTP time stamp, with 1-second resolution (i.e.,
1964 * seconds since the NTP epoch), big-endian.
1965 * Only supported for absolute times.
1967 DISSECTOR_ASSERT(!is_relative);
1971 * We need a temporary variable here so the
1972 * unsigned math works correctly (for
1973 * years > 2036 according to RFC 2030
1976 tmpsecs = tvb_get_ntohl(tvb, start);
1978 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1980 time_stamp->secs = tmpsecs; /* 0 */
1981 time_stamp->nsecs = 0;
1983 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, TRUE);
1986 case ENC_TIME_SECS_NTP|ENC_LITTLE_ENDIAN:
1988 * NTP time stamp, with 1-second resolution (i.e.,
1989 * seconds since the NTP epoch), little-endian.
1990 * Only supported for absolute times.
1992 DISSECTOR_ASSERT(!is_relative);
1995 tmpsecs = tvb_get_letohl(tvb, start);
1997 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1999 time_stamp->secs = tmpsecs; /* 0 */
2000 time_stamp->nsecs = 0;
2002 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, TRUE);
2004 case ENC_TIME_MSEC_NTP | ENC_BIG_ENDIAN:
2006 * Milliseconds, 1 to 8 bytes.
2007 * For absolute times, it's milliseconds since the
2010 if (length >= 1 && length <= 8) {
2013 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2014 tmpsecs = (guint32)(msecs / 1000);
2015 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
2016 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2019 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, TRUE);
2022 DISSECTOR_ASSERT_NOT_REACHED();
2028 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2030 const header_field_info *hfinfo = fi->hfinfo;
2032 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
2033 GPtrArray *ptrs = NULL;
2035 if (tree_data->interesting_hfids == NULL) {
2036 /* Initialize the hash because we now know that it is needed */
2037 tree_data->interesting_hfids =
2038 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
2039 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2040 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2041 GINT_TO_POINTER(hfinfo->id));
2045 /* First element triggers the creation of pointer array */
2046 ptrs = g_ptr_array_new();
2047 g_hash_table_insert(tree_data->interesting_hfids,
2048 GINT_TO_POINTER(hfinfo->id), ptrs);
2051 g_ptr_array_add(ptrs, fi);
2057 * Validates that field length bytes are available starting from
2058 * start (pos/neg). Throws an exception if they aren't.
2061 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2062 gint start, gint length, const guint encoding)
2069 if ((hfinfo->type == FT_STRINGZ) ||
2070 ((encoding & ENC_VARINT_PROTOBUF) && (IS_FT_UINT(hfinfo->type) || IS_FT_UINT(hfinfo->type)))) {
2071 /* If we're fetching until the end of the TVB, only validate
2072 * that the offset is within range.
2078 tvb_ensure_bytes_exist(tvb, start, size);
2081 /* Add an item to a proto_tree, using the text label registered to that item;
2082 the item is extracted from the tvbuff handed to it. */
2084 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2085 tvbuff_t *tvb, gint start, gint length,
2093 const char *stringval;
2094 nstime_t time_stamp;
2095 gboolean length_error;
2097 switch (new_fi->hfinfo->type) {
2099 /* no value to set for FT_NONE */
2103 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
2107 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2111 n = get_uint_value(tree, tvb, start, length, encoding);
2112 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2114 /* Instead of calling proto_item_set_len(), since we don't yet
2115 * have a proto_item, we set the field_info's length ourselves. */
2116 new_fi->length = n + length;
2121 * Map all non-zero values to little-endian for
2122 * backwards compatibility.
2125 encoding = ENC_LITTLE_ENDIAN;
2126 proto_tree_set_boolean(new_fi,
2127 get_uint64_value(tree, tvb, start, length, encoding));
2131 /* XXX - make these just FT_UINT? */
2136 if (encoding & ENC_VARINT_PROTOBUF) {
2137 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64);
2138 new_fi->flags |= FI_VARINT;
2139 value = (guint32)value64;
2142 * Map all non-zero values to little-endian for
2143 * backwards compatibility.
2146 encoding = ENC_LITTLE_ENDIAN;
2148 value = get_uint_value(tree, tvb, start, length, encoding);
2150 proto_tree_set_uint(new_fi, value);
2158 if (encoding & ENC_VARINT_PROTOBUF) {
2159 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64);
2160 new_fi->flags |= FI_VARINT;
2163 * Map all other non-zero values to little-endian for
2164 * backwards compatibility.
2167 encoding = ENC_LITTLE_ENDIAN;
2169 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2171 proto_tree_set_uint64(new_fi, value64);
2174 /* XXX - make these just FT_INT? */
2180 * Map all non-zero values to little-endian for
2181 * backwards compatibility.
2184 encoding = ENC_LITTLE_ENDIAN;
2185 proto_tree_set_int(new_fi,
2186 get_int_value(tree, tvb, start, length, encoding));
2194 * Map all non-zero values to little-endian for
2195 * backwards compatibility.
2198 encoding = ENC_LITTLE_ENDIAN;
2199 proto_tree_set_int64(new_fi,
2200 get_int64_value(tree, tvb, start, length, encoding));
2205 * Map all non-zero values to little-endian for
2206 * backwards compatibility.
2209 encoding = ENC_LITTLE_ENDIAN;
2210 if (length != FT_IPv4_LEN) {
2211 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
2212 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2214 value = tvb_get_ipv4(tvb, start);
2216 * NOTE: to support code written when
2217 * proto_tree_add_item() took a gboolean as its
2218 * last argument, with FALSE meaning "big-endian"
2219 * and TRUE meaning "little-endian", we treat any
2220 * non-zero value of "encoding" as meaning
2223 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
2227 if (length != FT_IPXNET_LEN) {
2228 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
2229 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2231 proto_tree_set_ipxnet(new_fi,
2232 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
2236 if (length != FT_IPv6_LEN) {
2237 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
2238 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2240 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2244 if (length != FT_FCWWN_LEN) {
2245 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2246 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2248 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2253 length_error = length < 7 ? TRUE : FALSE;
2254 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2256 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2260 if (length != VINES_ADDR_LEN) {
2261 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2262 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2264 proto_tree_set_vines_tvb(new_fi, tvb, start);
2268 if (length != FT_ETHER_LEN) {
2269 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2270 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2272 proto_tree_set_ether_tvb(new_fi, tvb, start);
2277 * Map all non-zero values to little-endian for
2278 * backwards compatibility.
2281 encoding = ENC_LITTLE_ENDIAN;
2282 if (length != FT_EUI64_LEN) {
2283 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2284 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2286 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2290 * Map all non-zero values to little-endian for
2291 * backwards compatibility.
2294 encoding = ENC_LITTLE_ENDIAN;
2295 if (length != FT_GUID_LEN) {
2296 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2297 report_type_length_mismatch(tree, "a GUID", length, length_error);
2299 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2304 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2308 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2313 * NOTE: to support code written when
2314 * proto_tree_add_item() took a gboolean as its
2315 * last argument, with FALSE meaning "big-endian"
2316 * and TRUE meaning "little-endian", we treat any
2317 * non-zero value of "encoding" as meaning
2320 * At some point in the future, we might
2321 * support non-IEEE-binary floating-point
2322 * formats in the encoding as well
2323 * (IEEE decimal, System/3x0, VAX).
2326 encoding = ENC_LITTLE_ENDIAN;
2328 length_error = length < 4 ? TRUE : FALSE;
2329 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2332 floatval = tvb_get_letohieee_float(tvb, start);
2334 floatval = tvb_get_ntohieee_float(tvb, start);
2335 proto_tree_set_float(new_fi, floatval);
2340 * NOTE: to support code written when
2341 * proto_tree_add_item() took a gboolean as its
2342 * last argument, with FALSE meaning "big-endian"
2343 * and TRUE meaning "little-endian", we treat any
2344 * non-zero value of "encoding" as meaning
2347 * At some point in the future, we might
2348 * support non-IEEE-binary floating-point
2349 * formats in the encoding as well
2350 * (IEEE decimal, System/3x0, VAX).
2352 if (encoding == TRUE)
2353 encoding = ENC_LITTLE_ENDIAN;
2355 length_error = length < 8 ? TRUE : FALSE;
2356 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2359 doubleval = tvb_get_letohieee_double(tvb, start);
2361 doubleval = tvb_get_ntohieee_double(tvb, start);
2362 proto_tree_set_double(new_fi, doubleval);
2366 stringval = get_string_value(wmem_packet_scope(),
2367 tvb, start, length, &length, encoding);
2368 proto_tree_set_string(new_fi, stringval);
2370 /* Instead of calling proto_item_set_len(), since we
2371 * don't yet have a proto_item, we set the
2372 * field_info's length ourselves.
2374 * XXX - our caller can't use that length to
2375 * advance an offset unless they arrange that
2376 * there always be a protocol tree into which
2377 * we're putting this item.
2379 new_fi->length = length;
2383 stringval = get_stringz_value(wmem_packet_scope(),
2384 tree, tvb, start, length, &length, encoding);
2385 proto_tree_set_string(new_fi, stringval);
2387 /* Instead of calling proto_item_set_len(),
2388 * since we don't yet have a proto_item, we
2389 * set the field_info's length ourselves.
2391 * XXX - our caller can't use that length to
2392 * advance an offset unless they arrange that
2393 * there always be a protocol tree into which
2394 * we're putting this item.
2396 new_fi->length = length;
2399 case FT_UINT_STRING:
2401 * NOTE: to support code written when
2402 * proto_tree_add_item() took a gboolean as its
2403 * last argument, with FALSE meaning "big-endian"
2404 * and TRUE meaning "little-endian", if the
2405 * encoding value is TRUE, treat that as
2406 * ASCII with a little-endian length.
2408 * This won't work for code that passes
2409 * arbitrary non-zero values; that code
2410 * will need to be fixed.
2412 if (encoding == TRUE)
2413 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2414 stringval = get_uint_string_value(wmem_packet_scope(),
2415 tree, tvb, start, length, &length, encoding);
2416 proto_tree_set_string(new_fi, stringval);
2418 /* Instead of calling proto_item_set_len(), since we
2419 * don't yet have a proto_item, we set the
2420 * field_info's length ourselves.
2422 * XXX - our caller can't use that length to
2423 * advance an offset unless they arrange that
2424 * there always be a protocol tree into which
2425 * we're putting this item.
2427 new_fi->length = length;
2431 stringval = get_stringzpad_value(wmem_packet_scope(),
2432 tvb, start, length, &length, encoding);
2433 proto_tree_set_string(new_fi, stringval);
2435 /* Instead of calling proto_item_set_len(), since we
2436 * don't yet have a proto_item, we set the
2437 * field_info's length ourselves.
2439 * XXX - our caller can't use that length to
2440 * advance an offset unless they arrange that
2441 * there always be a protocol tree into which
2442 * we're putting this item.
2444 new_fi->length = length;
2447 case FT_ABSOLUTE_TIME:
2449 * Absolute times can be in any of a number of
2450 * formats, and they can be big-endian or
2453 * Historically FT_TIMEs were only timespecs;
2454 * the only question was whether they were stored
2455 * in big- or little-endian format.
2457 * For backwards compatibility, we interpret an
2458 * encoding of 1 as meaning "little-endian timespec",
2459 * so that passing TRUE is interpreted as that.
2461 if (encoding == TRUE)
2462 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2464 if (length > 8 || length < 4) {
2465 length_error = length < 4 ? TRUE : FALSE;
2466 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2469 get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
2471 proto_tree_set_time(new_fi, &time_stamp);
2474 case FT_RELATIVE_TIME:
2476 * Relative times can be in any of a number of
2477 * formats, and they can be big-endian or
2480 * Historically FT_TIMEs were only timespecs;
2481 * the only question was whether they were stored
2482 * in big- or little-endian format.
2484 * For backwards compatibility, we interpret an
2485 * encoding of 1 as meaning "little-endian timespec",
2486 * so that passing TRUE is interpreted as that.
2488 if (encoding == TRUE)
2489 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2491 if (length != 8 && length != 4) {
2492 length_error = length < 4 ? TRUE : FALSE;
2493 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2496 get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
2498 proto_tree_set_time(new_fi, &time_stamp);
2500 case FT_IEEE_11073_SFLOAT:
2502 encoding = ENC_LITTLE_ENDIAN;
2504 length_error = length < 2 ? TRUE : FALSE;
2505 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2508 fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2511 case FT_IEEE_11073_FLOAT:
2513 encoding = ENC_LITTLE_ENDIAN;
2515 length_error = length < 4 ? TRUE : FALSE;
2516 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2521 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2522 new_fi->hfinfo->type,
2523 ftype_name(new_fi->hfinfo->type));
2524 DISSECTOR_ASSERT_NOT_REACHED();
2527 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2529 /* Don't add new node to proto_tree until now so that any exceptions
2530 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2531 /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2532 * to know which item caused exception? */
2533 pi = proto_tree_add_node(tree, new_fi);
2539 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2540 const gint start, gint length,
2541 const guint encoding, gint32 *retval)
2543 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2547 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2549 switch (hfinfo->type){
2556 DISSECTOR_ASSERT_NOT_REACHED();
2559 /* length validation for native number encoding caught by get_uint_value() */
2560 /* length has to be -1 or > 0 regardless of encoding */
2561 if (length < -1 || length == 0)
2562 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2563 "Invalid length %d passed to proto_tree_add_item_ret_int",
2566 if (encoding & ENC_STRING) {
2567 REPORT_DISSECTOR_BUG("wrong encoding");
2569 /* I believe it's ok if this is called with a NULL tree */
2570 value = get_int_value(tree, tvb, start, length, encoding);
2575 if (hfinfo->bitmask) {
2576 /* Mask out irrelevant portions */
2577 *retval &= (guint32)(hfinfo->bitmask);
2579 *retval >>= hfinfo_bitshift(hfinfo);
2581 no_of_bits = ws_count_ones(hfinfo->bitmask);
2582 *retval = ws_sign_ext32(*retval, no_of_bits);
2585 CHECK_FOR_NULL_TREE(tree);
2587 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2589 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2591 proto_tree_set_int(new_fi, value);
2593 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2595 return proto_tree_add_node(tree, new_fi);
2599 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2600 const gint start, gint length,
2601 const guint encoding, guint32 *retval)
2603 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2607 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2609 switch (hfinfo->type){
2617 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2618 "field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2622 /* length validation for native number encoding caught by get_uint_value() */
2623 /* length has to be -1 or > 0 regardless of encoding */
2624 if (length < -1 || length == 0)
2625 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2626 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2629 if (encoding & ENC_STRING) {
2630 REPORT_DISSECTOR_BUG("wrong encoding");
2632 /* I believe it's ok if this is called with a NULL tree */
2633 /* XXX - modify if we ever support EBCDIC FT_CHAR */
2634 if (encoding & ENC_VARINT_PROTOBUF) {
2636 tvb_get_varint(tvb, start, length, &temp64);
2637 value = (guint32)temp64;
2639 value = get_uint_value(tree, tvb, start, length, encoding);
2644 if (hfinfo->bitmask) {
2645 /* Mask out irrelevant portions */
2646 *retval &= (guint32)(hfinfo->bitmask);
2648 *retval >>= hfinfo_bitshift(hfinfo);
2652 CHECK_FOR_NULL_TREE(tree);
2654 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2656 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2658 proto_tree_set_uint(new_fi, value);
2660 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2661 if (encoding & ENC_VARINT_PROTOBUF) {
2662 new_fi->flags |= FI_VARINT;
2664 return proto_tree_add_node(tree, new_fi);
2667 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2668 * and returns proto_item* and uint value retreived*/
2670 ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, gint length,
2671 const guint encoding, guint32 *retval)
2674 header_field_info *hfinfo;
2679 offset = ptvc->offset;
2680 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2682 switch (hfinfo->type){
2690 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2691 "field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2695 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
2696 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
2698 /* I believe it's ok if this is called with a NULL tree */
2699 /* XXX - modify if we ever support EBCDIC FT_CHAR */
2700 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
2704 if (hfinfo->bitmask) {
2705 /* Mask out irrelevant portions */
2706 *retval &= (guint32)(hfinfo->bitmask);
2708 *retval >>= hfinfo_bitshift(hfinfo);
2712 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2713 item_length, encoding);
2715 CHECK_FOR_NULL_TREE(ptvc->tree);
2717 /* Coast clear. Try and fake it */
2718 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2720 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2722 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2723 offset, length, encoding);
2726 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2727 * and returns proto_item* and int value retreived*/
2729 ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, gint length,
2730 const guint encoding, gint32 *retval)
2733 header_field_info *hfinfo;
2738 offset = ptvc->offset;
2739 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2741 switch (hfinfo->type){
2748 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2749 "field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2753 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
2754 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
2756 /* I believe it's ok if this is called with a NULL tree */
2757 /* XXX - modify if we ever support EBCDIC FT_CHAR */
2758 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
2763 if (hfinfo->bitmask) {
2764 /* Mask out irrelevant portions */
2765 *retval &= (guint32)(hfinfo->bitmask);
2767 *retval >>= hfinfo_bitshift(hfinfo);
2769 no_of_bits = ws_count_ones(hfinfo->bitmask);
2770 *retval = ws_sign_ext32(*retval, no_of_bits);
2773 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2774 item_length, encoding);
2776 CHECK_FOR_NULL_TREE(ptvc->tree);
2778 /* Coast clear. Try and fake it */
2779 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2781 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2783 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2784 offset, length, encoding);
2787 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2788 * and returns proto_item* and string value retreived */
2790 ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, wmem_allocator_t *scope, const guint8 **retval)
2792 header_field_info *hfinfo;
2794 const guint8 *value;
2798 offset = ptvc->offset;
2800 PROTO_REGISTRAR_GET_NTH(hf, hfinfo);
2802 switch (hfinfo->type){
2804 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
2807 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
2809 case FT_UINT_STRING:
2810 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
2813 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
2816 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2817 "field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, or FT_STRINGZPAD",
2824 ptvc->offset += item_length;
2826 CHECK_FOR_NULL_TREE(ptvc->tree);
2828 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
2830 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2832 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2833 offset, length, encoding);
2836 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2837 * and returns proto_item* and boolean value retreived */
2839 ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, gint length, const guint encoding, gboolean *retval)
2841 header_field_info *hfinfo;
2845 guint64 value, bitval;
2847 offset = ptvc->offset;
2848 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2850 if (hfinfo->type != FT_BOOLEAN) {
2851 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2852 "field %s is not of type FT_BOOLEAN", hfinfo->abbrev));
2855 /* length validation for native number encoding caught by get_uint64_value() */
2856 /* length has to be -1 or > 0 regardless of encoding */
2857 if (length < -1 || length == 0)
2858 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2859 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2862 if (encoding & ENC_STRING) {
2863 REPORT_DISSECTOR_BUG("wrong encoding");
2866 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
2867 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
2869 /* I believe it's ok if this is called with a NULL tree */
2870 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
2874 if (hfinfo->bitmask) {
2875 /* Mask out irrelevant portions */
2876 bitval &= hfinfo->bitmask;
2878 *retval = (bitval != 0);
2881 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2882 item_length, encoding);
2884 CHECK_FOR_NULL_TREE(ptvc->tree);
2886 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
2888 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2890 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2891 offset, length, encoding);
2895 proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2896 const gint start, gint length, const guint encoding, guint64 *retval)
2898 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2902 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2904 if (hfinfo->type != FT_UINT64) {
2905 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2906 "field %s is not of type FT_UINT64", hfinfo->abbrev));
2909 /* length validation for native number encoding caught by get_uint64_value() */
2910 /* length has to be -1 or > 0 regardless of encoding */
2911 if (length < -1 || length == 0)
2912 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2913 "Invalid length %d passed to proto_tree_add_item_ret_uint",
2916 if (encoding & ENC_STRING) {
2917 REPORT_DISSECTOR_BUG("wrong encoding");
2919 /* I believe it's ok if this is called with a NULL tree */
2920 if (encoding & ENC_VARINT_PROTOBUF) {
2921 tvb_get_varint(tvb, start, length, &value);
2923 value = get_uint64_value(tree, tvb, start, length, encoding);
2928 if (hfinfo->bitmask) {
2929 /* Mask out irrelevant portions */
2930 *retval &= hfinfo->bitmask;
2932 *retval >>= hfinfo_bitshift(hfinfo);
2936 CHECK_FOR_NULL_TREE(tree);
2938 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2940 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2942 proto_tree_set_uint64(new_fi, value);
2944 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2945 if (encoding & ENC_VARINT_PROTOBUF) {
2946 new_fi->flags |= FI_VARINT;
2949 return proto_tree_add_node(tree, new_fi);
2953 proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2954 const gint start, gint length, const guint encoding, guint64 *retval, gint *lenretval)
2956 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2960 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2962 if ((!IS_FT_INT(hfinfo->type)) && (!IS_FT_UINT(hfinfo->type))) {
2963 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2964 "field %s is not of type FT_UINT or FT_INT", hfinfo->abbrev));
2967 /* length validation for native number encoding caught by get_uint64_value() */
2968 /* length has to be -1 or > 0 regardless of encoding */
2970 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2971 "Invalid length %d passed to proto_tree_add_item_ret_varint",
2974 if (encoding & ENC_STRING) {
2975 REPORT_DISSECTOR_BUG("wrong encoding");
2978 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value);
2982 if (hfinfo->bitmask) {
2983 /* Mask out irrelevant portions */
2984 *retval &= hfinfo->bitmask;
2986 *retval >>= hfinfo_bitshift(hfinfo);
2991 *lenretval = length;
2994 CHECK_FOR_NULL_TREE(tree);
2996 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2998 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3000 proto_tree_set_uint64(new_fi, value);
3002 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3003 if (encoding & ENC_VARINT_PROTOBUF) {
3004 new_fi->flags |= FI_VARINT;
3007 return proto_tree_add_node(tree, new_fi);
3012 proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3013 const gint start, gint length,
3014 const guint encoding, gboolean *retval)
3016 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3018 guint64 value, bitval;
3020 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3022 if (hfinfo->type != FT_BOOLEAN) {
3023 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
3024 "field %s is not of type FT_BOOLEAN", hfinfo->abbrev));
3027 /* length validation for native number encoding caught by get_uint64_value() */
3028 /* length has to be -1 or > 0 regardless of encoding */
3029 if (length < -1 || length == 0)
3030 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
3031 "Invalid length %d passed to proto_tree_add_item_ret_uint",
3034 if (encoding & ENC_STRING) {
3035 REPORT_DISSECTOR_BUG("wrong encoding");
3037 /* I believe it's ok if this is called with a NULL tree */
3038 value = get_uint64_value(tree, tvb, start, length, encoding);
3042 if (hfinfo->bitmask) {
3043 /* Mask out irrelevant portions */
3044 bitval &= hfinfo->bitmask;
3046 *retval = (bitval != 0);
3049 CHECK_FOR_NULL_TREE(tree);
3051 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3053 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3055 proto_tree_set_boolean(new_fi, value);
3057 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3059 return proto_tree_add_node(tree, new_fi);
3063 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
3065 const gint start, gint length,
3066 const guint encoding,
3067 wmem_allocator_t *scope,
3068 const guint8 **retval,
3071 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3073 const guint8 *value;
3075 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3077 switch (hfinfo->type){
3079 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
3082 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
3084 case FT_UINT_STRING:
3085 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
3088 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
3091 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
3092 "field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, or FT_STRINGZPAD",
3099 CHECK_FOR_NULL_TREE(tree);
3101 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3103 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
3105 proto_tree_set_string(new_fi, value);
3107 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3109 return proto_tree_add_node(tree, new_fi);
3113 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3114 const gint start, gint length,
3115 const guint encoding, wmem_allocator_t *scope,
3116 const guint8 **retval)
3118 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
3119 tvb, start, length, encoding, scope, retval, &length);
3123 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3124 and returns proto_item* */
3126 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
3127 const guint encoding)
3130 header_field_info *hfinfo;
3134 offset = ptvc->offset;
3135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3136 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3137 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3139 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3140 item_length, encoding);
3142 CHECK_FOR_NULL_TREE(ptvc->tree);
3144 /* Coast clear. Try and fake it */
3145 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3147 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3149 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3150 offset, length, encoding);
3153 /* Add an item to a proto_tree, using the text label registered to that item;
3154 the item is extracted from the tvbuff handed to it. */
3156 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
3157 const gint start, gint length, const guint encoding)
3162 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3164 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3165 test_length(hfinfo, tvb, start, item_length, encoding);
3167 CHECK_FOR_NULL_TREE(tree);
3169 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3171 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3173 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3177 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3178 const gint start, gint length, const guint encoding)
3180 register header_field_info *hfinfo;
3182 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3183 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
3186 /* Add an item to a proto_tree, using the text label registered to that item;
3187 the item is extracted from the tvbuff handed to it.
3189 Return the length of the item through the pointer. */
3191 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
3192 tvbuff_t *tvb, const gint start,
3193 gint length, const guint encoding,
3200 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3202 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3203 test_length(hfinfo, tvb, start, item_length, encoding);
3207 * We need to get the correct item length here.
3208 * That's normally done by proto_tree_new_item(),
3209 * but we won't be calling it.
3211 *lenretval = get_full_length(hfinfo, tvb, start, length,
3212 item_length, encoding);
3216 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
3218 * Even if the tree item is not referenced (and thus faked),
3219 * the caller must still be informed of the actual length.
3221 *lenretval = get_full_length(hfinfo, tvb, start, length,
3222 item_length, encoding);
3225 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3227 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3228 *lenretval = new_fi->length;
3233 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3234 const gint start, gint length,
3235 const guint encoding, gint *lenretval)
3237 register header_field_info *hfinfo;
3239 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3240 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
3243 /* which FT_ types can use proto_tree_add_bytes_item() */
3244 static inline gboolean
3245 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
3247 return (type == FT_BYTES ||
3248 type == FT_UINT_BYTES ||
3250 type == FT_REL_OID ||
3251 type == FT_SYSTEM_ID );
3254 /* Note: this does no validation that the byte array of an FT_OID or
3255 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
3256 so I think it's ok to continue not validating it?
3259 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3260 const gint start, gint length, const guint encoding,
3261 GByteArray *retval, gint *endoff, gint *err)
3264 GByteArray *bytes = retval;
3265 GByteArray *created_bytes = NULL;
3268 header_field_info *hfinfo;
3269 gboolean generate = (bytes || tree) ? TRUE : FALSE;
3271 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3273 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3275 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
3276 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
3278 /* length has to be -1 or > 0 regardless of encoding */
3279 /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
3280 if (length < -1 || length == 0) {
3281 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
3282 "Invalid length %d passed to proto_tree_add_bytes_item for %s",
3283 length, ftype_name(hfinfo->type)));
3286 if (encoding & ENC_STR_NUM) {
3287 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
3290 if (generate && (encoding & ENC_STR_HEX)) {
3291 if (hfinfo->type == FT_UINT_BYTES) {
3292 /* can't decode FT_UINT_BYTES from strings */
3293 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
3294 "FT_UINT_BYTES type, but as ENC_STR_HEX");
3298 /* caller doesn't care about return value, but we need it to
3299 call tvb_get_string_bytes() and set the tree later */
3300 bytes = created_bytes = g_byte_array_new();
3303 /* bytes might be NULL after this, but can't add expert error until later */
3304 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
3306 /* grab the errno now before it gets overwritten */
3309 else if (generate) {
3310 tvb_ensure_bytes_exist(tvb, start, length);
3313 /* caller doesn't care about return value, but we need it to
3314 call tvb_get_string_bytes() and set the tree later */
3315 bytes = created_bytes = g_byte_array_new();
3318 if (hfinfo->type == FT_UINT_BYTES) {
3319 n = length; /* n is now the "header" length */
3320 length = get_uint_value(tree, tvb, start, n, encoding);
3321 /* length is now the value's length; only store the value in the array */
3322 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
3324 else if (length > 0) {
3325 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
3329 *endoff = start + n + length;
3332 if (err) *err = saved_err;
3334 CHECK_FOR_NULL_TREE_AND_FREE(tree,
3337 g_byte_array_free(created_bytes, TRUE);
3338 created_bytes = NULL;
3342 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
3345 g_byte_array_free(created_bytes, TRUE);
3346 created_bytes = NULL;
3350 /* n will be zero except when it's a FT_UINT_BYTES */
3351 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
3353 if (encoding & ENC_STRING) {
3354 if (saved_err == ERANGE)
3355 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
3356 else if (!bytes || saved_err != 0)
3357 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
3360 proto_tree_set_bytes_gbytearray(new_fi, bytes);
3362 proto_tree_set_bytes(new_fi, NULL, 0);
3365 g_byte_array_free(created_bytes, TRUE);
3368 /* n will be zero except when it's a FT_UINT_BYTES */
3369 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
3372 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3375 return proto_tree_add_node(tree, new_fi);
3380 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3381 const gint start, gint length, const guint encoding,
3382 nstime_t *retval, gint *endoff, gint *err)
3385 nstime_t time_stamp;
3387 header_field_info *hfinfo;
3389 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3391 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3393 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3395 /* length has to be -1 or > 0 regardless of encoding */
3396 if (length < -1 || length == 0) {
3397 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
3398 "Invalid length %d passed to proto_tree_add_time_item", length));
3401 time_stamp.secs = 0;
3402 time_stamp.nsecs = 0;
3404 if (encoding & ENC_STR_TIME_MASK) {
3405 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
3406 /* grab the errno now before it gets overwritten */
3410 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
3411 const gboolean length_error = length < 4 ? TRUE : FALSE;
3413 if (length > 8 || length < 4) {
3415 report_type_length_mismatch(tree, "a relative time value", length, length_error);
3417 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
3420 tvb_ensure_bytes_exist(tvb, start, length);
3421 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
3422 if (endoff) *endoff = length;
3425 if (err) *err = saved_err;
3428 retval->secs = time_stamp.secs;
3429 retval->nsecs = time_stamp.nsecs;
3432 CHECK_FOR_NULL_TREE(tree);
3434 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3436 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3438 proto_tree_set_time(new_fi, &time_stamp);
3440 if (encoding & ENC_STRING) {
3441 if (saved_err == ERANGE)
3442 expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
3443 else if (saved_err == EDOM)
3444 expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
3448 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3451 return proto_tree_add_node(tree, new_fi);
3454 /* Add a FT_NONE to a proto_tree */
3456 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
3457 const gint start, gint length, const char *format,
3462 header_field_info *hfinfo;
3464 CHECK_FOR_NULL_TREE(tree);
3466 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3468 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
3470 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3472 TRY_TO_FAKE_THIS_REPR(pi);
3474 va_start(ap, format);
3475 proto_tree_set_representation(pi, format, ap);
3478 /* no value to set for FT_NONE */
3482 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
3483 * offset, and returns proto_item* */
3485 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
3486 const guint encoding)
3490 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
3496 /* Advance the ptvcursor's offset within its tvbuff without
3497 * adding anything to the proto_tree. */
3499 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
3501 ptvc->offset += length;
3506 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
3508 fvalue_set_protocol(&fi->value, tvb, field_data);
3511 /* Add a FT_PROTOCOL to a proto_tree */
3513 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3514 gint start, gint length, const char *format, ...)
3518 header_field_info *hfinfo;
3519 gchar* protocol_rep;
3521 CHECK_FOR_NULL_TREE(tree);
3523 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3525 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
3527 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3529 va_start(ap, format);
3530 protocol_rep = g_strdup_vprintf(format, ap);
3531 proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length)), protocol_rep);
3532 g_free(protocol_rep);
3535 TRY_TO_FAKE_THIS_REPR(pi);
3537 va_start(ap, format);
3538 proto_tree_set_representation(pi, format, ap);
3544 /* Add a FT_BYTES to a proto_tree */
3546 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3547 gint length, const guint8 *start_ptr)
3550 header_field_info *hfinfo;
3553 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3554 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
3555 test_length(hfinfo, tvb, start, item_length, ENC_NA);
3557 CHECK_FOR_NULL_TREE(tree);
3559 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3561 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
3563 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3564 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
3569 /* Add a FT_BYTES to a proto_tree */
3571 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3572 gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
3575 header_field_info *hfinfo;
3578 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3579 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA);
3580 test_length(hfinfo, tvb, start, item_length, ENC_NA);
3582 CHECK_FOR_NULL_TREE(tree);
3584 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3586 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
3588 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
3589 proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
3595 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3596 gint start, gint length,
3597 const guint8 *start_ptr,
3598 const char *format, ...)
3603 if (start_ptr == NULL)
3604 start_ptr = tvb_get_ptr(tvb, start, length);
3606 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
3608 TRY_TO_FAKE_THIS_REPR_NESTED(pi);
3610 va_start(ap, format);
3611 proto_tree_set_representation_value(pi, format, ap);
3618 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3619 gint start, gint length, const guint8 *start_ptr,
3620 const char *format, ...)
3625 if (start_ptr == NULL)
3626 start_ptr = tvb_get_ptr(tvb, start, length);
3628 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
3630 TRY_TO_FAKE_THIS_REPR_NESTED(pi);
3632 va_start(ap, format);
3633 proto_tree_set_representation(pi, format, ap);
3640 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
3644 DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
3646 bytes = g_byte_array_new();
3648 g_byte_array_append(bytes, start_ptr, length);
3650 fvalue_set_byte_array(&fi->value, bytes);
3655 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
3657 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
3661 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
3665 DISSECTOR_ASSERT(value != NULL);
3667 bytes = byte_array_dup(value);
3669 fvalue_set_byte_array(&fi->value, bytes);
3672 /* Add a FT_*TIME to a proto_tree */
3674 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3675 gint length, const nstime_t *value_ptr)
3678 header_field_info *hfinfo;
3680 CHECK_FOR_NULL_TREE(tree);
3682 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3684 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3686 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3687 proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
3693 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3694 gint start, gint length, nstime_t *value_ptr,
3695 const char *format, ...)
3700 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3702 va_start(ap, format);
3703 proto_tree_set_representation_value(pi, format, ap);
3711 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3712 gint start, gint length, nstime_t *value_ptr,
3713 const char *format, ...)
3718 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3720 TRY_TO_FAKE_THIS_REPR(pi);
3722 va_start(ap, format);
3723 proto_tree_set_representation(pi, format, ap);
3730 /* Set the FT_*TIME value */
3732 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
3734 DISSECTOR_ASSERT(value_ptr != NULL);
3736 fvalue_set_time(&fi->value, value_ptr);
3739 /* Add a FT_IPXNET to a proto_tree */
3741 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3742 gint length, guint32 value)
3745 header_field_info *hfinfo;
3747 CHECK_FOR_NULL_TREE(tree);
3749 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3751 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
3753 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3754 proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
3760 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3761 gint start, gint length, guint32 value,
3762 const char *format, ...)
3767 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3769 va_start(ap, format);
3770 proto_tree_set_representation_value(pi, format, ap);
3778 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3779 gint start, gint length, guint32 value,
3780 const char *format, ...)
3785 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3787 TRY_TO_FAKE_THIS_REPR(pi);
3789 va_start(ap, format);
3790 proto_tree_set_representation(pi, format, ap);
3797 /* Set the FT_IPXNET value */
3799 proto_tree_set_ipxnet(field_info *fi, guint32 value)
3801 fvalue_set_uinteger(&fi->value, value);
3804 /* Add a FT_IPv4 to a proto_tree */
3806 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3807 gint length, guint32 value)
3810 header_field_info *hfinfo;
3812 CHECK_FOR_NULL_TREE(tree);
3814 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3816 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
3818 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3819 proto_tree_set_ipv4(PNODE_FINFO(pi), value);
3825 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3826 gint start, gint length, guint32 value,
3827 const char *format, ...)
3832 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3834 va_start(ap, format);
3835 proto_tree_set_representation_value(pi, format, ap);
3843 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3844 gint start, gint length, guint32 value,
3845 const char *format, ...)
3850 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3852 TRY_TO_FAKE_THIS_REPR(pi);
3854 va_start(ap, format);
3855 proto_tree_set_representation(pi, format, ap);
3862 /* Set the FT_IPv4 value */
3864 proto_tree_set_ipv4(field_info *fi, guint32 value)
3866 fvalue_set_uinteger(&fi->value, value);
3869 /* Add a FT_IPv6 to a proto_tree */
3871 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3872 gint length, const ws_in6_addr *value_ptr)
3875 header_field_info *hfinfo;
3877 CHECK_FOR_NULL_TREE(tree);
3879 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3881 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
3883 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3884 proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
3890 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3891 gint start, gint length,
3892 const ws_in6_addr *value_ptr,
3893 const char *format, ...)
3898 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3900 va_start(ap, format);
3901 proto_tree_set_representation_value(pi, format, ap);
3909 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3910 gint start, gint length,
3911 const ws_in6_addr *value_ptr,
3912 const char *format, ...)
3917 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3919 TRY_TO_FAKE_THIS_REPR(pi);
3921 va_start(ap, format);
3922 proto_tree_set_representation(pi, format, ap);
3929 /* Set the FT_IPv6 value */
3931 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
3933 DISSECTOR_ASSERT(value_ptr != NULL);
3934 fvalue_set_bytes(&fi->value, value_ptr);
3938 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3940 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
3943 /* Set the FT_FCWWN value */
3945 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
3947 DISSECTOR_ASSERT(value_ptr != NULL);
3948 fvalue_set_bytes(&fi->value, value_ptr);
3952 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3954 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
3957 /* Add a FT_GUID to a proto_tree */
3959 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3960 gint length, const e_guid_t *value_ptr)
3963 header_field_info *hfinfo;
3965 CHECK_FOR_NULL_TREE(tree);
3967 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3969 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
3971 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3972 proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
3978 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3979 gint start, gint length,
3980 const e_guid_t *value_ptr,
3981 const char *format, ...)
3986 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3988 va_start(ap, format);
3989 proto_tree_set_representation_value(pi, format, ap);
3997 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3998 gint start, gint length, const e_guid_t *value_ptr,
3999 const char *format, ...)
4004 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4006 TRY_TO_FAKE_THIS_REPR(pi);
4008 va_start(ap, format);
4009 proto_tree_set_representation(pi, format, ap);
4016 /* Set the FT_GUID value */
4018 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
4020 DISSECTOR_ASSERT(value_ptr != NULL);
4021 fvalue_set_guid(&fi->value, value_ptr);
4025 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
4026 const guint encoding)
4030 tvb_get_guid(tvb, start, &guid, encoding);
4031 proto_tree_set_guid(fi, &guid);
4034 /* Add a FT_OID to a proto_tree */
4036 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4037 gint length, const guint8* value_ptr)
4040 header_field_info *hfinfo;
4042 CHECK_FOR_NULL_TREE(tree);
4044 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4046 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
4048 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4049 proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
4055 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4056 gint start, gint length,
4057 const guint8* value_ptr,
4058 const char *format, ...)
4063 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4065 va_start(ap, format);
4066 proto_tree_set_representation_value(pi, format, ap);
4074 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4075 gint start, gint length, const guint8* value_ptr,
4076 const char *format, ...)
4081 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4083 TRY_TO_FAKE_THIS_REPR(pi);
4085 va_start(ap, format);
4086 proto_tree_set_representation(pi, format, ap);
4093 /* Set the FT_OID value */
4095 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
4099 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4101 bytes = g_byte_array_new();
4103 g_byte_array_append(bytes, value_ptr, length);
4105 fvalue_set_byte_array(&fi->value, bytes);
4109 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4111 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
4114 /* Set the FT_SYSTEM_ID value */
4116 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
4120 DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4122 bytes = g_byte_array_new();
4124 g_byte_array_append(bytes, value_ptr, length);
4126 fvalue_set_byte_array(&fi->value, bytes);
4130 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4132 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
4135 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
4136 * own copy of string, and frees it when the proto_tree is destroyed. */
4138 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4139 gint length, const char* value)
4142 header_field_info *hfinfo;
4144 CHECK_FOR_NULL_TREE(tree);
4146 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4148 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
4150 if (hfinfo->display == STR_UNICODE) {
4151 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
4154 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4155 DISSECTOR_ASSERT(length >= 0);
4156 proto_tree_set_string(PNODE_FINFO(pi), value);
4162 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4163 gint start, gint length, const char* value,
4170 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4172 va_start(ap, format);
4173 proto_tree_set_representation_value(pi, format, ap);
4181 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4182 gint start, gint length, const char* value,
4183 const char *format, ...)
4188 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4190 TRY_TO_FAKE_THIS_REPR(pi);
4192 va_start(ap, format);
4193 proto_tree_set_representation(pi, format, ap);
4200 /* Set the FT_STRING value */
4202 proto_tree_set_string(field_info *fi, const char* value)
4205 fvalue_set_string(&fi->value, value);
4207 fvalue_set_string(&fi->value, "[ Null ]");
4211 /* Set the FT_AX25 value */
4213 proto_tree_set_ax25(field_info *fi, const guint8* value)
4215 fvalue_set_bytes(&fi->value, value);
4219 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
4221 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
4224 /* Set the FT_VINES value */
4226 proto_tree_set_vines(field_info *fi, const guint8* value)
4228 fvalue_set_bytes(&fi->value, value);
4232 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
4234 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
4237 /* Add a FT_ETHER to a proto_tree */
4239 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4240 gint length, const guint8* value)
4243 header_field_info *hfinfo;
4245 CHECK_FOR_NULL_TREE(tree);
4247 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4249 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
4251 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4252 proto_tree_set_ether(PNODE_FINFO(pi), value);
4258 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4259 gint start, gint length, const guint8* value,
4260 const char *format, ...)
4265 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
4267 va_start(ap, format);
4268 proto_tree_set_representation_value(pi, format, ap);
4276 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4277 gint start, gint length, const guint8* value,
4278 const char *format, ...)
4283 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
4285 TRY_TO_FAKE_THIS_REPR(pi);
4287 va_start(ap, format);
4288 proto_tree_set_representation(pi, format, ap);
4295 /* Set the FT_ETHER value */
4297 proto_tree_set_ether(field_info *fi, const guint8* value)
4299 fvalue_set_bytes(&fi->value, value);
4303 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
4305 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
4308 /* Add a FT_BOOLEAN to a proto_tree */
4310 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4311 gint length, guint32 value)
4314 header_field_info *hfinfo;
4316 CHECK_FOR_NULL_TREE(tree);
4318 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4320 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
4322 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4323 proto_tree_set_boolean(PNODE_FINFO(pi), value);
4329 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
4330 tvbuff_t *tvb, gint start, gint length,
4331 guint32 value, const char *format, ...)
4336 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
4338 va_start(ap, format);
4339 proto_tree_set_representation_value(pi, format, ap);
4347 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4348 gint start, gint length, guint32 value,
4349 const char *format, ...)
4354 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
4356 TRY_TO_FAKE_THIS_REPR(pi);
4358 va_start(ap, format);
4359 proto_tree_set_representation(pi, format, ap);
4367 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4368 gint length, guint64 value)
4371 header_field_info *hfinfo;
4373 CHECK_FOR_NULL_TREE(tree);
4375 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4377 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
4379 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4380 proto_tree_set_boolean(PNODE_FINFO(pi), value);
4385 /* Set the FT_BOOLEAN value */
4387 proto_tree_set_boolean(field_info *fi, guint64 value)
4389 proto_tree_set_uint64(fi, value);
4392 /* Generate, into "buf", a string showing the bits of a bitfield.
4393 Return a pointer to the character after that string. */
4394 /*XXX this needs a buf_len check */
4396 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
4404 bit = G_GUINT64_CONSTANT(1) << (width - 1);
4407 /* This bit is part of the field. Show its value. */
4413 /* This bit is not part of the field. */
4428 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
4432 p = other_decode_bitfield_value(buf, val, mask, width);
4433 p = g_stpcpy(p, " = ");
4439 other_decode_bitfield_varint_value(char *buf, guint64 val, guint64 mask, const int width)
4446 bit = G_GUINT64_CONSTANT(1) << (width - 1);
4448 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
4450 /* This bit is part of the field. Show its value. */
4456 /* This bit is not part of the field. */
4472 decode_bitfield_varint_value(char *buf, const guint64 val, const guint64 mask, const int width)
4476 p = other_decode_bitfield_varint_value(buf, val, mask, width);
4477 p = g_stpcpy(p, " = ");
4482 /* Add a FT_FLOAT to a proto_tree */
4484 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4485 gint length, float value)
4488 header_field_info *hfinfo;
4490 CHECK_FOR_NULL_TREE(tree);
4492 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4494 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
4496 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4497 proto_tree_set_float(PNODE_FINFO(pi), value);
4503 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4504 gint start, gint length, float value,
4505 const char *format, ...)
4510 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
4512 va_start(ap, format);
4513 proto_tree_set_representation_value(pi, format, ap);
4521 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4522 gint start, gint length, float value,
4523 const char *format, ...)
4528 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
4530 TRY_TO_FAKE_THIS_REPR(pi);
4532 va_start(ap, format);
4533 proto_tree_set_representation(pi, format, ap);
4540 /* Set the FT_FLOAT value */
4542 proto_tree_set_float(field_info *fi, float value)
4544 fvalue_set_floating(&fi->value, value);
4547 /* Add a FT_DOUBLE to a proto_tree */
4549 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4550 gint length, double value)
4553 header_field_info *hfinfo;
4555 CHECK_FOR_NULL_TREE(tree);
4557 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4559 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
4561 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4562 proto_tree_set_double(PNODE_FINFO(pi), value);
4568 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4569 gint start, gint length, double value,
4570 const char *format, ...)
4575 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
4577 va_start(ap, format);
4578 proto_tree_set_representation_value(pi, format, ap);
4586 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4587 gint start, gint length, double value,
4588 const char *format, ...)
4593 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
4595 TRY_TO_FAKE_THIS_REPR(pi);
4597 va_start(ap, format);
4598 proto_tree_set_representation(pi, format, ap);
4605 /* Set the FT_DOUBLE value */
4607 proto_tree_set_double(field_info *fi, double value)
4609 fvalue_set_floating(&fi->value, value);
4612 /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
4614 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4615 gint length, guint32 value)
4617 proto_item *pi = NULL;
4618 header_field_info *hfinfo;
4620 CHECK_FOR_NULL_TREE(tree);
4622 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4624 switch (hfinfo->type) {
4631 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4632 proto_tree_set_uint(PNODE_FINFO(pi), value);
4636 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4637 "field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",
4645 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4646 gint start, gint length, guint32 value,
4647 const char *format, ...)
4652 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
4654 va_start(ap, format);
4655 proto_tree_set_representation_value(pi, format, ap);
4663 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4664 gint start, gint length, guint32 value,
4665 const char *format, ...)
4670 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
4672 TRY_TO_FAKE_THIS_REPR(pi);
4674 va_start(ap, format);
4675 proto_tree_set_representation(pi, format, ap);
4682 /* Set the FT_UINT{8,16,24,32} value */
4684 proto_tree_set_uint(field_info *fi, guint32 value)
4686 header_field_info *hfinfo;
4689 hfinfo = fi->hfinfo;
4692 if (hfinfo->bitmask) {
4693 /* Mask out irrelevant portions */
4694 integer &= (guint32)(hfinfo->bitmask);
4697 integer >>= hfinfo_bitshift(hfinfo);
4700 fvalue_set_uinteger(&fi->value, integer);
4703 /* Add FT_UINT{40,48,56,64} to a proto_tree */
4705 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4706 gint length, guint64 value)
4708 proto_item *pi = NULL;
4709 header_field_info *hfinfo;
4711 CHECK_FOR_NULL_TREE(tree);
4713 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4715 switch (hfinfo->type) {
4721 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4722 proto_tree_set_uint64(PNODE_FINFO(pi), value);
4726 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4727 "field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",
4735 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4736 gint start, gint length, guint64 value,
4737 const char *format, ...)
4742 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4744 va_start(ap, format);
4745 proto_tree_set_representation_value(pi, format, ap);
4753 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4754 gint start, gint length, guint64 value,
4755 const char *format, ...)
4760 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4762 TRY_TO_FAKE_THIS_REPR(pi);
4764 va_start(ap, format);
4765 proto_tree_set_representation(pi, format, ap);
4772 /* Set the FT_UINT{40,48,56,64} value */
4774 proto_tree_set_uint64(field_info *fi, guint64 value)
4776 header_field_info *hfinfo;
4779 hfinfo = fi->hfinfo;
4782 if (hfinfo->bitmask) {
4783 /* Mask out irrelevant portions */
4784 integer &= hfinfo->bitmask;
4787 integer >>= hfinfo_bitshift(hfinfo);
4790 fvalue_set_uinteger64(&fi->value, integer);
4793 /* Add FT_INT{8,16,24,32} to a proto_tree */
4795 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4796 gint length, gint32 value)
4798 proto_item *pi = NULL;
4799 header_field_info *hfinfo;
4801 CHECK_FOR_NULL_TREE(tree);
4803 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4805 switch (hfinfo->type) {
4810 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4811 proto_tree_set_int(PNODE_FINFO(pi), value);
4815 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4816 "field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
4824 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4825 gint start, gint length, gint32 value,
4826 const char *format, ...)
4831 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4833 va_start(ap, format);
4834 proto_tree_set_representation_value(pi, format, ap);
4842 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4843 gint start, gint length, gint32 value,
4844 const char *format, ...)
4849 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4851 TRY_TO_FAKE_THIS_REPR(pi);
4853 va_start(ap, format);
4854 proto_tree_set_representation(pi, format, ap);
4861 /* Set the FT_INT{8,16,24,32} value */
4863 proto_tree_set_int(field_info *fi, gint32 value)
4865 header_field_info *hfinfo;
4869 hfinfo = fi->hfinfo;
4870 integer = (guint32) value;
4872 if (hfinfo->bitmask) {
4873 /* Mask out irrelevant portions */
4874 integer &= (guint32)(hfinfo->bitmask);
4877 integer >>= hfinfo_bitshift(hfinfo);
4879 no_of_bits = ws_count_ones(hfinfo->bitmask);
4880 integer = ws_sign_ext32(integer, no_of_bits);
4883 fvalue_set_sinteger(&fi->value, integer);
4886 /* Add FT_INT{40,48,56,64} to a proto_tree */
4888 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4889 gint length, gint64 value)
4891 proto_item *pi = NULL;
4892 header_field_info *hfinfo;
4894 CHECK_FOR_NULL_TREE(tree);
4896 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4898 switch (hfinfo->type) {
4903 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4904 proto_tree_set_int64(PNODE_FINFO(pi), value);
4908 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4909 "field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
4917 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4918 gint start, gint length, gint64 value,
4919 const char *format, ...)
4924 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4926 va_start(ap, format);
4927 proto_tree_set_representation_value(pi, format, ap);
4934 /* Set the FT_INT{40,48,56,64} value */
4936 proto_tree_set_int64(field_info *fi, gint64 value)
4938 header_field_info *hfinfo;
4942 hfinfo = fi->hfinfo;
4945 if (hfinfo->bitmask) {
4946 /* Mask out irrelevant portions */
4947 integer &= hfinfo->bitmask;
4950 integer >>= hfinfo_bitshift(hfinfo);
4952 no_of_bits = ws_count_ones(hfinfo->bitmask);
4953 integer = ws_sign_ext64(integer, no_of_bits);
4956 fvalue_set_sinteger64(&fi->value, integer);
4960 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4961 gint start, gint length, gint64 value,
4962 const char *format, ...)
4967 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4969 TRY_TO_FAKE_THIS_REPR(pi);
4971 va_start(ap, format);
4972 proto_tree_set_representation(pi, format, ap);
4979 /* Add a FT_EUI64 to a proto_tree */
4981 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4982 gint length, const guint64 value)
4985 header_field_info *hfinfo;
4987 CHECK_FOR_NULL_TREE(tree);
4989 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4991 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
4993 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4994 proto_tree_set_eui64(PNODE_FINFO(pi), value);
5000 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5001 gint start, gint length, const guint64 value,
5002 const char *format, ...)
5007 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5009 va_start(ap, format);
5010 proto_tree_set_representation_value(pi, format, ap);
5018 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5019 gint start, gint length, const guint64 value,
5020 const char *format, ...)
5025 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5027 TRY_TO_FAKE_THIS_REPR(pi);
5029 va_start(ap, format);
5030 proto_tree_set_representation(pi, format, ap);
5037 /* Set the FT_EUI64 value */
5039 proto_tree_set_eui64(field_info *fi, const guint64 value)
5041 fvalue_set_uinteger64(&fi->value, value);
5044 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
5048 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
5050 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
5054 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
5056 proto_tree_add_node(proto_tree *tree, field_info *fi)
5058 proto_node *pnode, *tnode, *sibling;
5063 * Restrict our depth. proto_tree_traverse_pre_order and
5064 * proto_tree_traverse_post_order (and possibly others) are recursive
5065 * so we need to be mindful of our stack size.
5067 if (tree->first_child == NULL) {
5068 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
5070 if (G_UNLIKELY(depth > MAX_TREE_LEVELS)) {
5071 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
5072 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u)",
5074 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
5080 * Make sure "tree" is ready to have subtrees under it, by
5081 * checking whether it's been given an ett_ value.
5083 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
5084 * node of the protocol tree. That node is not displayed,
5085 * so it doesn't need an ett_ value to remember whether it
5089 tfi = PNODE_FINFO(tnode);
5090 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
5091 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
5092 "\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
5093 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
5094 /* XXX - is it safe to continue here? */
5097 pnode = wmem_new(PNODE_POOL(tree), proto_node);
5098 PROTO_NODE_INIT(pnode);
5099 pnode->parent = tnode;
5100 PNODE_FINFO(pnode) = fi;
5101 pnode->tree_data = PTREE_DATA(tree);
5103 if (tnode->last_child != NULL) {
5104 sibling = tnode->last_child;
5105 DISSECTOR_ASSERT(sibling->next == NULL);
5106 sibling->next = pnode;
5108 tnode->first_child = pnode;
5109 tnode->last_child = pnode;
5111 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
5113 return (proto_item *)pnode;
5117 /* Generic way to allocate field_info and add to proto_tree.
5118 * Sets *pfi to address of newly-allocated field_info struct */
5120 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
5127 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA);
5128 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
5129 pi = proto_tree_add_node(tree, fi);
5136 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
5137 gint *item_length, const guint encoding)
5139 gint length_remaining;
5142 * We only allow a null tvbuff if the item has a zero length,
5143 * i.e. if there's no data backing it.
5145 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
5148 * XXX - in some protocols, there are 32-bit unsigned length
5149 * fields, so lengths in protocol tree and tvbuff routines
5150 * should really be unsigned. We should have, for those
5151 * field types for which "to the end of the tvbuff" makes sense,
5152 * additional routines that take no length argument and
5153 * add fields that run to the end of the tvbuff.
5155 if (*length == -1) {
5157 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
5158 * FT_STRINGZPAD fields, a length of -1 means "set the
5159 * length to what remains in the tvbuff".
5161 * The assumption is either that
5163 * 1) the length of the item can only be determined
5164 * by dissection (typically true of items with
5165 * subitems, which are probably FT_NONE or
5170 * 2) if the tvbuff is "short" (either due to a short
5171 * snapshot length or due to lack of reassembly of
5172 * fragments/segments/whatever), we want to display
5173 * what's available in the field (probably FT_BYTES
5174 * or FT_STRING) and then throw an exception later
5178 * 3) the field is defined to be "what's left in the
5181 * so we set the length to what remains in the tvbuff so
5182 * that, if we throw an exception while dissecting, it
5183 * has what is probably the right value.
5185 * For FT_STRINGZ, it means "the string is null-terminated,
5186 * not null-padded; set the length to the actual length
5187 * of the string", and if the tvbuff if short, we just
5188 * throw an exception.
5190 * For ENC_VARINT_PROTOBUF, it means "find the end of the string",
5191 * and if the tvbuff if short, we just throw an exception.
5193 * It's not valid for any other type of field. For those
5194 * fields, we treat -1 the same way we treat other
5195 * negative values - we assume the length is a Really
5196 * Big Positive Number, and throw a ReportedBoundsError
5197 * exception, under the assumption that the Really Big
5198 * Length would run past the end of the packet.
5200 if ((IS_FT_INT(hfinfo->type)) || (IS_FT_UINT(hfinfo->type))) {
5201 if (encoding & ENC_VARINT_PROTOBUF) {
5203 * Leave the length as -1, so our caller knows
5206 *item_length = *length;
5211 switch (hfinfo->type) {
5219 * We allow FT_PROTOCOLs to be zero-length -
5220 * for example, an ONC RPC NULL procedure has
5221 * neither arguments nor reply, so the
5222 * payload for that protocol is empty.
5224 * We also allow the others to be zero-length -
5225 * because that's the way the code has been for a
5228 * However, we want to ensure that the start
5229 * offset is not *past* the byte past the end
5230 * of the tvbuff: we throw an exception in that
5233 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
5234 DISSECTOR_ASSERT(*length >= 0);
5239 * Leave the length as -1, so our caller knows
5245 THROW(ReportedBoundsError);
5246 DISSECTOR_ASSERT_NOT_REACHED();
5248 *item_length = *length;
5250 *item_length = *length;
5251 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
5253 * These types are for interior nodes of the
5254 * tree, and don't have data associated with
5255 * them; if the length is negative (XXX - see
5256 * above) or goes past the end of the tvbuff,
5257 * cut it short at the end of the tvbuff.
5258 * That way, if this field is selected in
5259 * Wireshark, we don't highlight stuff past
5260 * the end of the data.
5262 /* XXX - what to do, if we don't have a tvb? */
5264 length_remaining = tvb_captured_length_remaining(tvb, start);
5265 if (*item_length < 0 ||
5266 (*item_length > 0 &&
5267 (length_remaining < *item_length)))
5268 *item_length = length_remaining;
5271 if (*item_length < 0) {
5272 THROW(ReportedBoundsError);
5278 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
5279 gint length, guint item_length, const gint encoding)
5284 * We need to get the correct item length here.
5285 * That's normally done by proto_tree_new_item(),
5286 * but we won't be calling it.
5288 switch (hfinfo->type) {
5294 * The length is the specified length.
5299 n = get_uint_value(NULL, tvb, start, length, encoding);
5303 /* XXX - make these just FT_UINT? */
5312 /* XXX - make these just FT_INT? */
5321 if (encoding & ENC_VARINT_PROTOBUF) {
5323 report_type_length_mismatch(NULL, "a FT_[U]INT", length, TRUE);
5327 /* This can throw an exception */
5328 /* XXX - do this without fetching the varint? */
5329 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN, &dummy);
5331 THROW(ReportedBoundsError);
5334 item_length = length;
5339 * The length is the specified length.
5361 * The length is the specified length.
5367 report_type_length_mismatch(NULL, "a string", length, TRUE);
5370 /* This can throw an exception */
5371 /* XXX - do this without fetching the string? */
5372 tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
5374 item_length = length;
5377 case FT_UINT_STRING:
5378 if (encoding & ENC_ZIGBEE) {
5379 n = get_uint_value(NULL, tvb, start, length, encoding);
5381 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
5387 case FT_ABSOLUTE_TIME:
5388 case FT_RELATIVE_TIME:
5389 case FT_IEEE_11073_SFLOAT:
5390 case FT_IEEE_11073_FLOAT:
5392 * The length is the specified length.
5397 g_error("hfinfo->type %d (%s) not handled\n",
5399 ftype_name(hfinfo->type));
5400 DISSECTOR_ASSERT_NOT_REACHED();
5407 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
5408 const gint start, const gint item_length)
5412 FIELD_INFO_NEW(PNODE_POOL(tree), fi);
5414 fi->hfinfo = hfinfo;
5416 fi->start += (tvb)?tvb_raw_offset(tvb):0;
5417 fi->length = item_length;
5420 if (!PTREE_DATA(tree)->visible)
5421 FI_SET_FLAG(fi, FI_HIDDEN);
5422 fvalue_init(&fi->value, fi->hfinfo->type);
5425 /* add the data source tvbuff */
5426 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
5428 fi->appendix_start = 0;
5429 fi->appendix_length = 0;
5434 /* If the protocol tree is to be visible, set the representation of a
5435 proto_tree entry with the name of the field for the item and with
5436 the value formatted with the supplied printf-style format and
5439 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
5443 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
5444 * items string representation */
5445 if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
5447 field_info *fi = PITEM_FINFO(pi);
5448 header_field_info *hf;
5450 DISSECTOR_ASSERT(fi);
5454 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5455 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
5459 if (IS_FT_UINT32(hf->type))
5460 val = fvalue_get_uinteger(&fi->value);
5462 val = fvalue_get_uinteger64(&fi->value);
5464 val <<= hfinfo_bitshift(hf);
5466 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
5467 ret = (int) (p - fi->rep->representation);
5470 /* put in the hf name */
5471 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
5473 /* If possible, Put in the value of the string */
5474 if (ret < ITEM_LABEL_LENGTH) {
5475 ret += g_vsnprintf(fi->rep->representation + ret,
5476 ITEM_LABEL_LENGTH - ret, format, ap);
5478 if (ret >= ITEM_LABEL_LENGTH) {
5479 /* Uh oh, we don't have enough room. Tell the user
5480 * that the field is truncated.
5482 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
5487 /* If the protocol tree is to be visible, set the representation of a
5488 proto_tree entry with the representation formatted with the supplied
5489 printf-style format and argument list. */
5491 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
5493 int ret; /*tmp return value */
5494 field_info *fi = PITEM_FINFO(pi);
5496 DISSECTOR_ASSERT(fi);
5498 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5499 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5500 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
5502 if (ret >= ITEM_LABEL_LENGTH) {
5503 /* Uh oh, we don't have enough room. Tell the user
5504 * that the field is truncated.
5506 LABEL_MARK_TRUNCATED_START(fi->rep->representation);
5512 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
5514 switch (hfinfo->display) {
5516 return format_text(NULL, string, strlen(string));
5519 return format_text_wsp(string, strlen(string));
5522 /* XXX, format_unicode_text() */
5523 return wmem_strdup(NULL, string);
5526 return format_text(NULL, string, strlen(string));
5530 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
5532 gsize res = g_strlcpy(dest, src, dest_size);
5534 if (res > dest_size)
5539 static header_field_info *
5540 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
5542 header_field_info *dup_hfinfo;
5544 if (hfinfo->same_name_prev_id == -1)
5546 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
5551 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
5553 g_free(last_field_name);
5554 last_field_name = NULL;
5556 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
5557 /* No hfinfo with the same name */
5558 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
5562 if (hfinfo->same_name_next) {
5563 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
5566 if (hfinfo->same_name_prev_id != -1) {
5567 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
5568 same_name_prev->same_name_next = hfinfo->same_name_next;
5569 if (!hfinfo->same_name_next) {
5570 /* It's always the latest added hfinfo which is stored in gpa_name_map */
5571 g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
5576 /* -------------------------- */
5578 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
5579 gchar *result, gchar *expr, const int size)
5588 const true_false_string *tfstring;
5590 int len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
5592 field_info *finfo = NULL;
5593 header_field_info* hfinfo;
5594 const gchar *abbrev = NULL;
5596 const char *hf_str_val;
5597 char number_buf[48];
5598 const char *number_out;
5604 g_assert(field_ids != NULL);
5605 while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
5606 field_id = *field_idx;
5607 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
5609 /* do we need to rewind ? */
5613 if (occurrence < 0) {
5614 /* Search other direction */
5615 while (hfinfo->same_name_prev_id != -1) {
5616 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
5621 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
5623 if (!finfos || !(len = g_ptr_array_len(finfos))) {
5624 if (occurrence < 0) {
5625 hfinfo = hfinfo->same_name_next;
5627 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5632 /* Are there enough occurrences of the field? */
5633 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
5634 if (occurrence < 0) {
5635 hfinfo = hfinfo->same_name_next;
5637 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5643 /* Calculate single index or set outer bounderies */
5644 if (occurrence < 0) {
5645 i = occurrence + len + prev_len;
5647 } else if (occurrence > 0) {
5648 i = occurrence - 1 - prev_len;
5655 prev_len += len; /* Count handled occurrences */
5658 finfo = (field_info *)g_ptr_array_index(finfos, i);
5660 if (offset_r && (offset_r < (size - 2)))
5661 result[offset_r++] = ',';
5663 if (offset_e && (offset_e < (size - 2)))
5664 expr[offset_e++] = ',';
5666 switch (hfinfo->type) {
5670 /* prevent multiple check marks by setting result directly */
5671 g_strlcpy(result, UTF8_CHECK_MARK, size);
5676 bytes = (guint8 *)fvalue_get(&finfo->value);
5678 switch(hfinfo->display)
5681 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
5684 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
5687 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
5690 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5694 if (prefs.display_byte_fields_with_spaces)
5696 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5700 str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
5704 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5705 wmem_free(NULL, str);
5708 if (hfinfo->display & BASE_ALLOW_ZERO) {
5709 offset_r += protoo_strlcpy(result+offset_r, "<none>", size-offset_r);
5711 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
5716 case FT_ABSOLUTE_TIME:
5717 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
5718 offset_r += protoo_strlcpy(result+offset_r,
5721 wmem_free(NULL, tmpbuf);
5724 case FT_RELATIVE_TIME:
5725 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
5726 offset_r += protoo_strlcpy(result+offset_r,
5729 wmem_free(NULL, tmpbuf);
5733 number64 = fvalue_get_uinteger64(&finfo->value);
5734 tfstring = (const true_false_string *)&tfs_true_false;
5735 if (hfinfo->strings) {
5736 tfstring = (const struct true_false_string*) hfinfo->strings;
5738 offset_r += protoo_strlcpy(result+offset_r,
5740 tfstring->true_string :
5741 tfstring->false_string, size-offset_r);
5743 offset_e += protoo_strlcpy(expr+offset_e,
5744 number64 ? "1" : "0", size-offset_e);
5749 number = fvalue_get_uinteger(&finfo->value);
5751 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
5752 gchar tmp[ITEM_LABEL_LENGTH];
5753 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5755 DISSECTOR_ASSERT(fmtfunc);
5756 fmtfunc(tmp, number);
5758 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5760 } else if (hfinfo->strings) {
5761 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5764 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
5766 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5769 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5771 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5774 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
5775 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5777 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5779 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5782 offset_e = (int)strlen(expr);
5785 /* XXX - make these just FT_NUMBER? */
5796 number = IS_FT_INT(hfinfo->type) ?
5797 (guint32) fvalue_get_sinteger(&finfo->value) :
5798 fvalue_get_uinteger(&finfo->value);
5800 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
5801 gchar tmp[ITEM_LABEL_LENGTH];
5802 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5804 DISSECTOR_ASSERT(fmtfunc);
5805 fmtfunc(tmp, number);
5807 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5809 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
5810 if (hfinfo->display & BASE_UNIT_STRING) {
5811 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5812 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5813 hf_str_val = hf_try_val_to_str(number, hfinfo);
5814 offset_r += protoo_strlcpy(result+offset_r, hf_str_val, size-offset_r);
5816 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5819 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
5821 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5824 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
5826 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5829 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
5830 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5832 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5834 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5837 offset_e = (int)strlen(expr);
5849 number64 = IS_FT_INT(hfinfo->type) ?
5850 (guint64) fvalue_get_sinteger64(&finfo->value) :
5851 fvalue_get_uinteger64(&finfo->value);
5853 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
5854 gchar tmp[ITEM_LABEL_LENGTH];
5855 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
5857 DISSECTOR_ASSERT(fmtfunc64);
5858 fmtfunc64(tmp, number64);
5859 offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5860 } else if (hfinfo->strings) {
5861 if (hfinfo->display & BASE_UNIT_STRING) {
5862 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
5863 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5864 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
5865 offset_r += protoo_strlcpy(result+offset_r, hf_str_val, size-offset_r);
5867 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
5870 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
5872 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5875 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
5877 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5880 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
5881 g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5883 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
5885 g_strlcpy(expr+offset_e, number_out, size-offset_e);
5888 offset_e = (int)strlen(expr);
5892 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
5893 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5894 wmem_free(NULL, str);
5898 ipv4 = fvalue_get_uinteger(&finfo->value);
5899 set_address (&addr, AT_IPv4, 4, &ipv4);
5900 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5901 offset_r = (int)strlen(result);
5905 ipv6 = (ws_in6_addr *)fvalue_get(&finfo->value);
5906 set_address (&addr, AT_IPv6, sizeof(ws_in6_addr), ipv6);
5907 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5908 offset_r = (int)strlen(result);
5912 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
5913 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5914 offset_r = (int)strlen(result);
5918 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
5919 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5920 offset_r = (int)strlen(result);
5924 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
5925 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5926 wmem_free(NULL, str);
5930 bytes = (guint8 *)fvalue_get(&finfo->value);
5931 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5932 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5933 wmem_free(NULL, str);
5935 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5936 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5937 wmem_free(NULL, str);
5941 bytes = (guint8 *)fvalue_get(&finfo->value);
5942 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5943 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5944 wmem_free(NULL, str);
5946 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5947 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5948 wmem_free(NULL, str);
5952 bytes = (guint8 *)fvalue_get(&finfo->value);
5953 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
5954 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5955 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5956 wmem_free(NULL, str);
5960 if (hfinfo->display & BASE_UNIT_STRING) {
5961 double d_value = fvalue_get_floating(&finfo->value);
5962 g_snprintf(result+offset_r, size-offset_r,
5963 "%." G_STRINGIFY(FLT_DIG) "g%s", d_value,
5964 unit_name_string_get_double(d_value, (unit_name_string*)hfinfo->strings));
5966 g_snprintf(result+offset_r, size-offset_r,
5967 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
5969 offset_r = (int)strlen(result);
5973 if (hfinfo->display & BASE_UNIT_STRING) {
5974 double d_value = fvalue_get_floating(&finfo->value);
5975 g_snprintf(result+offset_r, size-offset_r,
5976 "%." G_STRINGIFY(DBL_DIG) "g%s", d_value,
5977 unit_name_string_get_double(d_value, (unit_name_string*)hfinfo->strings));
5979 g_snprintf(result+offset_r, size-offset_r,
5980 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
5982 offset_r = (int)strlen(result);
5987 case FT_UINT_STRING:
5989 bytes = (guint8 *)fvalue_get(&finfo->value);
5990 str = hfinfo_format_text(hfinfo, bytes);
5991 offset_r += protoo_strlcpy(result+offset_r,
5992 str, size-offset_r);
5993 wmem_free(NULL, str);
5996 case FT_IEEE_11073_SFLOAT:
5997 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5998 g_snprintf(result+offset_r, size-offset_r,
6001 wmem_free(NULL, str);
6002 offset_r = (int)strlen(result);
6005 case FT_IEEE_11073_FLOAT:
6006 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
6007 g_snprintf(result+offset_r, size-offset_r,
6010 offset_r = (int)strlen(result);
6011 wmem_free(NULL, str);
6014 case FT_IPXNET: /*XXX really No column custom ?*/
6017 g_error("hfinfo->type %d (%s) not handled\n",
6019 ftype_name(hfinfo->type));
6020 DISSECTOR_ASSERT_NOT_REACHED();
6026 switch (hfinfo->type) {
6050 /* for these types, "expr" is filled in the loop above */
6054 /* for all others, just copy "result" to "expr" */
6055 g_strlcpy(expr, result, size);
6060 /* Store abbrev for return value */
6061 abbrev = hfinfo->abbrev;
6064 if (occurrence == 0) {
6065 /* Fetch next hfinfo with same name (abbrev) */
6066 hfinfo = hfinfo_same_name_get_prev(hfinfo);
6073 return abbrev ? abbrev : "";
6077 /* Set text of proto_item after having already been created. */
6079 proto_item_set_text(proto_item *pi, const char *format, ...)
6081 field_info *fi = NULL;
6084 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6086 fi = PITEM_FINFO(pi);
6091 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
6095 va_start(ap, format);
6096 proto_tree_set_representation(pi, format, ap);
6100 /* Append to text of proto_item after having already been created. */
6102 proto_item_append_text(proto_item *pi, const char *format, ...)
6104 field_info *fi = NULL;
6108 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6110 fi = PITEM_FINFO(pi);
6115 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
6117 * If we don't already have a representation,
6118 * generate the default representation.
6120 if (fi->rep == NULL) {
6121 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6122 proto_item_fill_label(fi, fi->rep->representation);
6125 curlen = strlen(fi->rep->representation);
6126 if (ITEM_LABEL_LENGTH > curlen) {
6127 va_start(ap, format);
6128 g_vsnprintf(fi->rep->representation + curlen,
6129 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
6135 /* Prepend to text of proto_item after having already been created. */
6137 proto_item_prepend_text(proto_item *pi, const char *format, ...)
6139 field_info *fi = NULL;
6140 char representation[ITEM_LABEL_LENGTH];
6143 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6145 fi = PITEM_FINFO(pi);
6150 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
6152 * If we don't already have a representation,
6153 * generate the default representation.
6155 if (fi->rep == NULL) {
6156 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6157 proto_item_fill_label(fi, representation);
6159 g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
6161 va_start(ap, format);
6162 g_vsnprintf(fi->rep->representation,
6163 ITEM_LABEL_LENGTH, format, ap);
6165 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
6170 finfo_set_len(field_info *fi, const gint length)
6172 gint length_remaining;
6174 DISSECTOR_ASSERT(length >= 0);
6175 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
6176 if (length > length_remaining)
6177 fi->length = length_remaining;
6179 fi->length = length;
6182 * You cannot just make the "len" field of a GByteArray
6183 * larger, if there's no data to back that length;
6184 * you can only make it smaller.
6186 if (fi->value.ftype->ftype == FT_BYTES && fi->length <= (gint)fi->value.value.bytes->len)
6187 fi->value.value.bytes->len = fi->length;
6191 proto_item_set_len(proto_item *pi, const gint length)
6195 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6197 fi = PITEM_FINFO(pi);
6201 finfo_set_len(fi, length);
6205 * Sets the length of the item based on its start and on the specified
6206 * offset, which is the offset past the end of the item; as the start
6207 * in the item is relative to the beginning of the data source tvbuff,
6208 * we need to pass in a tvbuff - the end offset is relative to the beginning
6212 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
6217 TRY_TO_FAKE_THIS_REPR_VOID(pi);
6219 fi = PITEM_FINFO(pi);
6223 end += tvb_raw_offset(tvb);
6224 DISSECTOR_ASSERT(end >= fi->start);
6225 length = end - fi->start;
6227 finfo_set_len(fi, length);
6231 proto_item_get_len(const proto_item *pi)
6233 field_info *fi = PITEM_FINFO(pi);
6234 return fi ? fi->length : -1;
6238 proto_tree_create_root(packet_info *pinfo)
6242 /* Initialize the proto_node */
6243 pnode = g_slice_new(proto_tree);
6244 PROTO_NODE_INIT(pnode);
6245 pnode->parent = NULL;
6246 PNODE_FINFO(pnode) = NULL;
6247 pnode->tree_data = g_slice_new(tree_data_t);
6249 /* Make sure we can access pinfo everywhere */
6250 pnode->tree_data->pinfo = pinfo;
6252 /* Don't initialize the tree_data_t. Wait until we know we need it */
6253 pnode->tree_data->interesting_hfids = NULL;
6255 /* Set the default to FALSE so it's easier to
6256 * find errors; if we expect to see the protocol tree
6257 * but for some reason the default 'visible' is not
6258 * changed, then we'll find out very quickly. */
6259 pnode->tree_data->visible = FALSE;
6261 /* Make sure that we fake protocols (if possible) */
6262 pnode->tree_data->fake_protocols = TRUE;
6264 /* Keep track of the number of children */
6265 pnode->tree_data->count = 0;
6267 return (proto_tree *)pnode;
6271 /* "prime" a proto_tree with a single hfid that a dfilter
6272 * is interested in. */
6274 proto_tree_prime_with_hfid(proto_tree *tree _U_, const gint hfid)
6276 header_field_info *hfinfo;
6278 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
6279 /* this field is referenced by a filter so increase the refcount.
6280 also increase the refcount for the parent, i.e the protocol.
6282 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
6283 /* only increase the refcount if there is a parent.
6284 if this is a protocol and not a field then parent will be -1
6285 and there is no parent to add any refcounting for.
6287 if (hfinfo->parent != -1) {
6288 header_field_info *parent_hfinfo;
6289 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
6291 /* Mark parent as indirectly referenced unless it is already directly
6292 * referenced, i.e. the user has specified the parent in a filter.
6294 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
6295 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
6300 proto_item_add_subtree(proto_item *pi, const gint idx) {
6306 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
6308 fi = PITEM_FINFO(pi);
6310 return (proto_tree *)pi;
6312 fi->tree_type = idx;
6314 return (proto_tree *)pi;
6318 proto_item_get_subtree(proto_item *pi) {
6323 fi = PITEM_FINFO(pi);
6324 if ( (!fi) || (fi->tree_type == -1) )
6326 return (proto_tree *)pi;
6330 proto_item_get_parent(const proto_item *ti) {
6337 proto_item_get_parent_nth(proto_item *ti, int gen) {
6350 proto_tree_get_parent(proto_tree *tree) {
6353 return (proto_item *)tree;
6357 proto_tree_get_parent_tree(proto_tree *tree) {
6361 /* we're the root tree, there's no parent
6362 return ourselves so the caller has at least a tree to attach to */
6366 return (proto_tree *)tree->parent;
6370 proto_tree_get_root(proto_tree *tree) {
6373 while (tree->parent) {
6374 tree = tree->parent;
6380 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
6381 proto_item *item_to_move)
6384 /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
6385 * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
6387 /* This function doesn't generate any values. It only reorganizes the prococol tree
6388 * so we can bail out immediately if it isn't visible. */
6389 if (!tree || !PTREE_DATA(tree)->visible)
6392 DISSECTOR_ASSERT(item_to_move->parent == tree);
6393 DISSECTOR_ASSERT(fixed_item->parent == tree);
6395 /*** cut item_to_move out ***/
6397 /* is item_to_move the first? */
6398 if (tree->first_child == item_to_move) {
6399 /* simply change first child to next */
6400 tree->first_child = item_to_move->next;
6402 DISSECTOR_ASSERT(tree->last_child != item_to_move);
6404 proto_item *curr_item;
6405 /* find previous and change it's next */
6406 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
6407 if (curr_item->next == item_to_move) {
6412 DISSECTOR_ASSERT(curr_item);
6414 curr_item->next = item_to_move->next;
6416 /* fix last_child if required */
6417 if (tree->last_child == item_to_move) {
6418 tree->last_child = curr_item;
6422 /*** insert to_move after fixed ***/
6423 item_to_move->next = fixed_item->next;
6424 fixed_item->next = item_to_move;
6425 if (tree->last_child == fixed_item) {
6426 tree->last_child = item_to_move;
6431 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
6439 fi = PTREE_FINFO(tree);
6443 start += tvb_raw_offset(tvb);
6444 DISSECTOR_ASSERT(start >= 0);
6445 DISSECTOR_ASSERT(length >= 0);
6447 fi->appendix_start = start;
6448 fi->appendix_length = length;
6452 proto_register_protocol(const char *name, const char *short_name,
6453 const char *filter_name)
6455 protocol_t *protocol;
6456 const protocol_t *existing_protocol = NULL;
6457 header_field_info *hfinfo;
6461 gboolean found_invalid;
6464 * Make sure there's not already a protocol with any of those
6465 * names. Crash if there is, as that's an error in the code
6466 * or an inappropriate plugin.
6467 * This situation has to be fixed to not register more than one
6468 * protocol with the same name.
6471 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_names, name);
6472 if (existing_protocol != NULL) {
6473 /* g_error will terminate the program */
6474 g_error("Duplicate protocol name \"%s\"!"
6475 " This might be caused by an inappropriate plugin or a development error.", name);
6478 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
6479 if (existing_protocol != NULL) {
6480 g_error("Duplicate protocol short_name \"%s\"!"
6481 " This might be caused by an inappropriate plugin or a development error.", short_name);
6484 found_invalid = FALSE;
6485 for (i = 0; filter_name[i]; i++) {
6487 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
6488 found_invalid = TRUE;
6491 if (found_invalid) {
6492 g_error("Protocol filter name \"%s\" has one or more invalid characters."
6493 " Allowed are lower characters, digits, '-', '_' and '.'."
6494 " This might be caused by an inappropriate plugin or a development error.", filter_name);
6496 existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
6497 if (existing_protocol != NULL) {
6498 g_error("Duplicate protocol filter_name \"%s\"!"
6499 " This might be caused by an inappropriate plugin or a development error.", filter_name);
6502 /* Add this protocol to the list of known protocols; the list
6503 is sorted by protocol short name. */
6504 protocol = g_new(protocol_t, 1);
6505 protocol->name = name;
6506 protocol->short_name = short_name;
6507 protocol->filter_name = filter_name;
6508 /*protocol->fields = g_ptr_array_new();*/
6509 /* Delegate until actually needed and use g_ptr_array_sized_new*/
6510 protocol->fields = NULL;
6511 protocol->is_enabled = TRUE; /* protocol is enabled by default */
6512 protocol->enabled_by_default = TRUE; /* see previous comment */
6513 protocol->can_toggle = TRUE;
6514 protocol->parent_proto_id = -1;
6515 protocol->heur_list = NULL;
6516 /* list will be sorted later by name, when all protocols completed registering */
6517 protocols = g_list_prepend(protocols, protocol);
6518 g_hash_table_insert(proto_names, (gpointer)name, protocol);
6519 g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
6520 g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
6522 /* Here we allocate a new header_field_info struct */
6523 hfinfo = g_slice_new(header_field_info);
6524 hfinfo->name = name;
6525 hfinfo->abbrev = filter_name;
6526 hfinfo->type = FT_PROTOCOL;
6527 hfinfo->display = BASE_NONE;
6528 hfinfo->strings = protocol;
6529 hfinfo->bitmask = 0;
6530 hfinfo->ref_type = HF_REF_TYPE_NONE;
6531 hfinfo->blurb = NULL;
6532 hfinfo->parent = -1; /* this field differentiates protos and fields */
6534 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
6535 protocol->proto_id = proto_id;
6540 proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
6542 protocol_t *protocol;
6543 header_field_info *hfinfo;
6546 gboolean found_invalid = FALSE;
6549 * Helper protocols don't need the strict rules as a "regular" protocol
6550 * Just register it in a list and make a hf_ field from it
6552 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
6553 g_error("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name);
6556 if (parent_proto < 0) {
6557 g_error("Must have a valid parent protocol for helper protocol \"%s\"!"
6558 " This might be caused by an inappropriate plugin or a development error.", name);
6561 for (i = 0; filter_name[i]; i++) {
6563 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
6564 found_invalid = TRUE;
6567 if (found_invalid) {
6568 g_error("Protocol filter name \"%s\" has one or more invalid characters."
6569 " Allowed are lower characters, digits, '-', '_' and '.'."
6570 " This might be caused by an inappropriate plugin or a development error.", filter_name);
6573 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
6574 protocol = g_new(protocol_t, 1);
6575 protocol->name = name;
6576 protocol->short_name = short_name;
6577 protocol->filter_name = filter_name;
6578 protocol->fields = NULL;
6580 /* Enabling and toggling is really determined by parent protocol,
6581 but provide default values here */
6582 protocol->is_enabled = TRUE;
6583 protocol->enabled_by_default = TRUE;
6584 protocol->can_toggle = TRUE;
6586 protocol->parent_proto_id = parent_proto;
6587 protocol->heur_list = NULL;
6588 /* list will be sorted later by name, when all protocols completed registering */
6589 pino_protocols = g_list_prepend(pino_protocols, protocol);
6591 /* Here we allocate a new header_field_info struct */
6592 hfinfo = g_slice_new(header_field_info);
6593 hfinfo->name = name;
6594 hfinfo->abbrev = filter_name;
6595 hfinfo->type = field_type;
6596 hfinfo->display = BASE_NONE;
6597 if (field_type == FT_BYTES) {
6598 hfinfo->display |= (BASE_NO_DISPLAY_VALUE|BASE_PROTOCOL_INFO);
6600 hfinfo->strings = protocol;
6601 hfinfo->bitmask = 0;
6602 hfinfo->ref_type = HF_REF_TYPE_NONE;
6603 hfinfo->blurb = NULL;
6604 hfinfo->parent = -1; /* this field differentiates protos and fields */
6606 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
6607 return protocol->proto_id;
6611 proto_deregister_protocol(const char *short_name)
6613 protocol_t *protocol;
6614 header_field_info *hfinfo;
6618 proto_id = proto_get_id_by_short_name(short_name);
6619 protocol = find_protocol_by_id(proto_id);
6620 if (protocol == NULL)
6623 g_hash_table_remove(proto_names, protocol->name);
6624 g_hash_table_remove(proto_short_names, (gpointer)short_name);
6625 g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
6627 if (protocol->fields) {
6628 for (i = 0; i < protocol->fields->len; i++) {
6629 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
6630 hfinfo_remove_from_gpa_name_map(hfinfo);
6631 expert_deregister_expertinfo(hfinfo->abbrev);
6632 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
6634 g_ptr_array_free(protocol->fields, TRUE);
6635 protocol->fields = NULL;
6638 /* Remove this protocol from the list of known protocols */
6639 protocols = g_list_remove(protocols, protocol);
6641 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
6642 g_hash_table_steal(gpa_name_map, protocol->filter_name);
6644 g_free(last_field_name);
6645 last_field_name = NULL;
6651 * Routines to use to iterate over the protocols.
6652 * The argument passed to the iterator routines is an opaque cookie to
6653 * their callers; it's the GList pointer for the current element in
6655 * The ID of the protocol is returned, or -1 if there is no protocol.
6658 proto_get_first_protocol(void **cookie)
6660 protocol_t *protocol;
6662 if (protocols == NULL)
6664 *cookie = protocols;
6665 protocol = (protocol_t *)protocols->data;
6666 return protocol->proto_id;
6670 proto_get_data_protocol(void *cookie)
6672 GList *list_item = (GList *)cookie;
6674 protocol_t *protocol = (protocol_t *)list_item->data;
6675 return protocol->proto_id;
6679 proto_get_next_protocol(void **cookie)
6681 GList *list_item = (GList *)*cookie;
6682 protocol_t *protocol;
6684 list_item = g_list_next(list_item);
6685 if (list_item == NULL)
6687 *cookie = list_item;
6688 protocol = (protocol_t *)list_item->data;
6689 return protocol->proto_id;
6692 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
6693 assume that the cookie stored by
6694 proto_get_(first|next)_protocol_field() will never have a
6695 value of NULL. So, to preserve this semantic, the cookie value
6696 below is adjusted so that the cookie value stored is 1 + the
6697 current (zero-based) array index.
6700 proto_get_first_protocol_field(const int proto_id, void **cookie)
6702 protocol_t *protocol = find_protocol_by_id(proto_id);
6704 if ((protocol == NULL) || (protocol->fields == NULL) || (protocol->fields->len == 0))
6707 *cookie = GUINT_TO_POINTER(0 + 1);
6708 return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
6712 proto_get_next_protocol_field(const int proto_id, void **cookie)
6714 protocol_t *protocol = find_protocol_by_id(proto_id);
6715 guint i = GPOINTER_TO_UINT(*cookie) - 1;
6719 if ((protocol->fields == NULL) || (i >= protocol->fields->len))
6722 *cookie = GUINT_TO_POINTER(i + 1);
6723 return (header_field_info *)g_ptr_array_index(protocol->fields, i);
6727 find_protocol_by_id(const int proto_id)
6729 header_field_info *hfinfo;
6734 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
6735 if (hfinfo->type != FT_PROTOCOL) {
6736 DISSECTOR_ASSERT(hfinfo->display & BASE_PROTOCOL_INFO);
6738 return (protocol_t *)hfinfo->strings;
6742 proto_get_id(const protocol_t *protocol)
6744 return protocol->proto_id;
6748 proto_name_already_registered(const gchar *name)
6750 DISSECTOR_ASSERT_HINT(name, "No name present");
6752 if (g_hash_table_lookup(proto_names, name) != NULL)
6758 proto_get_id_by_filter_name(const gchar *filter_name)
6760 const protocol_t *protocol = NULL;
6762 DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
6764 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
6766 if (protocol == NULL)
6768 return protocol->proto_id;
6772 proto_get_id_by_short_name(const gchar *short_name)
6774 const protocol_t *protocol = NULL;
6776 DISSECTOR_ASSERT_HINT(short_name, "No short name present");
6778 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
6780 if (protocol == NULL)
6782 return protocol->proto_id;
6786 proto_get_protocol_name(const int proto_id)
6788 protocol_t *protocol;
6790 protocol = find_protocol_by_id(proto_id);
6792 if (protocol == NULL)
6794 return protocol->name;
6798 proto_get_protocol_short_name(const protocol_t *protocol)
6800 if (protocol == NULL)
6802 return protocol->short_name;
6806 proto_get_protocol_long_name(const protocol_t *protocol)
6808 if (protocol == NULL)
6810 return protocol->name;
6814 proto_get_protocol_filter_name(const int proto_id)
6816 protocol_t *protocol;
6818 protocol = find_protocol_by_id(proto_id);
6819 if (protocol == NULL)
6821 return protocol->filter_name;
6824 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
6826 heur_dtbl_entry_t* heuristic_dissector;
6828 if (protocol == NULL)
6831 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
6832 if (heuristic_dissector != NULL)
6834 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
6838 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
6840 if (protocol == NULL)
6843 g_list_foreach(protocol->heur_list, func, user_data);
6847 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
6848 gboolean *is_tcp, gboolean *is_udp,
6849 gboolean *is_sctp, gboolean *is_ssl,
6851 gboolean *is_lte_rlc)
6853 wmem_list_frame_t *protos = wmem_list_head(layers);
6855 const char *proto_name;
6857 /* Walk the list of a available protocols in the packet and
6858 find "major" ones. */
6859 /* It might make more sense to assemble and return a bitfield. */
6860 while (protos != NULL)
6862 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6863 proto_name = proto_get_protocol_filter_name(proto_id);
6865 if (is_ip && ((!strcmp(proto_name, "ip")) ||
6866 (!strcmp(proto_name, "ipv6")))) {
6868 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
6870 } else if (is_udp && !strcmp(proto_name, "udp")) {
6872 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
6874 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
6876 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
6878 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
6882 protos = wmem_list_frame_next(protos);
6887 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
6889 wmem_list_frame_t *protos = wmem_list_head(layers);
6893 /* Walk the list of a available protocols in the packet and
6894 find "major" ones. */
6895 /* It might make more sense to assemble and return a bitfield. */
6896 while (protos != NULL)
6898 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6899 name = proto_get_protocol_filter_name(proto_id);
6901 if (!strcmp(name, proto_name))
6906 protos = wmem_list_frame_next(protos);
6913 proto_is_pino(const protocol_t *protocol)
6915 return (protocol->parent_proto_id != -1);
6919 proto_is_protocol_enabled(const protocol_t *protocol)
6921 //parent protocol determines enable/disable for helper dissectors
6922 if (proto_is_pino(protocol))
6923 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
6925 return protocol->is_enabled;
6929 proto_is_protocol_enabled_by_default(const protocol_t *protocol)
6931 //parent protocol determines enable/disable for helper dissectors
6932 if (proto_is_pino(protocol))
6933 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
6935 return protocol->enabled_by_default;
6939 proto_can_toggle_protocol(const int proto_id)
6941 protocol_t *protocol;
6943 protocol = find_protocol_by_id(proto_id);
6944 //parent protocol determines toggling for helper dissectors
6945 if (proto_is_pino(protocol))
6946 return proto_can_toggle_protocol(protocol->parent_proto_id);
6948 return protocol->can_toggle;
6952 proto_disable_by_default(const int proto_id)
6954 protocol_t *protocol;
6956 protocol = find_protocol_by_id(proto_id);
6957 DISSECTOR_ASSERT(protocol->can_toggle);
6958 DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
6959 protocol->is_enabled = FALSE;
6960 protocol->enabled_by_default = FALSE;
6964 proto_set_decoding(const int proto_id, const gboolean enabled)
6966 protocol_t *protocol;
6968 protocol = find_protocol_by_id(proto_id);
6969 DISSECTOR_ASSERT(protocol->can_toggle);
6970 DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
6971 protocol->is_enabled = enabled;
6975 proto_reenable_all(void)
6977 protocol_t *protocol;
6978 GList *list_item = protocols;
6980 if (protocols == NULL)
6984 protocol = (protocol_t *)list_item->data;
6985 if (protocol->can_toggle && protocol->enabled_by_default)
6986 protocol->is_enabled = TRUE;
6987 list_item = g_list_next(list_item);
6992 proto_set_cant_toggle(const int proto_id)
6994 protocol_t *protocol;
6996 protocol = find_protocol_by_id(proto_id);
6997 protocol->can_toggle = FALSE;
7001 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
7003 if (proto != NULL) {
7004 g_ptr_array_add(proto->fields, hfi);
7007 return proto_register_field_init(hfi, parent);
7010 /* for use with static arrays only, since we don't allocate our own copies
7011 of the header_field_info struct contained within the hf_register_info struct */
7013 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
7015 hf_register_info *ptr = hf;
7019 proto = find_protocol_by_id(parent);
7021 if (proto->fields == NULL) {
7022 proto->fields = g_ptr_array_sized_new(num_records);
7025 for (i = 0; i < num_records; i++, ptr++) {
7027 * Make sure we haven't registered this yet.
7028 * Most fields have variables associated with them
7029 * that are initialized to -1; some have array elements,
7030 * or possibly uninitialized variables, so we also allow
7031 * 0 (which is unlikely to be the field ID we get back
7032 * from "proto_register_field_init()").
7034 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
7036 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
7037 ptr->hfinfo.abbrev);
7041 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
7046 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
7051 proto = find_protocol_by_id(parent);
7053 if (proto->fields == NULL) {
7054 proto->fields = g_ptr_array_sized_new(num_records);
7057 for (i = 0; i < num_records; i++) {
7059 * Make sure we haven't registered this yet.
7061 if (hfi[i].id != -1) {
7063 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7068 proto_register_field_common(proto, &hfi[i], parent);
7073 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
7078 proto = find_protocol_by_id(parent);
7080 if (proto->fields == NULL) {
7081 proto->fields = g_ptr_array_sized_new(num_records);
7085 for (i = 0; i < num_records; i++) {
7087 * Make sure we haven't registered this yet.
7089 if (hfi[i]->id != -1) {
7091 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7096 proto_register_field_common(proto, hfi[i], parent);
7100 /* deregister already registered fields */
7102 proto_deregister_field (const int parent, gint hf_id)
7104 header_field_info *hfi;
7108 g_free(last_field_name);
7109 last_field_name = NULL;
7111 if (hf_id == -1 || hf_id == 0)
7114 proto = find_protocol_by_id (parent);
7115 if (!proto || proto->fields == NULL) {
7119 for (i = 0; i < proto->fields->len; i++) {
7120 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
7121 if (hfi->id == hf_id) {
7122 /* Found the hf_id in this protocol */
7123 g_hash_table_steal(gpa_name_map, hfi->abbrev);
7124 g_ptr_array_remove_index_fast(proto->fields, i);
7125 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
7132 proto_add_deregistered_data (void *data)
7134 g_ptr_array_add(deregistered_data, data);
7138 free_deregistered_field (gpointer data, gpointer user_data _U_)
7140 header_field_info *hfi = (header_field_info *) data;
7141 gint hf_id = hfi->id;
7143 g_free((char *)hfi->name);
7144 g_free((char *)hfi->abbrev);
7145 g_free((char *)hfi->blurb);
7148 switch (hfi->type) {
7150 /* This is just an integer represented as a pointer */
7153 protocol_t *protocol = (protocol_t *)hfi->strings;
7154 g_free((gchar *)protocol->short_name);
7158 true_false_string *tf = (true_false_string *)hfi->strings;
7159 g_free ((gchar *)tf->true_string);
7160 g_free ((gchar *)tf->false_string);
7165 if (hfi->display & BASE_UNIT_STRING) {
7166 unit_name_string *unit = (unit_name_string*)hfi->strings;
7167 g_free ((gchar *)unit->singular);
7168 g_free ((gchar *)unit->plural);
7170 val64_string *vs64 = (val64_string *)hfi->strings;
7171 while (vs64->strptr) {
7172 g_free((gchar *)vs64->strptr);
7179 /* Other Integer types */
7180 if (hfi->display & BASE_UNIT_STRING) {
7181 unit_name_string *unit = (unit_name_string*)hfi->strings;
7182 g_free ((gchar *)unit->singular);
7183 g_free ((gchar *)unit->plural);
7185 value_string *vs = (value_string *)hfi->strings;
7186 while (vs->strptr) {
7187 g_free((gchar *)vs->strptr);
7194 if (hfi->type != FT_FRAMENUM) {
7195 g_free((void *)hfi->strings);
7199 if (hfi->parent == -1)
7200 g_slice_free(header_field_info, hfi);
7202 gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
7206 free_deregistered_data (gpointer data, gpointer user_data _U_)
7211 /* free deregistered fields and data */
7213 proto_free_deregistered_fields (void)
7215 expert_free_deregistered_expertinfos();
7217 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
7218 g_ptr_array_free(deregistered_fields, TRUE);
7219 deregistered_fields = g_ptr_array_new();
7221 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
7222 g_ptr_array_free(deregistered_data, TRUE);
7223 deregistered_data = g_ptr_array_new();
7226 /* chars allowed in field abbrev */
7228 const guint8 fld_abbrev_chars[256] = {
7229 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
7230 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
7231 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
7232 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
7233 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
7234 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
7235 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
7236 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
7237 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
7238 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
7239 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
7240 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
7241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
7242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
7243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
7244 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
7247 static const value_string hf_display[] = {
7248 { BASE_NONE, "BASE_NONE" },
7249 { BASE_DEC, "BASE_DEC" },
7250 { BASE_HEX, "BASE_HEX" },
7251 { BASE_OCT, "BASE_OCT" },
7252 { BASE_DEC_HEX, "BASE_DEC_HEX" },
7253 { BASE_HEX_DEC, "BASE_HEX_DEC" },
7254 { BASE_CUSTOM, "BASE_CUSTOM" },
7255 { BASE_NONE|BASE_RANGE_STRING, "BASE_NONE|BASE_RANGE_STRING" },
7256 { BASE_DEC|BASE_RANGE_STRING, "BASE_DEC|BASE_RANGE_STRING" },
7257 { BASE_HEX|BASE_RANGE_STRING, "BASE_HEX|BASE_RANGE_STRING" },
7258 { BASE_OCT|BASE_RANGE_STRING, "BASE_OCT|BASE_RANGE_STRING" },
7259 { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
7260 { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
7261 { BASE_CUSTOM|BASE_RANGE_STRING, "BASE_CUSTOM|BASE_RANGE_STRING" },
7262 { BASE_NONE|BASE_VAL64_STRING, "BASE_NONE|BASE_VAL64_STRING" },
7263 { BASE_DEC|BASE_VAL64_STRING, "BASE_DEC|BASE_VAL64_STRING" },
7264 { BASE_HEX|BASE_VAL64_STRING, "BASE_HEX|BASE_VAL64_STRING" },
7265 { BASE_OCT|BASE_VAL64_STRING, "BASE_OCT|BASE_VAL64_STRING" },
7266 { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
7267 { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
7268 { BASE_CUSTOM|BASE_VAL64_STRING, "BASE_CUSTOM|BASE_VAL64_STRING" },
7269 /* Alias: BASE_NONE { BASE_FLOAT, "BASE_FLOAT" }, */
7270 /* Alias: BASE_NONE { STR_ASCII, "STR_ASCII" }, */
7271 { STR_UNICODE, "STR_UNICODE" },
7272 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
7273 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
7274 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
7275 { BASE_PT_UDP, "BASE_PT_UDP" },
7276 { BASE_PT_TCP, "BASE_PT_TCP" },
7277 { BASE_PT_DCCP, "BASE_PT_DCCP" },
7278 { BASE_PT_SCTP, "BASE_PT_SCTP" },
7279 { BASE_OUI, "BASE_OUI" },
7282 const char* proto_field_display_to_string(int field_display)
7284 return val_to_str_const(field_display, hf_display, "Unknown");
7287 static inline port_type
7288 display_to_port_type(field_display_e e)
7305 /* temporary function containing assert part for easier profiling */
7307 tmp_fld_check_assert(header_field_info *hfinfo)
7311 /* The field must have a name (with length > 0) */
7312 if (!hfinfo->name || !hfinfo->name[0]) {
7314 /* Try to identify the field */
7315 g_error("Field (abbrev='%s') does not have a name\n",
7319 g_error("Field does not have a name (nor an abbreviation)\n");
7322 /* fields with an empty string for an abbreviation aren't filterable */
7323 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
7324 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
7326 /* These types of fields are allowed to have value_strings,
7327 * true_false_strings or a protocol_t struct
7329 if (hfinfo->strings != NULL) {
7330 switch(hfinfo->type) {
7354 //allowed to support string if its a unit decsription
7355 if (hfinfo->display & BASE_UNIT_STRING)
7360 //allowed to support string if its a protocol (for pinos)
7361 if (hfinfo->display & BASE_PROTOCOL_INFO)
7366 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
7367 " (which is not allowed to have strings)\n",
7368 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
7372 /* TODO: This check may slow down startup, and output quite a few warnings.
7373 It would be good to be able to enable this (and possibly other checks?)
7374 in non-release builds. */
7376 /* Check for duplicate value_string values.
7377 There are lots that have the same value *and* string, so for now only
7378 report those that have same value but different string. */
7379 if ((hfinfo->strings != NULL) &&
7380 !(hfinfo->display & BASE_RANGE_STRING) &&
7381 !(FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) &&
7383 (hfinfo->type == FT_CHAR) ||
7384 (hfinfo->type == FT_UINT8) ||
7385 (hfinfo->type == FT_UINT16) ||
7386 (hfinfo->type == FT_UINT24) ||
7387 (hfinfo->type == FT_UINT32) ||
7388 (hfinfo->type == FT_INT8) ||
7389 (hfinfo->type == FT_INT16) ||
7390 (hfinfo->type == FT_INT24) ||
7391 (hfinfo->type == FT_INT32) ||
7392 (hfinfo->type == FT_FRAMENUM) )) {
7395 const value_string *start_values;
7396 const value_string *current;
7398 if (hfinfo->display & BASE_EXT_STRING)
7399 start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
7401 start_values = (const value_string*)hfinfo->strings;
7402 current = start_values;
7404 for (n=0; current; n++, current++) {
7405 /* Drop out if we reached the end. */
7406 if ((current->value == 0) && (current->strptr == NULL)) {
7410 /* Check value against all previous */
7411 for (m=0; m < n; m++) {
7412 /* There are lots of duplicates with the same string,
7413 so only report if different... */
7414 if ((start_values[m].value == current->value) &&
7415 (strcmp(start_values[m].strptr, current->strptr) != 0)) {
7416 ws_g_warning("Field '%s' (%s) has a conflicting entry in its"
7417 " value_string: %u is at indices %u (%s) and %u (%s))\n",
7418 hfinfo->name, hfinfo->abbrev,
7419 current->value, m, start_values[m].strptr, n, current->strptr);
7427 switch (hfinfo->type) {
7430 /* Require the char type to have BASE_HEX, BASE_OCT,
7431 * BASE_CUSTOM, or BASE_NONE as its base.
7433 * If the display value is BASE_NONE and there is a
7434 * strings conversion then the dissector writer is
7435 * telling us that the field's numerical value is
7436 * meaningless; we'll avoid showing the value to the
7439 switch (FIELD_DISPLAY(hfinfo->display)) {
7442 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
7445 if (hfinfo->strings == NULL)
7446 g_error("Field '%s' (%s) is an integral value (%s)"
7447 " but is being displayed as BASE_NONE but"
7448 " without a strings conversion",
7449 hfinfo->name, hfinfo->abbrev,
7450 ftype_name(hfinfo->type));
7453 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7454 g_error("Field '%s' (%s) is a character value (%s)"
7455 " but is being displayed as %s\n",
7456 hfinfo->name, hfinfo->abbrev,
7457 ftype_name(hfinfo->type), tmp_str);
7458 wmem_free(NULL, tmp_str);
7460 if (hfinfo->display & BASE_UNIT_STRING) {
7461 g_error("Field '%s' (%s) is a character value (%s) but has a unit string\n",
7462 hfinfo->name, hfinfo->abbrev,
7463 ftype_name(hfinfo->type));
7474 /* Hexadecimal and octal are, in printf() and everywhere
7475 * else, unsigned so don't allow dissectors to register a
7476 * signed field to be displayed unsigned. (Else how would
7477 * we display negative values?)
7479 switch (FIELD_DISPLAY(hfinfo->display)) {
7484 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7485 g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
7486 hfinfo->name, hfinfo->abbrev,
7487 ftype_name(hfinfo->type), tmp_str);
7488 wmem_free(NULL, tmp_str);
7499 if (IS_BASE_PORT(hfinfo->display)) {
7500 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7501 if (hfinfo->type != FT_UINT16) {
7502 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
7503 hfinfo->name, hfinfo->abbrev,
7504 tmp_str, ftype_name(hfinfo->type));
7506 if (hfinfo->strings != NULL) {
7507 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
7508 hfinfo->name, hfinfo->abbrev,
7509 ftype_name(hfinfo->type), tmp_str);
7511 if (hfinfo->bitmask != 0) {
7512 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
7513 hfinfo->name, hfinfo->abbrev,
7514 ftype_name(hfinfo->type), tmp_str);
7516 wmem_free(NULL, tmp_str);
7520 if (hfinfo->display == BASE_OUI) {
7521 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7522 if (hfinfo->type != FT_UINT24) {
7523 g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s\n",
7524 hfinfo->name, hfinfo->abbrev,
7525 tmp_str, ftype_name(hfinfo->type));
7527 if (hfinfo->strings != NULL) {
7528 g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
7529 hfinfo->name, hfinfo->abbrev,
7530 ftype_name(hfinfo->type), tmp_str);
7532 if (hfinfo->bitmask != 0) {
7533 g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
7534 hfinfo->name, hfinfo->abbrev,
7535 ftype_name(hfinfo->type), tmp_str);
7537 wmem_free(NULL, tmp_str);
7541 /* Require integral types (other than frame number,
7542 * which is always displayed in decimal) to have a
7545 * If the display value is BASE_NONE and there is a
7546 * strings conversion then the dissector writer is
7547 * telling us that the field's numerical value is
7548 * meaningless; we'll avoid showing the value to the
7551 switch (FIELD_DISPLAY(hfinfo->display)) {
7557 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
7560 if (hfinfo->strings == NULL) {
7561 g_error("Field '%s' (%s) is an integral value (%s)"
7562 " but is being displayed as BASE_NONE but"
7563 " without a strings conversion",
7564 hfinfo->name, hfinfo->abbrev,
7565 ftype_name(hfinfo->type));
7567 if (hfinfo->display & BASE_SPECIAL_VALS) {
7568 g_error("Field '%s' (%s) is an integral value (%s)"
7569 " that is being displayed as BASE_NONE but"
7570 " with BASE_SPECIAL_VALS",
7571 hfinfo->name, hfinfo->abbrev,
7572 ftype_name(hfinfo->type));
7577 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7578 g_error("Field '%s' (%s) is an integral value (%s)"
7579 " but is being displayed as %s\n",
7580 hfinfo->name, hfinfo->abbrev,
7581 ftype_name(hfinfo->type), tmp_str);
7582 wmem_free(NULL, tmp_str);
7587 /* Require bytes to have a "display type" that could
7588 * add a character between displayed bytes.
7590 switch (FIELD_DISPLAY(hfinfo->display)) {
7598 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7599 g_error("Field '%s' (%s) is an byte array but is being displayed as %s instead of BASE_NONE, SEP_DOT, SEP_DASH, SEP_COLON, or SEP_SPACE\n",
7600 hfinfo->name, hfinfo->abbrev, tmp_str);
7601 wmem_free(NULL, tmp_str);
7603 if (hfinfo->bitmask != 0)
7604 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7605 hfinfo->name, hfinfo->abbrev,
7606 ftype_name(hfinfo->type));
7607 //allowed to support string if its a protocol (for pinos)
7608 if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_PROTOCOL_INFO)))
7609 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7610 hfinfo->name, hfinfo->abbrev,
7611 ftype_name(hfinfo->type));
7616 if (hfinfo->display != BASE_NONE) {
7617 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7618 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7619 hfinfo->name, hfinfo->abbrev,
7620 ftype_name(hfinfo->type), tmp_str);
7621 wmem_free(NULL, tmp_str);
7623 if (hfinfo->bitmask != 0)
7624 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7625 hfinfo->name, hfinfo->abbrev,
7626 ftype_name(hfinfo->type));
7632 case FT_ABSOLUTE_TIME:
7633 if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
7634 hfinfo->display == ABSOLUTE_TIME_UTC ||
7635 hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
7636 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7637 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
7638 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
7639 wmem_free(NULL, tmp_str);
7641 if (hfinfo->bitmask != 0)
7642 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7643 hfinfo->name, hfinfo->abbrev,
7644 ftype_name(hfinfo->type));
7649 case FT_UINT_STRING:
7651 switch (hfinfo->display) {
7657 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7658 g_error("Field '%s' (%s) is an string value (%s)"
7659 " but is being displayed as %s\n",
7660 hfinfo->name, hfinfo->abbrev,
7661 ftype_name(hfinfo->type), tmp_str);
7662 wmem_free(NULL, tmp_str);
7665 if (hfinfo->bitmask != 0)
7666 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7667 hfinfo->name, hfinfo->abbrev,
7668 ftype_name(hfinfo->type));
7669 if (hfinfo->strings != NULL)
7670 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7671 hfinfo->name, hfinfo->abbrev,
7672 ftype_name(hfinfo->type));
7676 switch (hfinfo->display) {
7682 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7683 g_error("Field '%s' (%s) is an IPv4 value (%s)"
7684 " but is being displayed as %s\n",
7685 hfinfo->name, hfinfo->abbrev,
7686 ftype_name(hfinfo->type), tmp_str);
7687 wmem_free(NULL, tmp_str);
7693 if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
7694 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7695 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7696 hfinfo->name, hfinfo->abbrev,
7697 ftype_name(hfinfo->type),
7699 wmem_free(NULL, tmp_str);
7701 if (hfinfo->bitmask != 0)
7702 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7703 hfinfo->name, hfinfo->abbrev,
7704 ftype_name(hfinfo->type));
7705 if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_UNIT_STRING)))
7706 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7707 hfinfo->name, hfinfo->abbrev,
7708 ftype_name(hfinfo->type));
7711 if (hfinfo->display != BASE_NONE) {
7712 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7713 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7714 hfinfo->name, hfinfo->abbrev,
7715 ftype_name(hfinfo->type),
7717 wmem_free(NULL, tmp_str);
7719 if (hfinfo->bitmask != 0)
7720 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7721 hfinfo->name, hfinfo->abbrev,
7722 ftype_name(hfinfo->type));
7723 if (hfinfo->strings != NULL)
7724 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7725 hfinfo->name, hfinfo->abbrev,
7726 ftype_name(hfinfo->type));
7731 #ifdef ENABLE_CHECK_FILTER
7733 _ftype_common(enum ftenum type)
7757 case FT_UINT_STRING:
7770 case FT_ABSOLUTE_TIME:
7771 case FT_RELATIVE_TIME:
7772 return FT_ABSOLUTE_TIME;
7781 register_type_length_mismatch(void)
7783 static ei_register_info ei[] = {
7784 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
7785 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
7788 expert_module_t* expert_type_length_mismatch;
7790 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
7792 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
7793 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
7795 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
7796 disabling them makes no sense. */
7797 proto_set_cant_toggle(proto_type_length_mismatch);
7801 register_number_string_decoding_error(void)
7803 static ei_register_info ei[] = {
7804 { &ei_number_string_decoding_failed_error,
7805 { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
7806 "Failed to decode number from string", EXPFILL
7809 { &ei_number_string_decoding_erange_error,
7810 { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
7811 "Decoded number from string is out of valid range", EXPFILL
7816 expert_module_t* expert_number_string_decoding_error;
7818 proto_number_string_decoding_error =
7819 proto_register_protocol("Number-String Decoding Error",
7820 "Number-string decoding error",
7821 "_ws.number_string.decoding_error");
7823 expert_number_string_decoding_error =
7824 expert_register_protocol(proto_number_string_decoding_error);
7825 expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
7827 /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
7828 disabling them makes no sense. */
7829 proto_set_cant_toggle(proto_number_string_decoding_error);
7832 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (190000+PRE_ALLOC_EXPERT_FIELDS_MEM)
7834 proto_register_field_init(header_field_info *hfinfo, const int parent)
7837 tmp_fld_check_assert(hfinfo);
7839 hfinfo->parent = parent;
7840 hfinfo->same_name_next = NULL;
7841 hfinfo->same_name_prev_id = -1;
7843 /* if we always add and never delete, then id == len - 1 is correct */
7844 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
7845 if (!gpa_hfinfo.hfi) {
7846 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
7847 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
7849 gpa_hfinfo.allocated_len += 1000;
7850 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
7851 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
7852 /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
7855 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
7857 hfinfo->id = gpa_hfinfo.len - 1;
7859 /* if we have real names, enter this field in the name tree */
7860 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
7862 header_field_info *same_name_next_hfinfo;
7865 /* Check that the filter name (abbreviation) is legal;
7866 * it must contain only alphanumerics, '-', "_", and ".". */
7867 c = check_charset(fld_abbrev_chars, hfinfo->abbrev);
7869 if (g_ascii_isprint(c))
7870 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
7872 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
7873 DISSECTOR_ASSERT_NOT_REACHED();
7876 /* We allow multiple hfinfo's to be registered under the same
7877 * abbreviation. This was done for X.25, as, depending
7878 * on whether it's modulo-8 or modulo-128 operation,
7879 * some bitfield fields may be in different bits of
7880 * a byte, and we want to be able to refer to that field
7881 * with one name regardless of whether the packets
7882 * are modulo-8 or modulo-128 packets. */
7884 same_name_hfinfo = NULL;
7886 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
7887 /* GLIB 2.x - if it is already present
7888 * the previous hfinfo with the same name is saved
7889 * to same_name_hfinfo by value destroy callback */
7890 if (same_name_hfinfo) {
7891 /* There's already a field with this name.
7892 * Put the current field *before* that field
7893 * in the list of fields with this name, Thus,
7894 * we end up with an effectively
7895 * doubly-linked-list of same-named hfinfo's,
7896 * with the head of the list (stored in the
7897 * hash) being the last seen hfinfo.
7899 same_name_next_hfinfo =
7900 same_name_hfinfo->same_name_next;
7902 hfinfo->same_name_next = same_name_next_hfinfo;
7903 if (same_name_next_hfinfo)
7904 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
7906 same_name_hfinfo->same_name_next = hfinfo;
7907 hfinfo->same_name_prev_id = same_name_hfinfo->id;
7908 #ifdef ENABLE_CHECK_FILTER
7909 while (same_name_hfinfo) {
7910 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
7911 fprintf(stderr, "'%s' exists multiple times with NOT compatible types: %s and %s\n", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type));
7912 same_name_hfinfo = same_name_hfinfo->same_name_next;
7922 proto_register_subtree_array(gint *const *indices, const int num_indices)
7925 gint *const *ptr = indices;
7928 * If we've already allocated the array of tree types, expand
7929 * it; this lets plugins such as mate add tree types after
7930 * the initial startup. (If we haven't already allocated it,
7931 * we don't allocate it; on the first pass, we just assign
7932 * ett values and keep track of how many we've assigned, and
7933 * when we're finished registering all dissectors we allocate
7934 * the array, so that we do only one allocation rather than
7935 * wasting CPU time and memory by growing the array for each
7936 * dissector that registers ett values.)
7938 if (tree_is_expanded != NULL) {
7939 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
7941 /* set new items to 0 */
7942 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
7943 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
7944 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
7948 * Assign "num_indices" subtree numbers starting at "num_tree_types",
7949 * returning the indices through the pointers in the array whose
7950 * first element is pointed to by "indices", and update
7951 * "num_tree_types" appropriately.
7953 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
7955 /* g_error will terminate the program */
7956 g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
7957 " This is a development error:"
7958 " Either the subtree item type has already been assigned or"
7959 " was not initialized to -1.");
7961 **ptr = num_tree_types;
7966 label_concat(char *label_str, gsize pos, const char *str)
7968 if (pos < ITEM_LABEL_LENGTH)
7969 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
7975 label_mark_truncated(char *label_str, gsize name_pos)
7977 static const char trunc_str[] = " [truncated]";
7978 const size_t trunc_len = sizeof(trunc_str)-1;
7981 /* ..... field_name: dataaaaaaaaaaaaa
7985 * ..... field_name [truncated]: dataaaaaaaaaaaaa
7987 * name_pos==0 means that we have only data or only a field_name
7990 if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
7991 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
7992 memcpy(label_str + name_pos, trunc_str, trunc_len);
7994 /* in general, label_str is UTF-8
7995 we can truncate it only at the beginning of a new character
7996 we go backwards from the byte right after our buffer and
7997 find the next starting byte of a UTF-8 character, this is
7999 there's no need to use g_utf8_find_prev_char(), the search
8000 will always succeed since we copied trunc_str into the
8002 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH]);
8005 } else if (name_pos < ITEM_LABEL_LENGTH)
8006 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
8010 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
8014 /* "%s: %s", hfinfo->name, text */
8015 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
8016 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
8017 pos = label_concat(label_str, pos, ": ");
8018 pos = label_concat(label_str, pos, text ? text : "(null)");
8021 if (pos >= ITEM_LABEL_LENGTH) {
8022 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8023 label_mark_truncated(label_str, name_pos);
8030 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
8034 /* "%s: %s (%s)", hfinfo->name, text, descr */
8035 name_pos = pos = label_concat(label_str, pos, hfinfo->name);
8036 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
8037 pos = label_concat(label_str, pos, ": ");
8038 if (hfinfo->display & BASE_UNIT_STRING) {
8039 pos = label_concat(label_str, pos, descr ? descr : "(null)");
8040 pos = label_concat(label_str, pos, text ? text : "(null)");
8042 pos = label_concat(label_str, pos, text ? text : "(null)");
8043 pos = label_concat(label_str, pos, " (");
8044 pos = label_concat(label_str, pos, descr ? descr : "(null)");
8045 pos = label_concat(label_str, pos, ")");
8049 if (pos >= ITEM_LABEL_LENGTH) {
8050 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8051 label_mark_truncated(label_str, name_pos);
8058 proto_item_fill_label(field_info *fi, gchar *label_str)
8060 header_field_info *hfinfo;
8074 /* XXX: Check validity of hfinfo->type */
8078 hfinfo = fi->hfinfo;
8080 switch (hfinfo->type) {
8083 g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
8087 fill_label_boolean(fi, label_str);
8092 bytes = (guint8 *)fvalue_get(&fi->value);
8095 switch(hfinfo->display)
8098 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
8101 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
8104 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
8107 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
8111 if (prefs.display_byte_fields_with_spaces)
8113 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
8117 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
8121 label_fill(label_str, 0, hfinfo, str);
8122 wmem_free(NULL, str);
8124 if (hfinfo->display & BASE_ALLOW_ZERO) {
8125 label_fill(label_str, 0, hfinfo, "<none>");
8127 label_fill(label_str, 0, hfinfo, "<MISSING>");
8133 if (hfinfo->bitmask) {
8134 fill_label_bitfield_char(fi, label_str);
8136 fill_label_char(fi, label_str);
8140 /* Four types of integers to take care of:
8141 * Bitfield, with val_string
8142 * Bitfield, w/o val_string
8143 * Non-bitfield, with val_string
8144 * Non-bitfield, w/o val_string
8150 if (hfinfo->bitmask) {
8151 if (fi->flags & FI_VARINT) {
8152 fill_label_bitfield_varint(fi, label_str, FALSE);
8154 fill_label_bitfield(fi, label_str, FALSE);
8157 fill_label_number(fi, label_str, FALSE);
8162 fill_label_number(fi, label_str, FALSE);
8169 if (hfinfo->bitmask) {
8170 if (fi->flags & FI_VARINT) {
8171 fill_label_bitfield_varint64(fi, label_str, FALSE);
8173 fill_label_bitfield64(fi, label_str, FALSE);
8176 fill_label_number64(fi, label_str, FALSE);
8184 if (hfinfo->bitmask) {
8185 if (fi->flags & FI_VARINT) {
8186 fill_label_bitfield_varint(fi, label_str, TRUE);
8188 fill_label_bitfield(fi, label_str, TRUE);
8191 fill_label_number(fi, label_str, TRUE);
8199 if (hfinfo->bitmask) {
8200 if (fi->flags & FI_VARINT) {
8201 fill_label_bitfield_varint64(fi, label_str, TRUE);
8203 fill_label_bitfield64(fi, label_str, TRUE);
8206 fill_label_number64(fi, label_str, TRUE);
8211 double d_value = fvalue_get_floating(&fi->value);
8212 if (hfinfo->display & BASE_UNIT_STRING) {
8213 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8214 "%s: %." G_STRINGIFY(FLT_DIG) "g%s",
8215 hfinfo->name, d_value,
8216 unit_name_string_get_double(d_value, (unit_name_string*)hfinfo->strings));
8218 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8219 "%s: %." G_STRINGIFY(FLT_DIG) "g",
8220 hfinfo->name, d_value);
8226 double d_value = fvalue_get_floating(&fi->value);
8227 if (hfinfo->display & BASE_UNIT_STRING) {
8228 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8229 "%s: %." G_STRINGIFY(DBL_DIG) "g%s",
8230 hfinfo->name, d_value,
8231 unit_name_string_get_double(d_value, (unit_name_string*)hfinfo->strings));
8233 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8234 "%s: %." G_STRINGIFY(DBL_DIG) "g",
8235 hfinfo->name, d_value);
8240 case FT_ABSOLUTE_TIME:
8241 tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
8242 label_fill(label_str, 0, hfinfo, tmp);
8243 wmem_free(NULL, tmp);
8246 case FT_RELATIVE_TIME:
8247 tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
8248 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8249 "%s: %s seconds", hfinfo->name, tmp);
8250 wmem_free(NULL, tmp);
8254 integer = fvalue_get_uinteger(&fi->value);
8255 tmp = get_ipxnet_name(NULL, integer);
8256 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8257 "%s: %s (0x%08X)", hfinfo->name,
8259 wmem_free(NULL, tmp);
8263 addr.type = AT_AX25;
8264 addr.len = AX25_ADDR_LEN;
8265 addr.data = (guint8 *)fvalue_get(&fi->value);
8267 addr_str = (char*)address_to_str(NULL, &addr);
8268 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8269 "%s: %s", hfinfo->name, addr_str);
8270 wmem_free(NULL, addr_str);
8274 addr.type = vines_address_type;
8275 addr.len = VINES_ADDR_LEN;
8276 addr.data = (guint8 *)fvalue_get(&fi->value);
8278 addr_str = (char*)address_to_str(NULL, &addr);
8279 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8280 "%s: %s", hfinfo->name, addr_str);
8281 wmem_free(NULL, addr_str);
8285 bytes = (guint8 *)fvalue_get(&fi->value);
8287 addr.type = AT_ETHER;
8291 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8292 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8293 "%s: %s", hfinfo->name, addr_str);
8294 wmem_free(NULL, addr_str);
8298 ipv4 = fvalue_get_uinteger(&fi->value);
8300 addr.type = AT_IPv4;
8304 if (hfinfo->display == BASE_NETMASK)
8306 addr_str = (char*)address_to_str(NULL, &addr);
8310 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8312 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8313 "%s: %s", hfinfo->name, addr_str);
8314 wmem_free(NULL, addr_str);
8318 bytes = (guint8 *)fvalue_get(&fi->value);
8320 addr.type = AT_IPv6;
8324 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8325 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8326 "%s: %s", hfinfo->name, addr_str);
8327 wmem_free(NULL, addr_str);
8331 addr.type = AT_FCWWN;
8332 addr.len = FCWWN_ADDR_LEN;
8333 addr.data = (guint8 *)fvalue_get(&fi->value);
8335 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8336 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8337 "%s: %s", hfinfo->name, addr_str);
8338 wmem_free(NULL, addr_str);
8342 guid = (e_guid_t *)fvalue_get(&fi->value);
8343 tmp = guid_to_str(NULL, guid);
8344 label_fill(label_str, 0, hfinfo, tmp);
8345 wmem_free(NULL, tmp);
8349 bytes = (guint8 *)fvalue_get(&fi->value);
8350 name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
8351 tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
8353 label_fill_descr(label_str, 0, hfinfo, tmp, name);
8354 wmem_free(NULL, name);
8356 label_fill(label_str, 0, hfinfo, tmp);
8358 wmem_free(NULL, tmp);
8362 bytes = (guint8 *)fvalue_get(&fi->value);
8363 name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
8364 tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
8366 label_fill_descr(label_str, 0, hfinfo, tmp, name);
8367 wmem_free(NULL, name);
8369 label_fill(label_str, 0, hfinfo, tmp);
8371 wmem_free(NULL, tmp);
8375 bytes = (guint8 *)fvalue_get(&fi->value);
8376 tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
8377 label_fill(label_str, 0, hfinfo, tmp);
8378 wmem_free(NULL, tmp);
8382 integer64 = fvalue_get_uinteger64(&fi->value);
8383 addr_str = eui64_to_str(NULL, integer64);
8384 tmp = (char*)eui64_to_display(NULL, integer64);
8385 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
8386 wmem_free(NULL, tmp);
8387 wmem_free(NULL, addr_str);
8391 case FT_UINT_STRING:
8393 bytes = (guint8 *)fvalue_get(&fi->value);
8394 tmp = hfinfo_format_text(hfinfo, bytes);
8395 label_fill(label_str, 0, hfinfo, tmp);
8396 wmem_free(NULL, tmp);
8399 case FT_IEEE_11073_SFLOAT:
8400 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
8401 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8404 wmem_free(NULL, tmp);
8406 case FT_IEEE_11073_FLOAT:
8407 tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
8408 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8411 wmem_free(NULL, tmp);
8415 g_error("hfinfo->type %d (%s) not handled\n",
8416 hfinfo->type, ftype_name(hfinfo->type));
8417 DISSECTOR_ASSERT_NOT_REACHED();
8423 fill_label_boolean(field_info *fi, gchar *label_str)
8425 char *p = label_str;
8426 int bitfield_byte_length = 0, bitwidth;
8427 guint64 unshifted_value;
8430 header_field_info *hfinfo = fi->hfinfo;
8431 const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
8433 if (hfinfo->strings) {
8434 tfstring = (const struct true_false_string*) hfinfo->strings;
8437 value = fvalue_get_uinteger64(&fi->value);
8438 if (hfinfo->bitmask) {
8439 /* Figure out the bit width */
8440 bitwidth = hfinfo_container_bitwidth(hfinfo);
8443 unshifted_value = value;
8444 unshifted_value <<= hfinfo_bitshift(hfinfo);
8446 /* Create the bitfield first */
8447 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8448 bitfield_byte_length = (int) (p - label_str);
8451 /* Fill in the textual info */
8452 label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
8456 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
8458 if (hfinfo->display & BASE_RANGE_STRING)
8459 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
8461 if (hfinfo->display & BASE_EXT_STRING)
8462 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
8464 if (hfinfo->display & BASE_VAL64_STRING)
8465 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
8467 if (hfinfo->display & BASE_UNIT_STRING)
8468 return unit_name_string_get_value(value, (struct unit_name_string*) hfinfo->strings);
8470 return try_val_to_str(value, (const value_string *) hfinfo->strings);
8474 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
8476 if (hfinfo->display & BASE_VAL64_STRING)
8477 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
8479 if (hfinfo->display & BASE_RANGE_STRING)
8480 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
8482 if (hfinfo->display & BASE_UNIT_STRING)
8483 return unit_name_string_get_value64(value, (struct unit_name_string*) hfinfo->strings);
8485 /* If this is reached somebody registered a 64-bit field with a 32-bit
8486 * value-string, which isn't right. */
8487 DISSECTOR_ASSERT_NOT_REACHED();
8489 /* This is necessary to squelch MSVC errors; is there
8490 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
8496 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
8498 const char *str = hf_try_val_to_str(value, hfinfo);
8500 return (str) ? str : unknown_str;
8504 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
8506 const char *str = hf_try_val64_to_str(value, hfinfo);
8508 return (str) ? str : unknown_str;
8511 /* Fills data for bitfield chars with val_strings */
8513 fill_label_bitfield_char(field_info *fi, gchar *label_str)
8516 int bitfield_byte_length, bitwidth;
8517 guint32 unshifted_value;
8523 header_field_info *hfinfo = fi->hfinfo;
8525 /* Figure out the bit width */
8526 bitwidth = hfinfo_container_bitwidth(hfinfo);
8529 value = fvalue_get_uinteger(&fi->value);
8531 unshifted_value = value;
8532 if (hfinfo->bitmask) {
8533 unshifted_value <<= hfinfo_bitshift(hfinfo);
8536 /* Create the bitfield first */
8537 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8538 bitfield_byte_length = (int) (p - label_str);
8540 /* Fill in the textual info using stored (shifted) value */
8541 if (hfinfo->display == BASE_CUSTOM) {
8542 gchar tmp[ITEM_LABEL_LENGTH];
8543 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8545 DISSECTOR_ASSERT(fmtfunc);
8546 fmtfunc(tmp, value);
8547 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8549 else if (hfinfo->strings) {
8550 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8552 out = hfinfo_char_vals_format(hfinfo, buf, value);
8553 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8554 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8556 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8559 out = hfinfo_char_value_format(hfinfo, buf, value);
8561 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8565 /* Fills data for bitfield ints with val_strings */
8567 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
8570 int bitfield_byte_length, bitwidth;
8571 guint32 unshifted_value;
8577 header_field_info *hfinfo = fi->hfinfo;
8579 /* Figure out the bit width */
8580 bitwidth = hfinfo_container_bitwidth(hfinfo);
8584 value = fvalue_get_sinteger(&fi->value);
8586 value = fvalue_get_uinteger(&fi->value);
8588 unshifted_value = value;
8589 if (hfinfo->bitmask) {
8590 unshifted_value <<= hfinfo_bitshift(hfinfo);
8593 /* Create the bitfield first */
8594 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8595 bitfield_byte_length = (int) (p - label_str);
8597 /* Fill in the textual info using stored (shifted) value */
8598 if (hfinfo->display == BASE_CUSTOM) {
8599 gchar tmp[ITEM_LABEL_LENGTH];
8600 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8602 DISSECTOR_ASSERT(fmtfunc);
8603 fmtfunc(tmp, value);
8604 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8606 else if (hfinfo->strings) {
8607 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8609 out = hfinfo_number_vals_format(hfinfo, buf, value);
8610 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8611 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8613 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8616 out = hfinfo_number_value_format(hfinfo, buf, value);
8618 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8623 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
8626 int bitfield_byte_length, bitwidth;
8627 guint64 unshifted_value;
8633 header_field_info *hfinfo = fi->hfinfo;
8635 /* Figure out the bit width */
8636 bitwidth = hfinfo_container_bitwidth(hfinfo);
8640 value = fvalue_get_sinteger64(&fi->value);
8642 value = fvalue_get_uinteger64(&fi->value);
8644 unshifted_value = value;
8645 if (hfinfo->bitmask) {
8646 unshifted_value <<= hfinfo_bitshift(hfinfo);
8649 /* Create the bitfield first */
8650 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8651 bitfield_byte_length = (int) (p - label_str);
8653 /* Fill in the textual info using stored (shifted) value */
8654 if (hfinfo->display == BASE_CUSTOM) {
8655 gchar tmp[ITEM_LABEL_LENGTH];
8656 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
8658 DISSECTOR_ASSERT(fmtfunc64);
8659 fmtfunc64(tmp, value);
8660 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8662 else if (hfinfo->strings) {
8663 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
8665 out = hfinfo_number_vals_format64(hfinfo, buf, value);
8666 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8667 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8669 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8672 out = hfinfo_number_value_format64(hfinfo, buf, value);
8674 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8679 fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed)
8682 int bitfield_byte_length;
8683 guint32 value, unshifted_value;
8687 header_field_info *hfinfo = fi->hfinfo;
8691 value = fvalue_get_sinteger(&fi->value);
8693 value = fvalue_get_uinteger(&fi->value);
8695 unshifted_value = value;
8696 if (hfinfo->bitmask) {
8697 unshifted_value <<= hfinfo_bitshift(hfinfo);
8700 /* Create the bitfield first */
8701 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
8702 bitfield_byte_length = (int) (p - label_str);
8704 /* Fill in the textual info using stored (shifted) value */
8705 if (hfinfo->display == BASE_CUSTOM) {
8706 gchar tmp[ITEM_LABEL_LENGTH];
8707 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8709 DISSECTOR_ASSERT(fmtfunc);
8710 fmtfunc(tmp, value);
8711 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8713 else if (hfinfo->strings) {
8714 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8716 out = hfinfo_number_vals_format(hfinfo, buf, value);
8717 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8718 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8720 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8723 out = hfinfo_number_value_format(hfinfo, buf, value);
8725 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8730 fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed)
8733 int bitfield_byte_length;
8734 guint64 unshifted_value;
8740 header_field_info *hfinfo = fi->hfinfo;
8744 value = fvalue_get_sinteger64(&fi->value);
8746 value = fvalue_get_uinteger64(&fi->value);
8748 unshifted_value = value;
8749 if (hfinfo->bitmask) {
8750 unshifted_value <<= hfinfo_bitshift(hfinfo);
8753 /* Create the bitfield first */
8754 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
8755 bitfield_byte_length = (int) (p - label_str);
8757 /* Fill in the textual info using stored (shifted) value */
8758 if (hfinfo->display == BASE_CUSTOM) {
8759 gchar tmp[ITEM_LABEL_LENGTH];
8760 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
8762 DISSECTOR_ASSERT(fmtfunc64);
8763 fmtfunc64(tmp, value);
8764 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8766 else if (hfinfo->strings) {
8767 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
8769 out = hfinfo_number_vals_format64(hfinfo, buf, value);
8770 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8771 label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8773 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8776 out = hfinfo_number_value_format64(hfinfo, buf, value);
8778 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8783 fill_label_char(field_info *fi, gchar *label_str)
8785 header_field_info *hfinfo = fi->hfinfo;
8791 value = fvalue_get_uinteger(&fi->value);
8793 /* Fill in the textual info */
8794 if (hfinfo->display == BASE_CUSTOM) {
8795 gchar tmp[ITEM_LABEL_LENGTH];
8796 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8798 DISSECTOR_ASSERT(fmtfunc);
8799 fmtfunc(tmp, value);
8800 label_fill(label_str, 0, hfinfo, tmp);
8802 else if (hfinfo->strings) {
8803 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8805 out = hfinfo_char_vals_format(hfinfo, buf, value);
8806 label_fill_descr(label_str, 0, hfinfo, val_str, out);
8809 out = hfinfo_char_value_format(hfinfo, buf, value);
8811 label_fill(label_str, 0, hfinfo, out);
8816 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
8818 header_field_info *hfinfo = fi->hfinfo;
8825 value = fvalue_get_sinteger(&fi->value);
8827 value = fvalue_get_uinteger(&fi->value);
8829 /* Fill in the textual info */
8830 if (hfinfo->display == BASE_CUSTOM) {
8831 gchar tmp[ITEM_LABEL_LENGTH];
8832 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8834 DISSECTOR_ASSERT(fmtfunc);
8835 fmtfunc(tmp, value);
8836 label_fill(label_str, 0, hfinfo, tmp);
8838 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
8840 * It makes no sense to have a value-string table for a
8841 * frame-number field - they're just integers giving
8842 * the ordinal frame number.
8844 const char *val_str = hf_try_val_to_str(value, hfinfo);
8846 out = hfinfo_number_vals_format(hfinfo, buf, value);
8847 if (hfinfo->display & BASE_SPECIAL_VALS) {
8849 * Unique values only display value_string string
8850 * if there is a match. Otherwise it's just a number
8853 label_fill_descr(label_str, 0, hfinfo, val_str, out);
8855 label_fill(label_str, 0, hfinfo, out);
8858 if (val_str == NULL)
8859 val_str = "Unknown";
8861 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8862 label_fill(label_str, 0, hfinfo, val_str);
8864 label_fill_descr(label_str, 0, hfinfo, val_str, out);
8867 else if (IS_BASE_PORT(hfinfo->display)) {
8868 gchar tmp[ITEM_LABEL_LENGTH];
8870 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
8871 display_to_port_type((field_display_e)hfinfo->display), value);
8872 label_fill(label_str, 0, hfinfo, tmp);
8875 out = hfinfo_number_value_format(hfinfo, buf, value);
8877 label_fill(label_str, 0, hfinfo, out);
8882 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
8884 header_field_info *hfinfo = fi->hfinfo;
8891 value = fvalue_get_sinteger64(&fi->value);
8893 value = fvalue_get_uinteger64(&fi->value);
8895 /* Fill in the textual info */
8896 if (hfinfo->display == BASE_CUSTOM) {
8897 gchar tmp[ITEM_LABEL_LENGTH];
8898 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
8900 DISSECTOR_ASSERT(fmtfunc64);
8901 fmtfunc64(tmp, value);
8902 label_fill(label_str, 0, hfinfo, tmp);
8904 else if (hfinfo->strings) {
8905 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
8907 out = hfinfo_number_vals_format64(hfinfo, buf, value);
8908 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8909 label_fill(label_str, 0, hfinfo, val_str);
8911 label_fill_descr(label_str, 0, hfinfo, val_str, out);
8914 out = hfinfo_number_value_format64(hfinfo, buf, value);
8916 label_fill(label_str, 0, hfinfo, out);
8921 hfinfo_bitshift(const header_field_info *hfinfo)
8923 return ws_ctz(hfinfo->bitmask);
8927 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
8929 if (!hfinfo->bitmask) {
8933 /* ilog2 = first set bit, ctz = last set bit */
8934 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
8938 hfinfo_type_bitwidth(enum ftenum type)
8977 DISSECTOR_ASSERT_NOT_REACHED();
8985 hfinfo_container_bitwidth(const header_field_info *hfinfo)
8987 if (!hfinfo->bitmask) {
8991 if (hfinfo->type == FT_BOOLEAN) {
8992 return hfinfo->display; /* hacky? :) */
8995 return hfinfo_type_bitwidth(hfinfo->type);
8999 hfinfo_hex_digits(const header_field_info *hfinfo)
9003 /* If we have a bitmask, hfinfo->type is the width of the container, so not
9004 * appropriate to determine the number of hex digits for the field.
9005 * So instead, we compute it from the bitmask.
9007 if (hfinfo->bitmask != 0) {
9008 bitwidth = hfinfo_mask_bitwidth(hfinfo);
9010 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
9013 /* Divide by 4, rounding up, to get number of hex digits. */
9014 return (bitwidth + 3) / 4;
9018 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
9020 char *ptr = &buf[6];
9021 static const gchar hex_digits[16] =
9022 { '0', '1', '2', '3', '4', '5', '6', '7',
9023 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
9027 /* Properly format value */
9028 if (g_ascii_isprint(value)) {
9030 * Printable, so just show the character, and, if it needs
9031 * to be escaped, escape it.
9034 if (value == '\\' || value == '\'')
9038 * Non-printable; show it as an escape sequence.
9044 * Show a NUL with only one digit.
9078 switch (FIELD_DISPLAY(display)) {
9081 *(--ptr) = (value & 0x7) + '0';
9083 *(--ptr) = (value & 0x7) + '0';
9085 *(--ptr) = (value & 0x7) + '0';
9089 *(--ptr) = hex_digits[value & 0x0F];
9091 *(--ptr) = hex_digits[value & 0x0F];
9096 g_assert_not_reached();
9106 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
9108 char *ptr = &buf[31];
9109 gboolean isint = IS_FT_INT(hfinfo->type);
9112 /* Properly format value */
9113 switch (FIELD_DISPLAY(display)) {
9115 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
9119 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9122 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
9126 return oct_to_str_back(ptr, value);
9129 return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9133 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
9136 ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9143 port_with_resolution_to_str_buf(buf, 32,
9144 display_to_port_type((field_display_e)display), value);
9149 const gchar *manuf_name;
9151 p_oui[0] = value >> 16 & 0xFF;
9152 p_oui[1] = value >> 8 & 0xFF;
9153 p_oui[2] = value & 0xFF;
9155 /* Attempt an OUI lookup. */
9156 manuf_name = uint_get_manuf_name_if_known(value);
9157 if (manuf_name == NULL) {
9158 /* Could not find an OUI. */
9159 g_snprintf(buf, 32, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
9162 /* Found an address string. */
9163 g_snprintf(buf, 32, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
9169 g_assert_not_reached();
9175 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
9177 char *ptr = &buf[47];
9178 gboolean isint = IS_FT_INT(hfinfo->type);
9181 /* Properly format value */
9182 switch (FIELD_DISPLAY(display)) {
9184 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
9188 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9191 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
9195 return oct64_to_str_back(ptr, value);
9198 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9202 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
9205 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9209 g_assert_not_reached();
9215 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9217 int display = hfinfo->display;
9219 if (hfinfo->type == FT_FRAMENUM) {
9221 * Frame numbers are always displayed in decimal.
9226 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
9230 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
9232 int display = hfinfo->display;
9234 if (hfinfo->type == FT_FRAMENUM) {
9236 * Frame numbers are always displayed in decimal.
9241 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
9245 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9247 /* Get the underlying BASE_ value */
9248 int display = FIELD_DISPLAY(hfinfo->display);
9250 return hfinfo_char_value_format_display(display, buf, value);
9254 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9256 /* Get the underlying BASE_ value */
9257 int display = FIELD_DISPLAY(hfinfo->display);
9259 if (hfinfo->type == FT_FRAMENUM) {
9261 * Frame numbers are always displayed in decimal.
9266 if (IS_BASE_PORT(display)) {
9268 } else if (display == BASE_OUI) {
9274 /* case BASE_DEC: */
9276 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
9281 /* case BASE_HEX: */
9287 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
9291 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
9293 /* Get the underlying BASE_ value */
9294 int display = FIELD_DISPLAY(hfinfo->display);
9296 if (hfinfo->type == FT_FRAMENUM) {
9298 * Frame numbers are always displayed in decimal.
9305 /* case BASE_DEC: */
9307 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
9312 /* case BASE_HEX: */
9318 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
9322 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9324 /* Get the underlying BASE_ value */
9325 int display = FIELD_DISPLAY(hfinfo->display);
9327 return hfinfo_char_value_format_display(display, buf, value);
9331 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9333 /* Get the underlying BASE_ value */
9334 int display = FIELD_DISPLAY(hfinfo->display);
9336 if (display == BASE_NONE)
9339 if (display == BASE_DEC_HEX)
9341 if (display == BASE_HEX_DEC)
9344 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
9348 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
9350 /* Get the underlying BASE_ value */
9351 int display = FIELD_DISPLAY(hfinfo->display);
9353 if (display == BASE_NONE)
9356 if (display == BASE_DEC_HEX)
9358 if (display == BASE_HEX_DEC)
9361 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
9365 proto_registrar_get_name(const int n)
9367 header_field_info *hfinfo;
9369 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9370 return hfinfo->name;
9374 proto_registrar_get_abbrev(const int n)
9376 header_field_info *hfinfo;
9378 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9379 return hfinfo->abbrev;
9383 proto_registrar_get_ftype(const int n)
9385 header_field_info *hfinfo;
9387 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9388 return hfinfo->type;
9392 proto_registrar_get_parent(const int n)
9394 header_field_info *hfinfo;
9396 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9397 return hfinfo->parent;
9401 proto_registrar_is_protocol(const int n)
9403 header_field_info *hfinfo;
9405 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9406 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
9409 /* Returns length of field in packet (not necessarily the length
9410 * in our internal representation, as in the case of IPv4).
9411 * 0 means undeterminable at time of registration
9412 * -1 means the field is not registered. */
9414 proto_registrar_get_length(const int n)
9416 header_field_info *hfinfo;
9418 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9419 return ftype_length(hfinfo->type);
9422 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
9423 * it exists anywhere, or FALSE if it exists nowhere. */
9425 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
9427 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
9429 if (g_ptr_array_len(ptrs) > 0) {
9437 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
9438 * This only works if the hfindex was "primed" before the dissection
9439 * took place, as we just pass back the already-created GPtrArray*.
9440 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
9443 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
9448 if (PTREE_DATA(tree)->interesting_hfids != NULL)
9449 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
9450 GINT_TO_POINTER(id));
9456 proto_tracking_interesting_fields(const proto_tree *tree)
9458 GHashTable *interesting_hfids;
9463 interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
9465 return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
9468 /* Helper struct for proto_find_info() and proto_all_finfos() */
9474 /* Helper function for proto_find_info() */
9476 find_finfo(proto_node *node, gpointer data)
9478 field_info *fi = PNODE_FINFO(node);
9479 if (fi && fi->hfinfo) {
9480 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
9481 g_ptr_array_add(((ffdata_t*)data)->array, fi);
9485 /* Don't stop traversing. */
9489 /* Helper function for proto_find_first_info() */
9491 find_first_finfo(proto_node *node, gpointer data)
9493 field_info *fi = PNODE_FINFO(node);
9494 if (fi && fi->hfinfo) {
9495 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
9496 g_ptr_array_add(((ffdata_t*)data)->array, fi);
9498 /* Stop traversing. */
9503 /* Continue traversing. */
9507 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
9508 * This works on any proto_tree, primed or unprimed, but actually searches
9509 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
9510 * The caller does need to free the returned GPtrArray with
9511 * g_ptr_array_free(<array>, TRUE).
9514 proto_find_finfo(proto_tree *tree, const int id)
9518 ffdata.array = g_ptr_array_new();
9521 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
9523 return ffdata.array;
9526 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
9527 * This works on any proto_tree, primed or unprimed, but actually searches
9528 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
9529 * The caller does need to free the returned GPtrArray with
9530 * g_ptr_array_free(<array>, TRUE).
9533 proto_find_first_finfo(proto_tree *tree, const int id)
9537 ffdata.array = g_ptr_array_new();
9540 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
9542 return ffdata.array;
9545 /* Helper function for proto_all_finfos() */
9547 every_finfo(proto_node *node, gpointer data)
9549 field_info *fi = PNODE_FINFO(node);
9550 if (fi && fi->hfinfo) {
9551 g_ptr_array_add(((ffdata_t*)data)->array, fi);
9554 /* Don't stop traversing. */
9558 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
9560 proto_all_finfos(proto_tree *tree)
9564 /* Pre allocate enough space to hold all fields in most cases */
9565 ffdata.array = g_ptr_array_sized_new(512);
9568 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
9570 return ffdata.array;
9581 check_for_offset(proto_node *node, gpointer data)
9583 field_info *fi = PNODE_FINFO(node);
9584 offset_search_t *offsearch = (offset_search_t *)data;
9586 /* !fi == the top most container node which holds nothing */
9587 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
9588 if (offsearch->offset >= (guint) fi->start &&
9589 offsearch->offset < (guint) (fi->start + fi->length)) {
9591 offsearch->finfo = fi;
9592 return FALSE; /* keep traversing */
9595 return FALSE; /* keep traversing */
9598 /* Search a proto_tree backwards (from leaves to root) looking for the field
9599 * whose start/length occupies 'offset' */
9600 /* XXX - I couldn't find an easy way to search backwards, so I search
9601 * forwards, w/o stopping. Therefore, the last finfo I find will the be
9602 * the one I want to return to the user. This algorithm is inefficient
9603 * and could be re-done, but I'd have to handle all the children and
9604 * siblings of each node myself. When I have more time I'll do that.
9607 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
9609 offset_search_t offsearch;
9611 offsearch.offset = offset;
9612 offsearch.finfo = NULL;
9613 offsearch.tvb = tvb;
9615 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
9617 return offsearch.finfo;
9626 check_for_undecoded(proto_node *node, gpointer data)
9628 field_info *fi = PNODE_FINFO(node);
9629 decoded_data_t* decoded = (decoded_data_t*)data;
9634 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
9635 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
9638 decoded->buf[byte] |= (1 << bit);
9646 proto_find_undecoded_data(proto_tree *tree, guint length)
9648 decoded_data_t decoded;
9649 decoded.length = length;
9650 decoded.buf = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
9652 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
9656 /* Dumps the protocols in the registration database to stdout. An independent
9657 * program can take this output and format it into nice tables or HTML or
9660 * There is one record per line. The fields are tab-delimited.
9662 * Field 1 = protocol name
9663 * Field 2 = protocol short name
9664 * Field 3 = protocol filter name
9667 proto_registrar_dump_protocols(void)
9669 protocol_t *protocol;
9671 void *cookie = NULL;
9674 i = proto_get_first_protocol(&cookie);
9676 protocol = find_protocol_by_id(i);
9677 ws_debug_printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
9678 protocol->filter_name);
9679 i = proto_get_next_protocol(&cookie);
9683 /* Dumps the value_strings, extended value string headers, range_strings
9684 * or true/false strings for fields that have them.
9685 * There is one record per line. Fields are tab-delimited.
9686 * There are four types of records: Value String, Extended Value String Header,
9687 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
9688 * the type of record.
9690 * Note that a record will be generated only if the value_string,... is referenced
9691 * in a registered hfinfo entry.
9697 * Field 2 = Field abbreviation to which this value string corresponds
9698 * Field 3 = Integer value
9701 * Extended Value String Headers
9702 * -----------------------------
9704 * Field 2 = Field abbreviation to which this extended value string header corresponds
9705 * Field 3 = Extended Value String "Name"
9706 * Field 4 = Number of entries in the associated value_string array
9707 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
9712 * Field 2 = Field abbreviation to which this range string corresponds
9713 * Field 3 = Integer value: lower bound
9714 * Field 4 = Integer value: upper bound
9717 * True/False Strings
9718 * ------------------
9720 * Field 2 = Field abbreviation to which this true/false string corresponds
9721 * Field 3 = True String
9722 * Field 4 = False String
9725 proto_registrar_dump_values(void)
9727 header_field_info *hfinfo;
9729 const value_string *vals;
9730 const val64_string *vals64;
9731 const range_string *range;
9732 const true_false_string *tfs;
9733 const unit_name_string *units;
9735 len = gpa_hfinfo.len;
9736 for (i = 0; i < len ; i++) {
9737 if (gpa_hfinfo.hfi[i] == NULL)
9738 continue; /* This is a deregistered protocol or field */
9740 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
9742 if (hfinfo->id == hf_text_only) {
9746 /* ignore protocols */
9747 if (proto_registrar_is_protocol(i)) {
9750 /* process header fields */
9751 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
9753 * If this field isn't at the head of the list of
9754 * fields with this name, skip this field - all
9755 * fields with the same name are really just versions
9756 * of the same field stored in different bits, and
9757 * should have the same type/radix/value list, and
9758 * just differ in their bit masks. (If a field isn't
9759 * a bitfield, but can be, say, 1 or 2 bytes long,
9760 * it can just be made FT_UINT16, meaning the
9761 * *maximum* length is 2 bytes, and be used
9764 if (hfinfo->same_name_prev_id != -1)
9773 if (hfinfo->strings != NULL) {
9774 if (FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM &&
9775 (hfinfo->type == FT_CHAR ||
9776 hfinfo->type == FT_UINT8 ||
9777 hfinfo->type == FT_UINT16 ||
9778 hfinfo->type == FT_UINT24 ||
9779 hfinfo->type == FT_UINT32 ||
9780 hfinfo->type == FT_UINT40 ||
9781 hfinfo->type == FT_UINT48 ||
9782 hfinfo->type == FT_UINT56 ||
9783 hfinfo->type == FT_UINT64 ||
9784 hfinfo->type == FT_INT8 ||
9785 hfinfo->type == FT_INT16 ||
9786 hfinfo->type == FT_INT24 ||
9787 hfinfo->type == FT_INT32 ||
9788 hfinfo->type == FT_INT40 ||
9789 hfinfo->type == FT_INT48 ||
9790 hfinfo->type == FT_INT56 ||
9791 hfinfo->type == FT_INT64)) {
9793 if (hfinfo->display & BASE_RANGE_STRING) {
9794 range = (const range_string *)hfinfo->strings;
9795 } else if (hfinfo->display & BASE_EXT_STRING) {
9796 vals = VALUE_STRING_EXT_VS_P((value_string_ext *)hfinfo->strings);
9797 } else if (hfinfo->display & BASE_VAL64_STRING) {
9798 vals64 = (const val64_string *)hfinfo->strings;
9799 } else if (hfinfo->display & BASE_UNIT_STRING) {
9800 units = (const unit_name_string *)hfinfo->strings;
9802 vals = (const value_string *)hfinfo->strings;
9805 else if (hfinfo->type == FT_BOOLEAN) {
9806 tfs = (const struct true_false_string *)hfinfo->strings;
9810 /* Print value strings? */
9812 if (hfinfo->display & BASE_EXT_STRING) {
9813 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
9814 if (!value_string_ext_validate(vse_p)) {
9815 ws_g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
9818 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
9819 ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
9821 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
9822 VALUE_STRING_EXT_VS_NAME(vse_p),
9823 value_string_ext_match_type_str(vse_p));
9826 while (vals[vi].strptr) {
9827 /* Print in the proper base */
9828 if (hfinfo->type == FT_CHAR) {
9829 if (g_ascii_isprint(vals[vi].value)) {
9830 ws_debug_printf("V\t%s\t'%c'\t%s\n",
9835 if (hfinfo->display == BASE_HEX) {
9836 ws_debug_printf("V\t%s\t'\\x%02x'\t%s\n",
9842 ws_debug_printf("V\t%s\t'\\%03o'\t%s\n",
9849 if (hfinfo->display == BASE_HEX) {
9850 ws_debug_printf("V\t%s\t0x%x\t%s\n",
9856 ws_debug_printf("V\t%s\t%u\t%s\n",
9867 while (vals64[vi].strptr) {
9868 ws_debug_printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
9876 /* print range strings? */
9879 while (range[vi].strptr) {
9880 /* Print in the proper base */
9881 if (FIELD_DISPLAY(hfinfo->display) == BASE_HEX) {
9882 ws_debug_printf("R\t%s\t0x%x\t0x%x\t%s\n",
9884 range[vi].value_min,
9885 range[vi].value_max,
9889 ws_debug_printf("R\t%s\t%u\t%u\t%s\n",
9891 range[vi].value_min,
9892 range[vi].value_max,
9899 /* Print true/false strings? */
9901 ws_debug_printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
9902 tfs->true_string, tfs->false_string);
9904 /* Print unit strings? */
9906 ws_debug_printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
9907 units->singular, units->plural ? units->plural : "(no plural)");
9912 /* Prints the number of registered fields.
9913 * Useful for determining an appropriate value for
9914 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
9916 * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
9917 * the number of fields, TRUE otherwise.
9920 proto_registrar_dump_fieldcount(void)
9923 header_field_info *hfinfo;
9924 guint32 deregistered_count = 0;
9925 guint32 same_name_count = 0;
9926 guint32 protocol_count = 0;
9928 for (i = 0; i < gpa_hfinfo.len; i++) {
9929 if (gpa_hfinfo.hfi[i] == NULL) {
9930 deregistered_count++;
9931 continue; /* This is a deregistered protocol or header field */
9934 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
9936 if (proto_registrar_is_protocol(i))
9939 if (hfinfo->same_name_prev_id != -1)
9943 ws_debug_printf("There are %u header fields registered, of which:\n"
9944 "\t%u are deregistered\n"
9945 "\t%u are protocols\n"
9946 "\t%u have the same name as another field\n\n",
9947 gpa_hfinfo.len, deregistered_count, protocol_count,
9950 ws_debug_printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
9951 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
9952 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
9955 ws_debug_printf("The header field table consumes %u KiB of memory.\n",
9956 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
9957 ws_debug_printf("The fields themselves consume %u KiB of memory.\n",
9958 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
9960 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
9964 /* Dumps the contents of the registration database to stdout. An independent
9965 * program can take this output and format it into nice tables or HTML or
9968 * There is one record per line. Each record is either a protocol or a header
9969 * field, differentiated by the first field. The fields are tab-delimited.
9974 * Field 2 = descriptive protocol name
9975 * Field 3 = protocol abbreviation
9980 * Field 2 = descriptive field name
9981 * Field 3 = field abbreviation
9982 * Field 4 = type ( textual representation of the the ftenum type )
9983 * Field 5 = parent protocol abbreviation
9984 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
9985 * Field 7 = bitmask: format: hex: 0x....
9986 * Field 8 = blurb describing field
9989 proto_registrar_dump_fields(void)
9991 header_field_info *hfinfo, *parent_hfinfo;
9993 const char *enum_name;
9994 const char *base_name;
9998 len = gpa_hfinfo.len;
9999 for (i = 0; i < len ; i++) {
10000 if (gpa_hfinfo.hfi[i] == NULL)
10001 continue; /* This is a deregistered protocol or header field */
10003 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10006 * Skip the pseudo-field for "proto_tree_add_text()" since
10007 * we don't want it in the list of filterable fields.
10009 if (hfinfo->id == hf_text_only)
10012 /* format for protocols */
10013 if (proto_registrar_is_protocol(i)) {
10014 ws_debug_printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
10016 /* format for header fields */
10019 * If this field isn't at the head of the list of
10020 * fields with this name, skip this field - all
10021 * fields with the same name are really just versions
10022 * of the same field stored in different bits, and
10023 * should have the same type/radix/value list, and
10024 * just differ in their bit masks. (If a field isn't
10025 * a bitfield, but can be, say, 1 or 2 bytes long,
10026 * it can just be made FT_UINT16, meaning the
10027 * *maximum* length is 2 bytes, and be used
10028 * for all lengths.)
10030 if (hfinfo->same_name_prev_id != -1)
10033 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
10035 enum_name = ftype_name(hfinfo->type);
10038 if (hfinfo->type == FT_CHAR ||
10039 hfinfo->type == FT_UINT8 ||
10040 hfinfo->type == FT_UINT16 ||
10041 hfinfo->type == FT_UINT24 ||
10042 hfinfo->type == FT_UINT32 ||
10043 hfinfo->type == FT_UINT40 ||
10044 hfinfo->type == FT_UINT48 ||
10045 hfinfo->type == FT_UINT56 ||
10046 hfinfo->type == FT_UINT64 ||
10047 hfinfo->type == FT_INT8 ||
10048 hfinfo->type == FT_INT16 ||
10049 hfinfo->type == FT_INT24 ||
10050 hfinfo->type == FT_INT32 ||
10051 hfinfo->type == FT_INT40 ||
10052 hfinfo->type == FT_INT48 ||
10053 hfinfo->type == FT_INT56 ||
10054 hfinfo->type == FT_INT64) {
10056 switch (FIELD_DISPLAY(hfinfo->display)) {
10069 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
10072 base_name = "????";
10075 } else if (hfinfo->type == FT_BOOLEAN) {
10076 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
10077 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
10081 blurb = hfinfo->blurb;
10084 else if (strlen(blurb) == 0)
10087 ws_debug_printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
10088 hfinfo->name, hfinfo->abbrev, enum_name,
10089 parent_hfinfo->abbrev, base_name,
10090 hfinfo->bitmask, blurb);
10095 /* Dumps field types and descriptive names to stdout. An independent
10096 * program can take this output and format it into nice tables or HTML or
10099 * There is one record per line. The fields are tab-delimited.
10101 * Field 1 = field type name, e.g. FT_UINT8
10102 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
10105 proto_registrar_dump_ftypes(void)
10109 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
10110 ws_debug_printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
10114 /* This function indicates whether it's possible to construct a
10115 * "match selected" display filter string for the specified field,
10116 * returns an indication of whether it's possible, and, if it's
10117 * possible and "filter" is non-null, constructs the filter and
10118 * sets "*filter" to point to it.
10119 * You do not need to [g_]free() this string since it will be automatically
10120 * freed once the next packet is dissected.
10123 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
10126 header_field_info *hfinfo;
10130 int dfilter_len, i;
10131 gint start, length, length_remaining;
10133 gchar is_signed_num = FALSE;
10138 hfinfo = finfo->hfinfo;
10139 DISSECTOR_ASSERT(hfinfo);
10140 abbrev_len = (int) strlen(hfinfo->abbrev);
10142 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
10143 const gchar *str = NULL;
10145 switch (hfinfo->type) {
10151 str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
10159 str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
10166 if (str != NULL && filter != NULL) {
10167 *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
10173 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
10174 * functions for FT_UINT and FT_INT types, as we choose the base in
10175 * the string expression based on the display base of the field.
10177 * Note that the base does matter, as this is also used for
10178 * the protocolinfo tap.
10180 * It might be nice to use them in "proto_item_fill_label()"
10181 * as well, although, there, you'd have to deal with the base
10182 * *and* with resolved values for addresses.
10184 * Perhaps we need two different val_to_string routines, one
10185 * to generate items for display filters and one to generate
10186 * strings for display, and pass to both of them the
10187 * "display" and "strings" values in the header_field_info
10188 * structure for the field, so they can get the base and,
10189 * if the field is Boolean or an enumerated integer type,
10190 * the tables used to generate human-readable values.
10192 switch (hfinfo->type) {
10195 if (filter != NULL) {
10201 number = fvalue_get_uinteger(&finfo->value);
10203 out = hfinfo_char_value_format(hfinfo, buf, number);
10205 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
10213 is_signed_num = TRUE;
10220 if (filter != NULL) {
10227 number = fvalue_get_sinteger(&finfo->value);
10229 number = fvalue_get_uinteger(&finfo->value);
10231 out = hfinfo_numeric_value_format(hfinfo, buf, number);
10233 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
10241 is_signed_num = TRUE;
10247 if (filter != NULL) {
10254 number = fvalue_get_sinteger64(&finfo->value);
10256 number = fvalue_get_uinteger64(&finfo->value);
10258 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
10260 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
10265 if (filter != NULL)
10266 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
10271 * If the length is 0, just match the name of the
10274 * (Also check for negative values, just in case,
10275 * as we'll cast it to an unsigned value later.)
10277 length = finfo->length;
10279 if (filter != NULL)
10280 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
10287 * This doesn't have a value, so we'd match
10288 * on the raw bytes at this address.
10290 * Should we be allowed to access to the raw bytes?
10291 * If "edt" is NULL, the answer is "no".
10297 * Is this field part of the raw frame tvbuff?
10298 * If not, we can't use "frame[N:M]" to match
10301 * XXX - should this be frame-relative, or
10302 * protocol-relative?
10304 * XXX - does this fallback for non-registered
10305 * fields even make sense?
10307 if (finfo->ds_tvb != edt->tvb)
10308 return FALSE; /* you lose */
10311 * Don't go past the end of that tvbuff.
10313 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
10314 if (length > length_remaining)
10315 length = length_remaining;
10319 if (filter != NULL) {
10320 start = finfo->start;
10321 buf_len = 32 + length * 3;
10322 *filter = (char *)wmem_alloc0(NULL, buf_len);
10325 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
10326 "frame[%d:%d] == ", finfo->start, length);
10327 for (i=0; i<length; i++) {
10328 c = tvb_get_guint8(finfo->ds_tvb, start);
10331 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
10334 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
10341 /* FT_PCRE never appears as a type for a registered field. It is
10342 * only used internally. */
10343 DISSECTOR_ASSERT_NOT_REACHED();
10346 /* By default, use the fvalue's "to_string_repr" method. */
10348 /* Figure out the string length needed.
10349 * The ft_repr length.
10350 * 4 bytes for " == ".
10351 * 1 byte for trailing NUL.
10353 if (filter != NULL) {
10355 dfilter_len = fvalue_string_repr_len(&finfo->value,
10356 FTREPR_DFILTER, finfo->hfinfo->display);
10357 dfilter_len += abbrev_len + 4 + 1;
10358 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
10360 /* Create the string */
10361 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
10362 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
10363 wmem_free(NULL, str);
10372 * Returns TRUE if we can do a "match selected" on the field, FALSE
10376 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
10378 return construct_match_selected_string(finfo, edt, NULL);
10381 /* This function attempts to construct a "match selected" display filter
10382 * string for the specified field; if it can do so, it returns a pointer
10383 * to the string, otherwise it returns NULL.
10385 * The string is allocated with packet lifetime scope.
10386 * You do not need to [g_]free() this string since it will be automatically
10387 * freed once the next packet is dissected.
10390 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
10392 char *filter = NULL;
10394 if (!construct_match_selected_string(finfo, edt, &filter))
10396 wmem_free(NULL, filter);
10402 /* This function is common code for all proto_tree_add_bitmask... functions.
10406 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
10407 const int len, const gint ett, const int **fields,
10408 const int flags, gboolean first,
10409 gboolean use_parent_tree,
10410 proto_tree* tree, guint64 value)
10413 guint64 available_bits = 0;
10415 header_field_info *hf;
10419 if (len < 0 || len > 8)
10420 g_assert_not_reached();
10421 bitshift = (8 - (guint)len)*8;
10422 available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
10424 if (use_parent_tree == FALSE)
10425 tree = proto_item_add_subtree(item, ett);
10428 guint64 present_bits;
10429 PROTO_REGISTRAR_GET_NTH(**fields,hf);
10430 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
10432 /* Skip fields that aren't fully present */
10433 present_bits = available_bits & hf->bitmask;
10434 if (present_bits != hf->bitmask) {
10439 switch (hf->type) {
10445 proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
10452 proto_tree_add_int(tree, **fields, tvb, offset, len, (gint32)value);
10459 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
10466 proto_tree_add_int64(tree, **fields, tvb, offset, len, (gint64)value);
10470 proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
10474 DISSECTOR_ASSERT_NOT_REACHED();
10477 if (flags & BMT_NO_APPEND) {
10481 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
10483 switch (hf->type) {
10485 if (hf->display == BASE_CUSTOM) {
10486 gchar lbl[ITEM_LABEL_LENGTH];
10487 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
10489 DISSECTOR_ASSERT(fmtfunc);
10490 fmtfunc(lbl, (guint32) tmpval);
10491 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10495 else if (hf->strings) {
10496 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10497 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
10500 else if (!(flags & BMT_NO_INT)) {
10505 proto_item_append_text(item, ", ");
10508 out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
10509 proto_item_append_text(item, "%s: %s", hf->name, out);
10519 if (hf->display == BASE_CUSTOM) {
10520 gchar lbl[ITEM_LABEL_LENGTH];
10521 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
10523 DISSECTOR_ASSERT(fmtfunc);
10524 fmtfunc(lbl, (guint32) tmpval);
10525 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10529 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
10530 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10531 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
10534 else if (!(flags & BMT_NO_INT)) {
10539 proto_item_append_text(item, ", ");
10542 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
10543 if (hf->display & BASE_UNIT_STRING) {
10544 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (unit_name_string*)hf->strings));
10546 proto_item_append_text(item, "%s: %s", hf->name, out);
10557 integer32 = (guint32) tmpval;
10559 no_of_bits = ws_count_ones(hf->bitmask);
10560 integer32 = ws_sign_ext32(integer32, no_of_bits);
10562 if (hf->display == BASE_CUSTOM) {
10563 gchar lbl[ITEM_LABEL_LENGTH];
10564 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
10566 DISSECTOR_ASSERT(fmtfunc);
10567 fmtfunc(lbl, (gint32) integer32);
10568 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10572 else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
10573 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10574 hf->name, hf_try_val_to_str_const((gint32) integer32, hf, "Unknown"));
10577 else if (!(flags & BMT_NO_INT)) {
10582 proto_item_append_text(item, ", ");
10585 out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
10586 if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
10587 proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (unit_name_string*)hf->strings));
10589 proto_item_append_text(item, "%s: %s", hf->name, out);
10600 if (hf->display == BASE_CUSTOM) {
10601 gchar lbl[ITEM_LABEL_LENGTH];
10602 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
10604 DISSECTOR_ASSERT(fmtfunc);
10605 fmtfunc(lbl, tmpval);
10606 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10610 else if (hf->strings) {
10611 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10612 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
10615 else if (!(flags & BMT_NO_INT)) {
10620 proto_item_append_text(item, ", ");
10623 out = hfinfo_number_value_format64(hf, buf, tmpval);
10624 proto_item_append_text(item, "%s: %s", hf->name, out);
10635 no_of_bits = ws_count_ones(hf->bitmask);
10636 tmpval = ws_sign_ext64(tmpval, no_of_bits);
10638 if (hf->display == BASE_CUSTOM) {
10639 gchar lbl[ITEM_LABEL_LENGTH];
10640 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
10642 DISSECTOR_ASSERT(fmtfunc);
10643 fmtfunc(lbl, (gint64) tmpval);
10644 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10648 else if (hf->strings) {
10649 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10650 hf->name, hf_try_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
10653 else if (!(flags & BMT_NO_INT)) {
10658 proto_item_append_text(item, ", ");
10661 out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
10662 proto_item_append_text(item, "%s: %s", hf->name, out);
10669 if (hf->strings && !(flags & BMT_NO_TFS)) {
10670 /* If we have true/false strings, emit full - otherwise messages
10671 might look weird */
10672 const struct true_false_string *tfs =
10673 (const struct true_false_string *)hf->strings;
10676 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10677 hf->name, tfs->true_string);
10679 } else if (!(flags & BMT_NO_FALSE)) {
10680 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10681 hf->name, tfs->false_string);
10684 } else if (hf->bitmask & value) {
10685 /* If the flag is set, show the name */
10686 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
10691 DISSECTOR_ASSERT_NOT_REACHED();
10701 /* This function will dissect a sequence of bytes that describe a
10702 * bitmask and supply the value of that sequence through a pointer.
10703 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
10705 * This field will form an expansion under which the individual fields of the
10706 * bitmask is dissected and displayed.
10707 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
10709 * fields is an array of pointers to int that lists all the fields of the
10710 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
10711 * or another integer of the same type/size as hf_hdr with a mask specified.
10712 * This array is terminated by a NULL entry.
10714 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
10715 * FT_integer fields that have a value_string attached will have the
10716 * matched string displayed on the expansion line.
10719 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
10720 const guint offset, const int hf_hdr,
10721 const gint ett, const int **fields,
10722 const guint encoding, guint64 *retval)
10724 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);
10727 /* This function will dissect a sequence of bytes that describe a
10729 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
10731 * This field will form an expansion under which the individual fields of the
10732 * bitmask is dissected and displayed.
10733 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
10735 * fields is an array of pointers to int that lists all the fields of the
10736 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
10737 * or another integer of the same type/size as hf_hdr with a mask specified.
10738 * This array is terminated by a NULL entry.
10740 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
10741 * FT_integer fields that have a value_string attached will have the
10742 * matched string displayed on the expansion line.
10745 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
10746 const guint offset, const int hf_hdr,
10747 const gint ett, const int **fields,
10748 const guint encoding)
10750 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
10753 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
10754 * what data is appended to the header.
10757 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
10758 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
10761 proto_item *item = NULL;
10762 header_field_info *hf;
10766 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
10767 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
10768 len = ftype_length(hf->type);
10769 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
10772 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
10773 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
10774 flags, FALSE, FALSE, NULL, value);
10779 /* Mask out irrelevant portions */
10780 *retval &= hf->bitmask;
10782 *retval >>= hfinfo_bitshift(hf);
10788 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
10789 * what data is appended to the header.
10792 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
10793 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
10795 proto_item *item = NULL;
10796 header_field_info *hf;
10800 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
10801 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
10804 len = ftype_length(hf->type);
10805 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
10806 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
10807 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
10808 flags, FALSE, FALSE, NULL, value);
10814 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
10815 can't be retrieved directly from tvb) */
10817 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
10818 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
10820 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
10821 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
10824 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
10825 WS_DLL_PUBLIC proto_item *
10826 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
10827 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
10829 proto_item *item = NULL;
10830 header_field_info *hf;
10833 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
10834 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
10835 /* the proto_tree_add_uint/_uint64() calls below
10836 will fail if tvb==NULL and len!=0 */
10837 len = tvb ? ftype_length(hf->type) : 0;
10841 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
10843 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
10845 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
10846 flags, FALSE, FALSE, NULL, value);
10852 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
10854 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
10855 const int len, const int **fields, const guint encoding)
10860 value = get_uint64_value(tree, tvb, offset, len, encoding);
10861 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
10862 BMT_NO_APPEND, FALSE, TRUE, tree, value);
10867 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
10868 const int len, const int **fields, const guint64 value)
10871 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
10872 BMT_NO_APPEND, FALSE, TRUE, tree, value);
10877 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
10878 * This is intended to support bitmask fields whose lengths can vary, perhaps
10879 * as the underlying standard evolves over time.
10880 * With this API there is the possibility of being called to display more or
10881 * less data than the dissector was coded to support.
10882 * In such cases, it is assumed that bitmasks are extended on the MSb end.
10883 * Thus when presented with "too much" or "too little" data, MSbits will be
10884 * ignored or MSfields sacrificed.
10886 * Only fields for which all defined bits are available are displayed.
10889 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
10890 const guint offset, const guint len, const int hf_hdr,
10891 const gint ett, const int **fields, struct expert_field* exp,
10892 const guint encoding)
10894 proto_item *item = NULL;
10895 header_field_info *hf;
10896 guint decodable_len;
10897 guint decodable_offset;
10898 guint32 decodable_value;
10901 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
10902 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
10904 decodable_offset = offset;
10905 decodable_len = MIN(len, (guint) ftype_length(hf->type));
10907 /* If we are ftype_length-limited,
10908 * make sure we decode as many LSBs as possible.
10910 if (encoding == ENC_BIG_ENDIAN) {
10911 decodable_offset += (len - decodable_len);
10915 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
10916 decodable_len, encoding);
10918 /* The root item covers all the bytes even if we can't decode them all */
10919 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
10923 if (decodable_len < len) {
10924 /* Dissector likely requires updating for new protocol revision */
10925 expert_add_info_format(NULL, item, exp,
10926 "Only least-significant %d of %d bytes decoded",
10927 decodable_len, len);
10931 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
10932 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
10933 ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
10939 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
10941 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
10942 const guint offset, const guint len,
10943 const char *name, const char *fallback,
10944 const gint ett, const int **fields,
10945 const guint encoding, const int flags)
10947 proto_item *item = NULL;
10951 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
10952 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
10953 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
10954 flags, TRUE, FALSE, NULL, value) && fallback) {
10955 /* Still at first item - append 'fallback' text if any */
10956 proto_item_append_text(item, "%s", fallback);
10964 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10965 const guint bit_offset, const gint no_of_bits,
10966 const guint encoding)
10968 header_field_info *hfinfo;
10972 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
10974 octet_length = (no_of_bits + 7) >> 3;
10975 octet_offset = bit_offset >> 3;
10976 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
10978 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
10979 * but only after doing a bunch more work (which we can, in the common
10980 * case, shortcut here).
10982 CHECK_FOR_NULL_TREE(tree);
10983 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
10985 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
10989 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
10990 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
10991 * Offset should be given in bits from the start of the tvb.
10994 static proto_item *
10995 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
10996 const guint bit_offset, const gint no_of_bits,
10997 guint64 *return_value, const guint encoding)
11001 guint8 tot_no_bits;
11003 char lbl_str[ITEM_LABEL_LENGTH];
11007 header_field_info *hf_field;
11009 const true_false_string *tfstring;
11011 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
11012 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
11014 if (hf_field->bitmask != 0) {
11015 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
11016 "Incompatible use of proto_tree_add_bits_ret_val"
11017 " with field '%s' (%s) with bitmask != 0",
11018 hf_field->abbrev, hf_field->name));
11021 DISSECTOR_ASSERT(no_of_bits > 0);
11023 /* Byte align offset */
11024 offset = bit_offset>>3;
11027 * Calculate the number of octets used to hold the bits
11029 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
11030 length = (tot_no_bits + 7) >> 3;
11032 if (no_of_bits < 65) {
11033 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
11035 DISSECTOR_ASSERT_NOT_REACHED();
11039 /* Sign extend for signed types */
11040 switch (hf_field->type) {
11049 value = ws_sign_ext64(value, no_of_bits);
11056 if (return_value) {
11057 *return_value = value;
11060 /* Coast clear. Try and fake it */
11061 CHECK_FOR_NULL_TREE(tree);
11062 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11064 bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
11066 switch (hf_field->type) {
11068 /* Boolean field */
11069 tfstring = (const true_false_string *) &tfs_true_false;
11070 if (hf_field->strings)
11071 tfstring = (const true_false_string *)hf_field->strings;
11072 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
11074 bf_str, hf_field->name,
11075 (guint64)value ? tfstring->true_string : tfstring->false_string);
11079 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
11080 fill_label_char(PITEM_FINFO(pi), lbl_str);
11087 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
11088 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
11095 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
11096 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
11103 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
11104 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
11111 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
11112 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
11116 DISSECTOR_ASSERT_NOT_REACHED();
11121 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
11126 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11127 const guint bit_offset, const crumb_spec_t *crumb_spec,
11128 guint64 *return_value)
11133 guint mask_initial_bit_offset;
11134 guint mask_greatest_bit_offset;
11135 guint octet_length;
11138 char lbl_str[ITEM_LABEL_LENGTH];
11140 guint64 composite_bitmask;
11141 guint64 composite_bitmap;
11143 header_field_info *hf_field;
11144 const true_false_string *tfstring;
11146 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
11147 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
11149 if (hf_field->bitmask != 0) {
11150 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
11151 "Incompatible use of proto_tree_add_split_bits_item_ret_val"
11152 " with field '%s' (%s) with bitmask != 0",
11153 hf_field->abbrev, hf_field->name));
11156 mask_initial_bit_offset = bit_offset % 8;
11161 mask_greatest_bit_offset = 0;
11162 composite_bitmask = 0;
11163 composite_bitmap = 0;
11165 while (crumb_spec[i].crumb_bit_length != 0) {
11166 guint64 crumb_mask, crumb_value;
11167 guint8 crumb_end_bit_offset;
11169 DISSECTOR_ASSERT(i < 64);
11170 crumb_value = tvb_get_bits64(tvb,
11171 bit_offset + crumb_spec[i].crumb_bit_offset,
11172 crumb_spec[i].crumb_bit_length,
11174 value += crumb_value;
11175 no_of_bits += crumb_spec[i].crumb_bit_length;
11177 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
11178 octet containing the initial offset.
11179 If the mask is beyond 32 bits, then give up on bit map display.
11180 This could be improved in future, probably showing a table
11181 of 32 or 64 bits per row */
11182 if (mask_greatest_bit_offset < 32) {
11183 crumb_end_bit_offset = mask_initial_bit_offset
11184 + crumb_spec[i].crumb_bit_offset
11185 + crumb_spec[i].crumb_bit_length;
11186 crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
11188 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
11189 mask_greatest_bit_offset = crumb_end_bit_offset;
11191 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
11192 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
11194 /* Shift left for the next segment */
11195 value <<= crumb_spec[++i].crumb_bit_length;
11198 /* Sign extend for signed types */
11199 switch (hf_field->type) {
11208 value = ws_sign_ext64(value, no_of_bits);
11214 if (return_value) {
11215 *return_value = value;
11218 /* Coast clear. Try and fake it */
11219 CHECK_FOR_NULL_TREE(tree);
11220 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11222 /* initialise the format string */
11225 octet_offset = bit_offset >> 3;
11227 /* Round up mask length to nearest octet */
11228 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
11229 mask_greatest_bit_offset = octet_length << 3;
11231 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
11232 It would be a useful enhancement to eliminate this restriction. */
11233 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
11234 other_decode_bitfield_value(bf_str,
11235 (guint32)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
11236 (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
11237 mask_greatest_bit_offset);
11240 switch (hf_field->type) {
11241 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
11242 /* Boolean field */
11243 tfstring = (const true_false_string *) &tfs_true_false;
11244 if (hf_field->strings)
11245 tfstring = (const true_false_string *) hf_field->strings;
11246 return proto_tree_add_boolean_format(tree, hfindex,
11247 tvb, octet_offset, octet_length, (guint32)value,
11249 bf_str, hf_field->name,
11250 (guint64)value ? tfstring->true_string : tfstring->false_string);
11254 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
11255 fill_label_char(PITEM_FINFO(pi), lbl_str);
11262 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
11263 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
11270 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
11271 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
11278 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
11279 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
11286 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
11287 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
11291 DISSECTOR_ASSERT_NOT_REACHED();
11295 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
11300 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
11301 const crumb_spec_t *crumb_spec, guint16 crumb_index)
11303 header_field_info *hfinfo;
11305 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
11306 proto_tree_add_text_internal(tree, tvb,
11308 ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
11309 "%s crumb %d of %s (decoded above)",
11310 decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
11313 crumb_spec[crumb_index].crumb_bit_length,
11320 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11321 const guint bit_offset, const gint no_of_bits,
11322 guint64 *return_value, const guint encoding)
11326 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
11327 bit_offset, no_of_bits,
11328 return_value, encoding))) {
11329 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
11330 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
11335 static proto_item *
11336 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
11337 tvbuff_t *tvb, const guint bit_offset,
11338 const gint no_of_bits, void *value_ptr,
11343 guint8 tot_no_bits;
11346 header_field_info *hf_field;
11348 /* We do not have to return a value, try to fake it as soon as possible */
11349 CHECK_FOR_NULL_TREE(tree);
11350 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11352 if (hf_field->bitmask != 0) {
11353 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
11354 "Incompatible use of proto_tree_add_bits_format_value"
11355 " with field '%s' (%s) with bitmask != 0",
11356 hf_field->abbrev, hf_field->name));
11359 DISSECTOR_ASSERT(no_of_bits > 0);
11361 /* Byte align offset */
11362 offset = bit_offset>>3;
11365 * Calculate the number of octets used to hold the bits
11367 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
11368 length = tot_no_bits>>3;
11369 /* If we are using part of the next octet, increase length by 1 */
11370 if (tot_no_bits & 0x07)
11373 if (no_of_bits < 65) {
11374 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
11376 DISSECTOR_ASSERT_NOT_REACHED();
11380 str = decode_bits_in_field(bit_offset, no_of_bits, value);
11382 g_strlcat(str, " = ", 256+64);
11383 g_strlcat(str, hf_field->name, 256+64);
11386 * This function does not receive an actual value but a dimensionless pointer to that value.
11387 * For this reason, the type of the header field is examined in order to determine
11388 * what kind of value we should read from this address.
11389 * The caller of this function must make sure that for the specific header field type the address of
11390 * a compatible value is provided.
11392 switch (hf_field->type) {
11394 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
11395 "%s: %s", str, value_str);
11403 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
11404 "%s: %s", str, value_str);
11411 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
11412 "%s: %s", str, value_str);
11419 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
11420 "%s: %s", str, value_str);
11427 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
11428 "%s: %s", str, value_str);
11432 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
11433 "%s: %s", str, value_str);
11437 DISSECTOR_ASSERT_NOT_REACHED();
11443 static proto_item *
11444 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
11445 tvbuff_t *tvb, const guint bit_offset,
11446 const gint no_of_bits, void *value_ptr,
11451 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
11452 tvb, bit_offset, no_of_bits,
11453 value_ptr, value_str))) {
11454 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
11455 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
11460 #define CREATE_VALUE_STRING(dst,format,ap) \
11461 va_start(ap, format); \
11462 dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
11466 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
11467 tvbuff_t *tvb, const guint bit_offset,
11468 const gint no_of_bits, guint32 value,
11469 const char *format, ...)
11473 header_field_info *hf_field;
11475 CHECK_FOR_NULL_TREE(tree);
11477 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11479 switch (hf_field->type) {
11487 DISSECTOR_ASSERT_NOT_REACHED();
11492 CREATE_VALUE_STRING(dst, format, ap);
11494 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11498 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
11499 tvbuff_t *tvb, const guint bit_offset,
11500 const gint no_of_bits, guint64 value,
11501 const char *format, ...)
11505 header_field_info *hf_field;
11507 CHECK_FOR_NULL_TREE(tree);
11509 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11511 switch (hf_field->type) {
11519 DISSECTOR_ASSERT_NOT_REACHED();
11524 CREATE_VALUE_STRING(dst, format, ap);
11526 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11530 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
11531 tvbuff_t *tvb, const guint bit_offset,
11532 const gint no_of_bits, float value,
11533 const char *format, ...)
11537 header_field_info *hf_field;
11539 CHECK_FOR_NULL_TREE(tree);
11541 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11543 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
11545 CREATE_VALUE_STRING(dst, format, ap);
11547 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11551 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
11552 tvbuff_t *tvb, const guint bit_offset,
11553 const gint no_of_bits, gint32 value,
11554 const char *format, ...)
11558 header_field_info *hf_field;
11560 CHECK_FOR_NULL_TREE(tree);
11562 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11564 switch (hf_field->type) {
11572 DISSECTOR_ASSERT_NOT_REACHED();
11577 CREATE_VALUE_STRING(dst, format, ap);
11579 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11583 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
11584 tvbuff_t *tvb, const guint bit_offset,
11585 const gint no_of_bits, gint64 value,
11586 const char *format, ...)
11590 header_field_info *hf_field;
11592 CHECK_FOR_NULL_TREE(tree);
11594 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11596 switch (hf_field->type) {
11604 DISSECTOR_ASSERT_NOT_REACHED();
11609 CREATE_VALUE_STRING(dst, format, ap);
11611 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11615 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
11616 tvbuff_t *tvb, const guint bit_offset,
11617 const gint no_of_bits, guint32 value,
11618 const char *format, ...)
11622 header_field_info *hf_field;
11624 CHECK_FOR_NULL_TREE(tree);
11626 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11628 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
11630 CREATE_VALUE_STRING(dst, format, ap);
11632 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11636 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
11637 tvbuff_t *tvb, const guint bit_offset,
11638 const gint no_of_bits, guint64 value,
11639 const char *format, ...)
11643 header_field_info *hf_field;
11645 CHECK_FOR_NULL_TREE(tree);
11647 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11649 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
11651 CREATE_VALUE_STRING(dst, format, ap);
11653 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11657 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11658 const guint bit_offset, const gint no_of_chars)
11661 header_field_info *hfinfo;
11666 CHECK_FOR_NULL_TREE(tree);
11668 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
11670 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
11672 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
11673 byte_offset = bit_offset >> 3;
11675 string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
11677 if (hfinfo->display == STR_UNICODE) {
11678 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
11681 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
11682 DISSECTOR_ASSERT(byte_length >= 0);
11683 proto_tree_set_string(PNODE_FINFO(pi), string);
11689 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11690 const guint bit_offset, const gint no_of_chars)
11693 header_field_info *hfinfo;
11698 CHECK_FOR_NULL_TREE(tree);
11700 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
11702 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
11704 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
11705 byte_offset = bit_offset >> 3;
11707 string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
11709 if (hfinfo->display == STR_UNICODE) {
11710 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
11713 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
11714 DISSECTOR_ASSERT(byte_length >= 0);
11715 proto_tree_set_string(PNODE_FINFO(pi), string);
11720 const value_string proto_checksum_vals[] = {
11721 { PROTO_CHECKSUM_E_BAD, "Bad" },
11722 { PROTO_CHECKSUM_E_GOOD, "Good" },
11723 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
11724 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
11730 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
11731 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
11732 packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
11734 header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
11737 proto_item* ti = NULL;
11739 gboolean incorrect_checksum = TRUE;
11741 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
11743 if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
11744 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, 0, 0, "[missing]");
11745 PROTO_ITEM_SET_GENERATED(ti);
11746 if (hf_checksum_status != -1) {
11747 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_NOT_PRESENT);
11748 PROTO_ITEM_SET_GENERATED(ti2);
11753 switch (hfinfo->type){
11767 DISSECTOR_ASSERT_NOT_REACHED();
11770 if (flags & PROTO_CHECKSUM_GENERATED) {
11771 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, 0, computed_checksum);
11772 PROTO_ITEM_SET_GENERATED(ti);
11774 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
11775 if (flags & PROTO_CHECKSUM_VERIFY) {
11776 if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
11777 if (computed_checksum == 0) {
11778 proto_item_append_text(ti, " [correct]");
11779 if (hf_checksum_status != -1) {
11780 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
11781 PROTO_ITEM_SET_GENERATED(ti2);
11783 incorrect_checksum = FALSE;
11784 } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
11785 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
11788 if (checksum == computed_checksum) {
11789 proto_item_append_text(ti, " [correct]");
11790 if (hf_checksum_status != -1) {
11791 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
11792 PROTO_ITEM_SET_GENERATED(ti2);
11794 incorrect_checksum = FALSE;
11798 if (incorrect_checksum) {
11799 if (hf_checksum_status != -1) {
11800 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
11801 PROTO_ITEM_SET_GENERATED(ti2);
11803 if (flags & PROTO_CHECKSUM_ZERO) {
11804 proto_item_append_text(ti, " [incorrect]");
11805 if (bad_checksum_expert != NULL)
11806 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum");
11808 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
11809 if (bad_checksum_expert != NULL)
11810 expert_add_info_format(pinfo, ti, bad_checksum_expert, "Bad checksum [should be 0x%0*x]", len*2, computed_checksum);
11814 if (hf_checksum_status != -1) {
11815 proto_item_append_text(ti, " [unverified]");
11816 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
11817 PROTO_ITEM_SET_GENERATED(ti2);
11826 proto_check_field_name(const gchar *field_name)
11828 return check_charset(fld_abbrev_chars, field_name);
11832 tree_expanded(int tree_type)
11834 g_assert(tree_type >= 0 && tree_type < num_tree_types);
11835 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
11839 tree_expanded_set(int tree_type, gboolean value)
11841 g_assert(tree_type >= 0 && tree_type < num_tree_types);
11844 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
11846 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
11850 * Editor modelines - http://www.wireshark.org/tools/modelines.html
11853 * c-basic-offset: 8
11855 * indent-tabs-mode: t
11858 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
11859 * :indentSize=8:tabSize=8:noTabs=false: