Replace g_log() calls with ws_log()
[metze/wireshark/wip.git] / epan / proto.c
1 /* proto.c
2  * Routines for protocol tree
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "config.h"
12 #define WS_LOG_DOMAIN LOG_DOMAIN_EPAN
13
14 #include <stdio.h>
15 #include <string.h>
16 #include <glib.h>
17 #include <float.h>
18 #include <errno.h>
19
20 #include <wsutil/bits_ctz.h>
21 #include <wsutil/bits_count_ones.h>
22 #include <wsutil/sign_ext.h>
23 #include <wsutil/utf8_entities.h>
24 #include <wsutil/json_dumper.h>
25 #include <wsutil/wslog.h>
26
27 #include <ftypes/ftypes-int.h>
28
29 #include "packet.h"
30 #include "exceptions.h"
31 #include "ptvcursor.h"
32 #include "strutil.h"
33 #include "addr_resolv.h"
34 #include "address_types.h"
35 #include "oids.h"
36 #include "proto.h"
37 #include "epan_dissect.h"
38 #include "tvbuff.h"
39 #include "wmem/wmem.h"
40 #include "charsets.h"
41 #include "column-utils.h"
42 #include "to_str-int.h"
43 #include "to_str.h"
44 #include "osi-utils.h"
45 #include "expert.h"
46 #include "show_exception.h"
47 #include "in_cksum.h"
48 #include "register-int.h"
49
50 #include <wsutil/crash_info.h>
51 #include <wsutil/epochs.h>
52
53 /* Ptvcursor limits */
54 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
55 #define SUBTREE_MAX_LEVELS 256
56
57 typedef struct __subtree_lvl {
58         gint        cursor_offset;
59         proto_item *it;
60         proto_tree *tree;
61 } subtree_lvl;
62
63 struct ptvcursor {
64         subtree_lvl *pushed_tree;
65         guint8       pushed_tree_index;
66         guint8       pushed_tree_max;
67         proto_tree  *tree;
68         tvbuff_t    *tvb;
69         gint         offset;
70 };
71
72 #define cVALS(x) (const value_string*)(x)
73
74 /** See inlined comments.
75  @param tree the tree to append this item to
76  @param free_block a code block to call to free resources if this returns
77  @return NULL if 'tree' is null */
78 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)                  \
79         if (!tree) {                                                    \
80                 free_block;                                             \
81                 return NULL;                                            \
82         }
83
84 /** See inlined comments.
85  @param tree the tree to append this item to
86  @param free_block a code block to call to free resources if this returns
87  @return NULL if 'tree' is null */
88 #define CHECK_FOR_NULL_TREE(tree) \
89         CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
90
91 /** See inlined comments.
92  @param tree the tree to append this item to
93  @param hfindex field index
94  @param hfinfo header_field
95  @param free_block a code block to call to free resources if this returns
96  @return the header field matching 'hfinfo' */
97 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
98         /* If this item is not referenced we don't have to do much work \
99            at all but we should still return a node so that field items \
100            below this node (think proto_item_add_subtree()) will still  \
101            have somewhere to attach to or else filtering will not work  \
102            (they would be ignored since tree would be NULL).            \
103            DON'T try to fake a node where PTREE_FINFO(tree) is NULL     \
104            since dissectors that want to do proto_item_set_len() or     \
105            other operations that dereference this would crash.          \
106            We fake FT_PROTOCOL unless some clients have requested us    \
107            not to do so.                                                \
108         */                                                              \
109         PTREE_DATA(tree)->count++;                                      \
110         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);                       \
111         if (PTREE_DATA(tree)->count > prefs.gui_max_tree_items) {                       \
112                 free_block;                                             \
113                 if (wireshark_abort_on_too_many_items) \
114                         ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \
115                             hfinfo->abbrev, prefs.gui_max_tree_items);  \
116                 /* Let the exception handler add items to the tree */   \
117                 PTREE_DATA(tree)->count = 0;                            \
118                 THROW_MESSAGE(DissectorError,                           \
119                         wmem_strdup_printf(wmem_packet_scope(),         \
120                             "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \
121                             hfinfo->abbrev, prefs.gui_max_tree_items)); \
122         }                                                               \
123         if (!(PTREE_DATA(tree)->visible)) {                             \
124                 if (PTREE_FINFO(tree)) {                                \
125                         if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT)    \
126                             && (hfinfo->type != FT_PROTOCOL ||          \
127                                 PTREE_DATA(tree)->fake_protocols)) {    \
128                                 free_block;                             \
129                                 /* just return tree back to the caller */\
130                                 return tree;                            \
131                         }                                               \
132                 }                                                       \
133         }
134
135 /** See inlined comments.
136  @param tree the tree to append this item to
137  @param hfindex field index
138  @param hfinfo header_field
139  @return the header field matching 'hfinfo' */
140 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
141         TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
142
143
144 /** See inlined comments.
145  @param pi the created protocol item we're about to return */
146 #define TRY_TO_FAKE_THIS_REPR(pi)       \
147         g_assert(pi);                   \
148         if (!(PTREE_DATA(pi)->visible)) { \
149                 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
150                  * items string representation */ \
151                 return pi; \
152         }
153 /* Same as above but returning void */
154 #define TRY_TO_FAKE_THIS_REPR_VOID(pi)  \
155         if (!pi)                        \
156                 return;                 \
157         if (!(PTREE_DATA(pi)->visible)) { \
158                 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
159                  * items string representation */ \
160                 return; \
161         }
162 /* Similar to above, but allows a NULL tree */
163 #define TRY_TO_FAKE_THIS_REPR_NESTED(pi)        \
164         if ((pi == NULL) || (!(PTREE_DATA(pi)->visible))) { \
165                 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
166                  * items string representation */ \
167                 return pi; \
168         }
169
170 #ifdef ENABLE_CHECK_FILTER
171 #define CHECK_HF_VALUE(type, modifier, start_values) \
172 { \
173         const type *current; \
174         int n, m; \
175         current = start_values; \
176         for (n=0; current; n++, current++) { \
177                 /* Drop out if we reached the end. */ \
178                 if ((current->value == 0) && (current->strptr == NULL)) { \
179                         break; \
180                 } \
181                 /* Check value against all previous */ \
182                 for (m=0; m < n; m++) { \
183                         /* There are lots of duplicates with the same string, \
184                            so only report if different... */ \
185                         if ((start_values[m].value == current->value) && \
186                             (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
187                                 ws_warning("Field '%s' (%s) has a conflicting entry in its" \
188                                           " value_string: %" modifier "u is at indices %u (%s) and %u (%s)", \
189                                           hfinfo->name, hfinfo->abbrev, \
190                                           current->value, m, start_values[m].strptr, n, current->strptr); \
191                         } \
192                 } \
193         } \
194 }
195 #endif
196
197
198 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
199 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
200 static int hfinfo_bitoffset(const header_field_info *hfinfo);
201 static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
202 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
203
204 static void label_mark_truncated(char *label_str, gsize name_pos);
205 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
206
207 static void fill_label_boolean(field_info *fi, gchar *label_str);
208 static void fill_label_bitfield_char(field_info *fi, gchar *label_str);
209 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
210 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
211 static void fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed);
212 static void fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed);
213 static void fill_label_char(field_info *fi, gchar *label_str);
214 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
215 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
216
217 static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value);
218 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
219 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
220 static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
221 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
222 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
223 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
224 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
225 static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
226 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
227 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
228
229 static void proto_cleanup_base(void);
230
231 static proto_item *
232 proto_tree_add_node(proto_tree *tree, field_info *fi);
233
234 static void
235 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
236                 gint *item_length, const guint encoding);
237
238 static gint
239 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
240                 gint length, guint item_length, const gint encoding);
241
242 static field_info *
243 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
244                const gint start, const gint item_length);
245
246 static proto_item *
247 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
248                   gint start, gint *length);
249
250 static void
251 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
252 static void
253 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
254
255 static void
256 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
257 static void
258 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
259 static void
260 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
261 static void
262 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
263 static void
264 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
265 static void
266 proto_tree_set_string(field_info *fi, const char* value);
267 static void
268 proto_tree_set_ax25(field_info *fi, const guint8* value);
269 static void
270 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
271 static void
272 proto_tree_set_vines(field_info *fi, const guint8* value);
273 static void
274 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
275 static void
276 proto_tree_set_ether(field_info *fi, const guint8* value);
277 static void
278 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
279 static void
280 proto_tree_set_ipxnet(field_info *fi, guint32 value);
281 static void
282 proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
283 static void
284 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
285 static void
286 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
287 static void
288 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
289 static void
290 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
291 static void
292 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
293 static void
294 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
295 static void
296 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
297 static void
298 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
299 static void
300 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
301 static void
302 proto_tree_set_boolean(field_info *fi, guint64 value);
303 static void
304 proto_tree_set_float(field_info *fi, float value);
305 static void
306 proto_tree_set_double(field_info *fi, double value);
307 static void
308 proto_tree_set_uint(field_info *fi, guint32 value);
309 static void
310 proto_tree_set_int(field_info *fi, gint32 value);
311 static void
312 proto_tree_set_uint64(field_info *fi, guint64 value);
313 static void
314 proto_tree_set_int64(field_info *fi, gint64 value);
315 static void
316 proto_tree_set_eui64(field_info *fi, const guint64 value);
317 static void
318 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
319
320 /* Handle type length mismatch (now filterable) expert info */
321 static int proto_type_length_mismatch = -1;
322 static expert_field ei_type_length_mismatch_error = EI_INIT;
323 static expert_field ei_type_length_mismatch_warn = EI_INIT;
324 static void register_type_length_mismatch(void);
325
326 /* Handle number string decoding errors with expert info */
327 static int proto_number_string_decoding_error = -1;
328 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
329 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
330 static void register_number_string_decodinws_error(void);
331
332 /* Handle string errors expert info */
333 static int proto_string_errors = -1;
334 static expert_field ei_string_trailing_characters = EI_INIT;
335 static void register_string_errors(void);
336
337 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
338
339 /* special-case header field used within proto.c */
340 static header_field_info hfi_text_only =
341         { "Text item",  "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
342 int hf_text_only = -1;
343
344 /* Structure for information about a protocol */
345 struct _protocol {
346         const char *name;               /* long description */
347         const char *short_name;         /* short description */
348         const char *filter_name;        /* name of this protocol in filters */
349         GPtrArray  *fields;             /* fields for this protocol */
350         int         proto_id;           /* field ID for this protocol */
351         gboolean    is_enabled;         /* TRUE if protocol is enabled */
352         gboolean    enabled_by_default; /* TRUE if protocol is enabled by default */
353         gboolean    can_toggle;         /* TRUE if is_enabled can be changed */
354         int         parent_proto_id;    /* Used to identify "pino"s (Protocol In Name Only).
355                                        For dissectors that need a protocol name so they
356                                        can be added to a dissector table, but use the
357                                        parent_proto_id for things like enable/disable */
358         GList      *heur_list;          /* Heuristic dissectors associated with this protocol */
359 };
360
361 /* List of all protocols */
362 static GList *protocols = NULL;
363
364 /* Deregistered fields */
365 static GPtrArray *deregistered_fields = NULL;
366 static GPtrArray *deregistered_data = NULL;
367
368 /* indexed by prefix, contains initializers */
369 static GHashTable* prefixes = NULL;
370
371 /* Contains information about a field when a dissector calls
372  * proto_tree_add_item.  */
373 #define FIELD_INFO_NEW(pool, fi)  fi = wmem_new(pool, field_info)
374 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
375
376 /* Contains the space for proto_nodes. */
377 #define PROTO_NODE_INIT(node)                   \
378         node->first_child = NULL;               \
379         node->last_child = NULL;                \
380         node->next = NULL;
381
382 #define PROTO_NODE_FREE(pool, node)                     \
383         wmem_free(pool, node)
384
385 /* String space for protocol and field items for the GUI */
386 #define ITEM_LABEL_NEW(pool, il)                        \
387         il = wmem_new(pool, item_label_t);
388 #define ITEM_LABEL_FREE(pool, il)                       \
389         wmem_free(pool, il);
390
391 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)                                                \
392         if((guint)hfindex >= gpa_hfinfo.len && wireshark_abort_on_dissector_bug)        \
393                 ws_error("Unregistered hf! index=%d", hfindex);                                 \
394         DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!");     \
395         DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!");     \
396         hfinfo = gpa_hfinfo.hfi[hfindex];
397
398 /* List which stores protocols and fields that have been registered */
399 typedef struct _gpa_hfinfo_t {
400         guint32             len;
401         guint32             allocated_len;
402         header_field_info **hfi;
403 } gpa_hfinfo_t;
404
405 static gpa_hfinfo_t gpa_hfinfo;
406
407 /* Hash table of abbreviations and IDs */
408 static GHashTable *gpa_name_map = NULL;
409 static header_field_info *same_name_hfinfo;
410
411 /* Hash table protocol aliases. const char * -> const char * */
412 static GHashTable *gpa_protocol_aliases = NULL;
413
414 /*
415  * We're called repeatedly with the same field name when sorting a column.
416  * Cache our last gpa_name_map hit for faster lookups.
417  */
418 static char *last_field_name = NULL;
419 static header_field_info *last_hfinfo;
420
421 static void save_same_name_hfinfo(gpointer data)
422 {
423         same_name_hfinfo = (header_field_info*)data;
424 }
425
426 /* Points to the first element of an array of bits, indexed by
427    a subtree item type; that array element is TRUE if subtrees of
428    an item of that type are to be expanded. */
429 static guint32 *tree_is_expanded;
430
431 /* Number of elements in that array. */
432 int             num_tree_types;
433
434 /* Name hashtables for fast detection of duplicate names */
435 static GHashTable* proto_names        = NULL;
436 static GHashTable* proto_short_names  = NULL;
437 static GHashTable* proto_filter_names = NULL;
438
439 static gint
440 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
441 {
442         const protocol_t *p1 = (const protocol_t *)p1_arg;
443         const protocol_t *p2 = (const protocol_t *)p2_arg;
444
445         return g_ascii_strcasecmp(p1->short_name, p2->short_name);
446 }
447
448 static GSList *dissector_plugins = NULL;
449
450 #ifdef HAVE_PLUGINS
451 void
452 proto_register_plugin(const proto_plugin *plug)
453 {
454         dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
455 }
456 #else /* HAVE_PLUGINS */
457 void
458 proto_register_plugin(const proto_plugin *plug _U_)
459 {
460         ws_warning("proto_register_plugin: built without support for binary plugins");
461 }
462 #endif /* HAVE_PLUGINS */
463
464 static void
465 call_plugin_register_protoinfo(gpointer data, gpointer user_data _U_)
466 {
467         proto_plugin *plug = (proto_plugin *)data;
468
469         if (plug->register_protoinfo) {
470                 plug->register_protoinfo();
471         }
472 }
473
474 static void
475 call_plugin_register_handoff(gpointer data, gpointer user_data _U_)
476 {
477         proto_plugin *plug = (proto_plugin *)data;
478
479         if (plug->register_handoff) {
480                 plug->register_handoff();
481         }
482 }
483
484 /* initialize data structures and register protocols and fields */
485 void
486 proto_init(GSList *register_all_plugin_protocols_list,
487            GSList *register_all_plugin_handoffs_list,
488            register_cb cb,
489            gpointer client_data)
490 {
491         proto_cleanup_base();
492
493         proto_names        = g_hash_table_new(g_str_hash, g_str_equal);
494         proto_short_names  = g_hash_table_new(g_str_hash, g_str_equal);
495         proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
496
497         gpa_hfinfo.len           = 0;
498         gpa_hfinfo.allocated_len = 0;
499         gpa_hfinfo.hfi           = NULL;
500         gpa_name_map             = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
501         gpa_protocol_aliases     = g_hash_table_new(g_str_hash, g_str_equal);
502         deregistered_fields      = g_ptr_array_new();
503         deregistered_data        = g_ptr_array_new();
504
505         /* Initialize the ftype subsystem */
506         ftypes_initialize();
507
508         /* Initialize the addres type subsystem */
509         address_types_initialize();
510
511         /* Register one special-case FT_TEXT_ONLY field for use when
512            converting wireshark to new-style proto_tree. These fields
513            are merely strings on the GUI tree; they are not filterable */
514         hf_text_only = proto_register_field_init(&hfi_text_only, -1);
515
516         /* Register the pseudo-protocols used for exceptions. */
517         register_show_exception();
518         register_type_length_mismatch();
519         register_number_string_decodinws_error();
520         register_string_errors();
521
522         /* Have each built-in dissector register its protocols, fields,
523            dissector tables, and dissectors to be called through a
524            handle, and do whatever one-time initialization it needs to
525            do. */
526         register_all_protocols(cb, client_data);
527
528         /* Now call the registration routines for all epan plugins. */
529         for (GSList *l = register_all_plugin_protocols_list; l != NULL; l = l->next) {
530                 ((void (*)(register_cb, gpointer))l->data)(cb, client_data);
531         }
532
533         /* Now call the registration routines for all dissector plugins. */
534         if (cb)
535                 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
536         g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL);
537
538         /* Now call the "handoff registration" routines of all built-in
539            dissectors; those routines register the dissector in other
540            dissectors' handoff tables, and fetch any dissector handles
541            they need. */
542         register_all_protocol_handoffs(cb, client_data);
543
544         /* Now do the same with epan plugins. */
545         for (GSList *l = register_all_plugin_handoffs_list; l != NULL; l = l->next) {
546                 ((void (*)(register_cb, gpointer))l->data)(cb, client_data);
547         }
548
549         /* Now do the same with dissector plugins. */
550         if (cb)
551                 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
552         g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL);
553
554         /* sort the protocols by protocol name */
555         protocols = g_list_sort(protocols, proto_compare_name);
556
557         /* We've assigned all the subtree type values; allocate the array
558            for them, and zero it out. */
559         tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
560 }
561
562 static void
563 proto_cleanup_base(void)
564 {
565         protocol_t *protocol;
566         header_field_info *hfinfo;
567
568         /* Free the abbrev/ID hash table */
569         if (gpa_name_map) {
570                 g_hash_table_destroy(gpa_name_map);
571                 gpa_name_map = NULL;
572         }
573         if (gpa_protocol_aliases) {
574                 g_hash_table_destroy(gpa_protocol_aliases);
575                 gpa_protocol_aliases = NULL;
576         }
577         g_free(last_field_name);
578         last_field_name = NULL;
579
580         while (protocols) {
581                 protocol = (protocol_t *)protocols->data;
582                 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
583                 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
584
585                 g_slice_free(header_field_info, hfinfo);
586                 if (protocol->parent_proto_id != -1) {
587                         // pino protocol
588                         DISSECTOR_ASSERT(protocol->fields == NULL); //helpers should not have any registered fields
589                         DISSECTOR_ASSERT(protocol->heur_list == NULL); //helpers should not have a heuristic list
590                 } else {
591                         if (protocol->fields) {
592                                 g_ptr_array_free(protocol->fields, TRUE);
593                         }
594                         g_list_free(protocol->heur_list);
595                 }
596                 protocols = g_list_remove(protocols, protocol);
597                 g_free(protocol);
598         }
599
600         if (proto_names) {
601                 g_hash_table_destroy(proto_names);
602                 proto_names = NULL;
603         }
604
605         if (proto_short_names) {
606                 g_hash_table_destroy(proto_short_names);
607                 proto_short_names = NULL;
608         }
609
610         if (proto_filter_names) {
611                 g_hash_table_destroy(proto_filter_names);
612                 proto_filter_names = NULL;
613         }
614
615         if (gpa_hfinfo.allocated_len) {
616                 gpa_hfinfo.len           = 0;
617                 gpa_hfinfo.allocated_len = 0;
618                 g_free(gpa_hfinfo.hfi);
619                 gpa_hfinfo.hfi           = NULL;
620         }
621
622         if (deregistered_fields) {
623                 g_ptr_array_free(deregistered_fields, TRUE);
624                 deregistered_fields = NULL;
625         }
626
627         if (deregistered_data) {
628                 g_ptr_array_free(deregistered_data, TRUE);
629                 deregistered_data = NULL;
630         }
631
632         g_free(tree_is_expanded);
633         tree_is_expanded = NULL;
634
635         if (prefixes)
636                 g_hash_table_destroy(prefixes);
637 }
638
639 void
640 proto_cleanup(void)
641 {
642         proto_free_deregistered_fields();
643         proto_cleanup_base();
644
645         g_slist_free(dissector_plugins);
646         dissector_plugins = NULL;
647 }
648
649 static gboolean
650 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
651                               gpointer data)
652 {
653         proto_node *pnode = tree;
654         proto_node *child;
655         proto_node *current;
656
657         if (func(pnode, data))
658                 return TRUE;
659
660         child = pnode->first_child;
661         while (child != NULL) {
662                 /*
663                  * The routine we call might modify the child, e.g. by
664                  * freeing it, so we get the child's successor before
665                  * calling that routine.
666                  */
667                 current = child;
668                 child   = current->next;
669                 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
670                         return TRUE;
671         }
672
673         return FALSE;
674 }
675
676 gboolean
677 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
678                                gpointer data)
679 {
680         proto_node *pnode = tree;
681         proto_node *child;
682         proto_node *current;
683
684         child = pnode->first_child;
685         while (child != NULL) {
686                 /*
687                  * The routine we call might modify the child, e.g. by
688                  * freeing it, so we get the child's successor before
689                  * calling that routine.
690                  */
691                 current = child;
692                 child   = current->next;
693                 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
694                         return TRUE;
695         }
696         if (func(pnode, data))
697                 return TRUE;
698
699         return FALSE;
700 }
701
702 void
703 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
704                             gpointer data)
705 {
706         proto_node *node = tree;
707         proto_node *current;
708
709         if (!node)
710                 return;
711
712         node = node->first_child;
713         while (node != NULL) {
714                 current = node;
715                 node    = current->next;
716                 func((proto_tree *)current, data);
717         }
718 }
719
720 static void
721 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
722 {
723         GPtrArray         *ptrs = (GPtrArray *)value;
724         gint               hfid = GPOINTER_TO_UINT(key);
725         header_field_info *hfinfo;
726
727         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
728         if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
729                 /* when a field is referenced by a filter this also
730                    affects the refcount for the parent protocol so we need
731                    to adjust the refcount for the parent as well
732                 */
733                 if (hfinfo->parent != -1) {
734                         header_field_info *parent_hfinfo;
735                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
736                         parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
737                 }
738                 hfinfo->ref_type = HF_REF_TYPE_NONE;
739         }
740
741         g_ptr_array_free(ptrs, TRUE);
742 }
743
744 static void
745 proto_tree_free_node(proto_node *node, gpointer data _U_)
746 {
747         field_info *finfo  = PNODE_FINFO(node);
748
749         proto_tree_children_foreach(node, proto_tree_free_node, NULL);
750
751         FVALUE_CLEANUP(&finfo->value);
752 }
753
754 void
755 proto_tree_reset(proto_tree *tree)
756 {
757         tree_data_t *tree_data = PTREE_DATA(tree);
758
759         proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
760
761         /* free tree data */
762         if (tree_data->interesting_hfids) {
763                 /* Free all the GPtrArray's in the interesting_hfids hash. */
764                 g_hash_table_foreach(tree_data->interesting_hfids,
765                         free_GPtrArray_value, NULL);
766
767                 /* And then remove all values. */
768                 g_hash_table_remove_all(tree_data->interesting_hfids);
769         }
770
771         /* Reset track of the number of children */
772         tree_data->count = 0;
773
774         PROTO_NODE_INIT(tree);
775 }
776
777 /* frees the resources that the dissection a proto_tree uses */
778 void
779 proto_tree_free(proto_tree *tree)
780 {
781         tree_data_t *tree_data = PTREE_DATA(tree);
782
783         proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
784
785         /* free tree data */
786         if (tree_data->interesting_hfids) {
787                 /* Free all the GPtrArray's in the interesting_hfids hash. */
788                 g_hash_table_foreach(tree_data->interesting_hfids,
789                         free_GPtrArray_value, NULL);
790
791                 /* And then destroy the hash. */
792                 g_hash_table_destroy(tree_data->interesting_hfids);
793         }
794
795         g_slice_free(tree_data_t, tree_data);
796
797         g_slice_free(proto_tree, tree);
798 }
799
800 /* Is the parsing being done for a visible proto_tree or an invisible one?
801  * By setting this correctly, the proto_tree creation is sped up by not
802  * having to call g_vsnprintf and copy strings around.
803  */
804 gboolean
805 proto_tree_set_visible(proto_tree *tree, gboolean visible)
806 {
807         gboolean old_visible = PTREE_DATA(tree)->visible;
808
809         PTREE_DATA(tree)->visible = visible;
810
811         return old_visible;
812 }
813
814 void
815 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
816 {
817         PTREE_DATA(tree)->fake_protocols = fake_protocols;
818 }
819
820 /* Assume dissector set only its protocol fields.
821    This function is called by dissectors and allows the speeding up of filtering
822    in wireshark; if this function returns FALSE it is safe to reset tree to NULL
823    and thus skip calling most of the expensive proto_tree_add_...()
824    functions.
825    If the tree is visible we implicitly assume the field is referenced.
826 */
827 gboolean
828 proto_field_is_referenced(proto_tree *tree, int proto_id)
829 {
830         register header_field_info *hfinfo;
831
832
833         if (!tree)
834                 return FALSE;
835
836         if (PTREE_DATA(tree)->visible)
837                 return TRUE;
838
839         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
840         if (hfinfo->ref_type != HF_REF_TYPE_NONE)
841                 return TRUE;
842
843         if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
844                 return TRUE;
845
846         return FALSE;
847 }
848
849
850 /* Finds a record in the hfinfo array by id. */
851 header_field_info *
852 proto_registrar_get_nth(guint hfindex)
853 {
854         register header_field_info *hfinfo;
855
856         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
857         return hfinfo;
858 }
859
860
861 /*      Prefix initialization
862  *        this allows for a dissector to register a display filter name prefix
863  *        so that it can delay the initialization of the hf array as long as
864  *        possible.
865  */
866
867 /* compute a hash for the part before the dot of a display filter */
868 static guint
869 prefix_hash (gconstpointer key) {
870         /* end the string at the dot and compute its hash */
871         gchar* copy = g_strdup((const gchar *)key);
872         gchar* c    = copy;
873         guint tmp;
874
875         for (; *c; c++) {
876                 if (*c == '.') {
877                         *c = 0;
878                         break;
879                 }
880         }
881
882         tmp = g_str_hash(copy);
883         g_free(copy);
884         return tmp;
885 }
886
887 /* are both strings equal up to the end or the dot? */
888 static gboolean
889 prefix_equal (gconstpointer ap, gconstpointer bp) {
890         const gchar* a = (const gchar *)ap;
891         const gchar* b = (const gchar *)bp;
892
893         do {
894                 gchar ac = *a++;
895                 gchar bc = *b++;
896
897                 if ( (ac == '.' || ac == '\0') &&   (bc == '.' || bc == '\0') ) return TRUE;
898
899                 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
900                 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
901
902                 if (ac != bc) return FALSE;
903         } while (1);
904
905         return FALSE;
906 }
907
908 /* Register a new prefix for "delayed" initialization of field arrays */
909 void
910 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
911         if (! prefixes ) {
912                 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
913         }
914
915         g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
916 }
917
918 /* helper to call all prefix initializers */
919 static gboolean
920 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
921         ((prefix_initializer_t)v)((const char *)k);
922         return TRUE;
923 }
924
925 /** Initialize every remaining uninitialized prefix. */
926 void
927 proto_initialize_all_prefixes(void) {
928         g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
929 }
930
931 /* Finds a record in the hfinfo array by name.
932  * If it fails to find it in the already registered fields,
933  * it tries to find and call an initializer in the prefixes
934  * table and if so it looks again.
935  */
936
937 header_field_info *
938 proto_registrar_get_byname(const char *field_name)
939 {
940         header_field_info    *hfinfo;
941         prefix_initializer_t  pi;
942
943         if (!field_name)
944                 return NULL;
945
946         if (g_strcmp0(field_name, last_field_name) == 0) {
947                 return last_hfinfo;
948         }
949
950         hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
951
952         if (hfinfo) {
953                 g_free(last_field_name);
954                 last_field_name = g_strdup(field_name);
955                 last_hfinfo = hfinfo;
956                 return hfinfo;
957         }
958
959         if (!prefixes)
960                 return NULL;
961
962         if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
963                 pi(field_name);
964                 g_hash_table_remove(prefixes, field_name);
965         } else {
966                 return NULL;
967         }
968
969         hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
970
971         if (hfinfo) {
972                 g_free(last_field_name);
973                 last_field_name = g_strdup(field_name);
974                 last_hfinfo = hfinfo;
975         }
976         return hfinfo;
977 }
978
979 header_field_info*
980 proto_registrar_get_byalias(const char *alias_name)
981 {
982         if (!alias_name) {
983                 return NULL;
984         }
985
986         /* Find our aliased protocol. */
987         char *an_copy = g_strdup(alias_name);
988         char *dot = strchr(an_copy, '.');
989         if (dot) {
990                 *dot = '\0';
991         }
992         const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
993         if (!proto_pfx) {
994                 g_free(an_copy);
995                 return NULL;
996         }
997
998         /* Construct our aliased field and look it up. */
999         GString *filter_name = g_string_new(proto_pfx);
1000         if (dot) {
1001                 g_string_append_printf(filter_name, ".%s", dot+1);
1002         }
1003         header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1004         g_free(an_copy);
1005         g_string_free(filter_name, TRUE);
1006
1007         return hfinfo;
1008 }
1009
1010 int
1011 proto_registrar_get_id_byname(const char *field_name)
1012 {
1013         header_field_info *hfinfo;
1014
1015         hfinfo = proto_registrar_get_byname(field_name);
1016
1017         if (!hfinfo)
1018                 return -1;
1019
1020         return hfinfo->id;
1021 }
1022
1023
1024 static char *
1025 hfinfo_format_text(wmem_allocator_t *scope, const header_field_info *hfinfo,
1026     const guchar *string)
1027 {
1028         switch (hfinfo->display) {
1029                 case STR_ASCII:
1030                         return format_text(scope, string, strlen(string));
1031 /*
1032                 case STR_ASCII_WSP
1033                         return format_text_wsp(string, strlen(string));
1034  */
1035                 case STR_UNICODE:
1036                         return format_text(scope, string, strlen(string));
1037         }
1038
1039         return format_text(scope, string, strlen(string));
1040 }
1041
1042 static char *
1043 hfinfo_format_bytes(wmem_allocator_t *scope, const header_field_info *hfinfo,
1044     const guint8 *bytes, guint length)
1045 {
1046         char *str = NULL;
1047         const guint8 *p;
1048         gboolean is_printable;
1049
1050         if (bytes) {
1051                 if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE) {
1052                         /*
1053                          * Check whether all bytes are printable.
1054                          */
1055                         is_printable = TRUE;
1056                         for (p = bytes; p < bytes+length; p++) {
1057                                 if (!g_ascii_isprint(*p)) {
1058                                         /* Not printable. */
1059                                         is_printable = FALSE;
1060                                         break;
1061                                 }
1062                         }
1063
1064                         /*
1065                          * If all bytes are printable ASCII, show the bytes
1066                          * as a string - in quotes to indicate that it's
1067                          * a string.
1068                          */
1069                         if (is_printable) {
1070                                 str = wmem_strdup_printf(scope, "\"%.*s\"",
1071                                     (int)length, bytes);
1072                                 return str;
1073                         }
1074                 }
1075
1076                 /*
1077                  * Either it's not printable ASCII, or we don't care whether
1078                  * it's printable ASCII; show it as hex bytes.
1079                  */
1080                 switch (FIELD_DISPLAY(hfinfo->display)) {
1081                 case SEP_DOT:
1082                         str = bytestring_to_str(scope, bytes, length, '.');
1083                         break;
1084                 case SEP_DASH:
1085                         str = bytestring_to_str(scope, bytes, length, '-');
1086                         break;
1087                 case SEP_COLON:
1088                         str = bytestring_to_str(scope, bytes, length, ':');
1089                         break;
1090                 case SEP_SPACE:
1091                         str = bytestring_to_str(scope, bytes, length, ' ');
1092                         break;
1093                 case BASE_NONE:
1094                 default:
1095                         if (prefs.display_byte_fields_with_spaces) {
1096                                 str = bytestring_to_str(scope, bytes, length, ' ');
1097                         } else {
1098                                 str = bytes_to_str(scope, bytes, length);
1099                         }
1100                         break;
1101                 }
1102         }
1103         else {
1104                 if (hfinfo->display & BASE_ALLOW_ZERO) {
1105                         str = wmem_strdup(scope, "<none>");
1106                 } else {
1107                         str = wmem_strdup(scope, "<MISSING>");
1108                 }
1109         }
1110         return str;
1111 }
1112
1113 static void
1114 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1115 {
1116         subtree_lvl *pushed_tree;
1117
1118         DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
1119         ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
1120
1121         pushed_tree = (subtree_lvl *)wmem_realloc(wmem_packet_scope(), (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1122         DISSECTOR_ASSERT(pushed_tree != NULL);
1123         ptvc->pushed_tree = pushed_tree;
1124 }
1125
1126 static void
1127 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1128 {
1129         ptvc->pushed_tree       = NULL;
1130         ptvc->pushed_tree_max   = 0;
1131         DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1132         ptvc->pushed_tree_index = 0;
1133 }
1134
1135 /* Allocates an initializes a ptvcursor_t with 3 variables:
1136  *      proto_tree, tvbuff, and offset. */
1137 ptvcursor_t *
1138 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
1139 {
1140         ptvcursor_t *ptvc;
1141
1142         ptvc                    = wmem_new(wmem_packet_scope(), ptvcursor_t);
1143         ptvc->tree              = tree;
1144         ptvc->tvb               = tvb;
1145         ptvc->offset            = offset;
1146         ptvc->pushed_tree       = NULL;
1147         ptvc->pushed_tree_max   = 0;
1148         ptvc->pushed_tree_index = 0;
1149         return ptvc;
1150 }
1151
1152
1153 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1154 void
1155 ptvcursor_free(ptvcursor_t *ptvc)
1156 {
1157         ptvcursor_free_subtree_levels(ptvc);
1158         /*g_free(ptvc);*/
1159 }
1160
1161 /* Returns tvbuff. */
1162 tvbuff_t *
1163 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1164 {
1165         return ptvc->tvb;
1166 }
1167
1168 /* Returns current offset. */
1169 gint
1170 ptvcursor_current_offset(ptvcursor_t *ptvc)
1171 {
1172         return ptvc->offset;
1173 }
1174
1175 proto_tree *
1176 ptvcursor_tree(ptvcursor_t *ptvc)
1177 {
1178         if (!ptvc)
1179                 return NULL;
1180
1181         return ptvc->tree;
1182 }
1183
1184 void
1185 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1186 {
1187         ptvc->tree = tree;
1188 }
1189
1190 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1191 proto_tree *
1192 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1193 {
1194         subtree_lvl *subtree;
1195         if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1196                 ptvcursor_new_subtree_levels(ptvc);
1197
1198         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1199         subtree->tree = ptvc->tree;
1200         subtree->it= NULL;
1201         ptvc->pushed_tree_index++;
1202         return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1203 }
1204
1205 /* pops a subtree */
1206 void
1207 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1208 {
1209         subtree_lvl *subtree;
1210
1211         if (ptvc->pushed_tree_index <= 0)
1212                 return;
1213
1214         ptvc->pushed_tree_index--;
1215         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1216         if (subtree->it != NULL)
1217                 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1218
1219         ptvc->tree = subtree->tree;
1220 }
1221
1222 /* saves the current tvb offset and the item in the current subtree level */
1223 static void
1224 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1225 {
1226         subtree_lvl *subtree;
1227
1228         DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1229
1230         subtree                = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1231         subtree->it            = it;
1232         subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1233 }
1234
1235 /* Creates a subtree and adds it to the cursor as the working tree but does not
1236  * save the old working tree */
1237 proto_tree *
1238 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1239 {
1240         ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1241         return ptvc->tree;
1242 }
1243
1244 static proto_tree *
1245 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1246 {
1247         ptvcursor_push_subtree(ptvc, it, ett_subtree);
1248         if (length == SUBTREE_UNDEFINED_LENGTH)
1249                 ptvcursor_subtree_set_item(ptvc, it);
1250         return ptvcursor_tree(ptvc);
1251 }
1252
1253 /* Add an item to the tree and create a subtree
1254  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1255  * In this case, when the subtree will be closed, the parent item length will
1256  * be equal to the advancement of the cursor since the creation of the subtree.
1257  */
1258 proto_tree *
1259 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1260                            const guint encoding, gint ett_subtree)
1261 {
1262         proto_item *it;
1263
1264         it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1265         return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1266 }
1267
1268 static proto_item *
1269 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1270
1271 /* Add a text node to the tree and create a subtree
1272  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1273  * In this case, when the subtree will be closed, the item length will be equal
1274  * to the advancement of the cursor since the creation of the subtree.
1275  */
1276 proto_tree *
1277 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1278                                 gint ett_subtree, const char *format, ...)
1279 {
1280         proto_item        *pi;
1281         va_list            ap;
1282         header_field_info *hfinfo;
1283         proto_tree        *tree;
1284
1285         tree = ptvcursor_tree(ptvc);
1286
1287         CHECK_FOR_NULL_TREE(tree);
1288
1289         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1290
1291         pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1292                                       ptvcursor_current_offset(ptvc), length);
1293
1294         TRY_TO_FAKE_THIS_REPR(pi);
1295
1296         va_start(ap, format);
1297         proto_tree_set_representation(pi, format, ap);
1298         va_end(ap);
1299
1300         return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1301 }
1302
1303 /* Add a text-only node, leaving it to our caller to fill the text in */
1304 static proto_item *
1305 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1306 {
1307         proto_item *pi;
1308
1309         if (tree == NULL)
1310                 return NULL;
1311
1312         pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1313
1314         return pi;
1315 }
1316
1317 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1318 proto_item *
1319 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1320                     const char *format, ...)
1321 {
1322         proto_item        *pi;
1323         va_list            ap;
1324         header_field_info *hfinfo;
1325
1326         if (length == -1) {
1327                 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1328         } else {
1329                 tvb_ensure_bytes_exist(tvb, start, length);
1330         }
1331
1332         CHECK_FOR_NULL_TREE(tree);
1333
1334         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1335
1336         pi = proto_tree_add_text_node(tree, tvb, start, length);
1337
1338         TRY_TO_FAKE_THIS_REPR(pi);
1339
1340         va_start(ap, format);
1341         proto_tree_set_representation(pi, format, ap);
1342         va_end(ap);
1343
1344         return pi;
1345 }
1346
1347 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1348 proto_item *
1349 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1350                            gint length, const char *format, va_list ap)
1351 {
1352         proto_item        *pi;
1353         header_field_info *hfinfo;
1354
1355         if (length == -1) {
1356                 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1357         } else {
1358                 tvb_ensure_bytes_exist(tvb, start, length);
1359         }
1360
1361         CHECK_FOR_NULL_TREE(tree);
1362
1363         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1364
1365         pi = proto_tree_add_text_node(tree, tvb, start, length);
1366
1367         TRY_TO_FAKE_THIS_REPR(pi);
1368
1369         proto_tree_set_representation(pi, format, ap);
1370
1371         return pi;
1372 }
1373
1374 /* Add a text-only node that creates a subtree underneath.
1375  */
1376 proto_tree *
1377 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1378 {
1379         return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1380 }
1381
1382 /* Add a text-only node that creates a subtree underneath.
1383  */
1384 proto_tree *
1385 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1386 {
1387         proto_tree *pt;
1388         proto_item *pi;
1389         va_list     ap;
1390
1391         va_start(ap, format);
1392         pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1393         va_end(ap);
1394
1395         if (tree_item != NULL)
1396                 *tree_item = pi;
1397
1398         pt = proto_item_add_subtree(pi, idx);
1399
1400         return pt;
1401 }
1402
1403 /* Add a text-only node for debugging purposes. The caller doesn't need
1404  * to worry about tvbuff, start, or length. Debug message gets sent to
1405  * STDOUT, too */
1406 proto_item *
1407 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1408 {
1409         proto_item *pi;
1410         va_list     ap;
1411
1412         pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1413
1414         if (pi) {
1415                 va_start(ap, format);
1416                 proto_tree_set_representation(pi, format, ap);
1417                 va_end(ap);
1418         }
1419         va_start(ap, format);
1420         vprintf(format, ap);
1421         va_end(ap);
1422         printf("\n");
1423
1424         return pi;
1425 }
1426
1427 proto_item *
1428 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1429 {
1430         proto_item        *pi;
1431         header_field_info *hfinfo;
1432
1433         CHECK_FOR_NULL_TREE(tree);
1434
1435         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1436
1437         pi = proto_tree_add_text_node(tree, tvb, start, length);
1438
1439         TRY_TO_FAKE_THIS_REPR(pi);
1440
1441         proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1442
1443         return pi;
1444 }
1445
1446 proto_item *
1447 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1448 {
1449         proto_item        *pi;
1450         header_field_info *hfinfo;
1451         gchar             *str;
1452
1453         CHECK_FOR_NULL_TREE(tree);
1454
1455         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1456
1457         pi = proto_tree_add_text_node(tree, tvb, start, length);
1458
1459         TRY_TO_FAKE_THIS_REPR(pi);
1460
1461         str = tvb_format_text_wsp(NULL, tvb, start, length);
1462         proto_item_set_text(pi, "%s", str);
1463         wmem_free(NULL, str);
1464
1465         return pi;
1466 }
1467
1468 void proto_report_dissector_bug(const char *format, ...)
1469 {
1470         va_list args;
1471
1472         if (wireshark_abort_on_dissector_bug) {
1473                 /*
1474                  * Try to have the error message show up in the crash
1475                  * information.
1476                  */
1477                 va_start(args, format);
1478                 ws_vadd_crash_info(format, args);
1479                 va_end(args);
1480
1481                 /*
1482                  * Print the error message.
1483                  */
1484                 va_start(args, format);
1485                 vfprintf(stderr, format, args);
1486                 va_end(args);
1487                 putc('\n', stderr);
1488
1489                 /*
1490                  * And crash.
1491                  */
1492                 abort();
1493         } else {
1494                 va_start(args, format);
1495                 VTHROW_FORMATTED(DissectorError, format, args);
1496                 va_end(args);
1497         }
1498 }
1499
1500 /* We could probably get away with changing is_error to a minimum length value. */
1501 static void
1502 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error)
1503 {
1504         if (is_error) {
1505                 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1506         } else {
1507                 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1508         }
1509
1510         if (is_error) {
1511                 THROW(ReportedBoundsError);
1512         }
1513 }
1514
1515 static guint32
1516 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1517 {
1518         guint32 value;
1519         gboolean length_error;
1520
1521         switch (length) {
1522
1523         case 1:
1524                 value = tvb_get_guint8(tvb, offset);
1525                 if (encoding & ENC_ZIGBEE) {
1526                         if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1527                                 value = 0;
1528                         }
1529                 }
1530                 break;
1531
1532         case 2:
1533                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1534                                                        : tvb_get_ntohs(tvb, offset);
1535                 if (encoding & ENC_ZIGBEE) {
1536                         if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1537                                 value = 0;
1538                         }
1539                 }
1540                 break;
1541
1542         case 3:
1543                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1544                                                        : tvb_get_ntoh24(tvb, offset);
1545                 break;
1546
1547         case 4:
1548                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1549                                                        : tvb_get_ntohl(tvb, offset);
1550                 break;
1551
1552         default:
1553                 if (length < 1) {
1554                         length_error = TRUE;
1555                         value = 0;
1556                 } else {
1557                         length_error = FALSE;
1558                         value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1559                                                                : tvb_get_ntohl(tvb, offset);
1560                 }
1561                 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1562                 break;
1563         }
1564         return value;
1565 }
1566
1567 static inline guint64
1568 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1569 {
1570         guint64 value;
1571         gboolean length_error;
1572
1573         switch (length) {
1574
1575         case 1:
1576                 value = tvb_get_guint8(tvb, offset);
1577                 break;
1578
1579         case 2:
1580                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1581                                                        : tvb_get_ntohs(tvb, offset);
1582                 break;
1583
1584         case 3:
1585                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1586                                                        : tvb_get_ntoh24(tvb, offset);
1587                 break;
1588
1589         case 4:
1590                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1591                                                        : tvb_get_ntohl(tvb, offset);
1592                 break;
1593
1594         case 5:
1595                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1596                                                        : tvb_get_ntoh40(tvb, offset);
1597                 break;
1598
1599         case 6:
1600                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1601                                                        : tvb_get_ntoh48(tvb, offset);
1602                 break;
1603
1604         case 7:
1605                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1606                                                        : tvb_get_ntoh56(tvb, offset);
1607                 break;
1608
1609         case 8:
1610                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1611                                                        : tvb_get_ntoh64(tvb, offset);
1612                 break;
1613
1614         default:
1615                 if (length < 1) {
1616                         length_error = TRUE;
1617                         value = 0;
1618                 } else {
1619                         length_error = FALSE;
1620                         value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1621                                                                : tvb_get_ntoh64(tvb, offset);
1622                 }
1623                 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1624                 break;
1625         }
1626         return value;
1627 }
1628
1629 static gint32
1630 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1631 {
1632         gint32 value;
1633         gboolean length_error;
1634
1635         switch (length) {
1636
1637         case 1:
1638                 value = tvb_get_gint8(tvb, offset);
1639                 break;
1640
1641         case 2:
1642                 value = encoding ? tvb_get_letohis(tvb, offset)
1643                                  : tvb_get_ntohis(tvb, offset);
1644                 break;
1645
1646         case 3:
1647                 value = encoding ? tvb_get_letohi24(tvb, offset)
1648                                  : tvb_get_ntohi24(tvb, offset);
1649                 break;
1650
1651         case 4:
1652                 value = encoding ? tvb_get_letohil(tvb, offset)
1653                                  : tvb_get_ntohil(tvb, offset);
1654                 break;
1655
1656         default:
1657                 if (length < 1) {
1658                         length_error = TRUE;
1659                         value = 0;
1660                 } else {
1661                         length_error = FALSE;
1662                         value = encoding ? tvb_get_letohil(tvb, offset)
1663                                          : tvb_get_ntohil(tvb, offset);
1664                 }
1665                 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1666                 break;
1667         }
1668         return value;
1669 }
1670
1671 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1672  * be cast-able as a gint64. This is weird, but what the code has always done.
1673  */
1674 static inline guint64
1675 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1676 {
1677         guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1678
1679         switch (length) {
1680                 case 7:
1681                         value = ws_sign_ext64(value, 56);
1682                         break;
1683                 case 6:
1684                         value = ws_sign_ext64(value, 48);
1685                         break;
1686                 case 5:
1687                         value = ws_sign_ext64(value, 40);
1688                         break;
1689                 case 4:
1690                         value = ws_sign_ext64(value, 32);
1691                         break;
1692                 case 3:
1693                         value = ws_sign_ext64(value, 24);
1694                         break;
1695                 case 2:
1696                         value = ws_sign_ext64(value, 16);
1697                         break;
1698                 case 1:
1699                         value = ws_sign_ext64(value, 8);
1700                         break;
1701         }
1702
1703         return value;
1704 }
1705
1706 /* For FT_STRING */
1707 static inline const guint8 *
1708 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1709     gint length, gint *ret_length, const guint encoding)
1710 {
1711         if (length == -1) {
1712                 length = tvb_ensure_captured_length_remaining(tvb, start);
1713         }
1714         *ret_length = length;
1715         return tvb_get_string_enc(scope, tvb, start, length, encoding);
1716 }
1717
1718 /* For FT_STRINGZ */
1719 static inline const guint8 *
1720 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1721     gint start, gint length, gint *ret_length, const guint encoding)
1722 {
1723         const guint8 *value;
1724
1725         if (length < -1) {
1726                 report_type_length_mismatch(tree, "a string", length, TRUE);
1727         }
1728         if (length == -1) {
1729                 /* This can throw an exception */
1730                 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1731         } else {
1732                 /* In this case, length signifies the length of the string.
1733                  *
1734                  * This could either be a null-padded string, which doesn't
1735                  * necessarily have a '\0' at the end, or a null-terminated
1736                  * string, with a trailing '\0'.  (Yes, there are cases
1737                  * where you have a string that's both counted and null-
1738                  * terminated.)
1739                  *
1740                  * In the first case, we must allocate a buffer of length
1741                  * "length+1", to make room for a trailing '\0'.
1742                  *
1743                  * In the second case, we don't assume that there is a
1744                  * trailing '\0' there, as the packet might be malformed.
1745                  * (XXX - should we throw an exception if there's no
1746                  * trailing '\0'?)  Therefore, we allocate a buffer of
1747                  * length "length+1", and put in a trailing '\0', just to
1748                  * be safe.
1749                  *
1750                  * (XXX - this would change if we made string values counted
1751                  * rather than null-terminated.)
1752                  */
1753                 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1754         }
1755         *ret_length = length;
1756         return value;
1757 }
1758
1759 /* For FT_UINT_STRING */
1760 static inline const guint8 *
1761 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1762     tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1763     const guint encoding)
1764 {
1765         guint32 n;
1766         const guint8 *value;
1767
1768         /* I believe it's ok if this is called with a NULL tree */
1769         n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1770         value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1771         length += n;
1772         *ret_length = length;
1773         return value;
1774 }
1775
1776 /* For FT_STRINGZPAD */
1777 static inline const guint8 *
1778 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1779     gint length, gint *ret_length, const guint encoding)
1780 {
1781         /*
1782          * XXX - currently, string values are null-
1783          * terminated, so a "zero-padded" string
1784          * isn't special.  If we represent string
1785          * values as something that includes a counted
1786          * array of bytes, we'll need to strip the
1787          * trailing NULs.
1788          */
1789         if (length == -1) {
1790                 length = tvb_ensure_captured_length_remaining(tvb, start);
1791         }
1792         *ret_length = length;
1793         return tvb_get_string_enc(scope, tvb, start, length, encoding);
1794 }
1795
1796 /* For FT_STRINGZTRUNC */
1797 static inline const guint8 *
1798 get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1799     gint length, gint *ret_length, const guint encoding)
1800 {
1801         /*
1802          * XXX - currently, string values are null-
1803          * terminated, so a "zero-truncated" string
1804          * isn't special.  If we represent string
1805          * values as something that includes a counted
1806          * array of bytes, we'll need to strip everything
1807          * starting with the terminating NUL.
1808          */
1809         if (length == -1) {
1810                 length = tvb_ensure_captured_length_remaining(tvb, start);
1811         }
1812         *ret_length = length;
1813         return tvb_get_string_enc(scope, tvb, start, length, encoding);
1814 }
1815
1816 /*
1817  * Deltas between the epochs for various non-UN*X time stamp formats and
1818  * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1819  * stamp format.
1820  */
1821
1822 /*
1823  * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1824  * XXX - if it's OK if this is unsigned, can we just use
1825  * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1826  */
1827 #define NTP_TIMEDIFF1900TO1970SEC G_GINT64_CONSTANT(2208988800)
1828
1829 /*
1830  * NTP Era 1: the epoch is January 1, 2036, 00:00:00 UTC.
1831  */
1832 #define NTP_TIMEDIFF1970TO2036SEC G_GINT64_CONSTANT(2085978496)
1833
1834 /* this can be called when there is no tree, so tree may be null */
1835 static void
1836 get_time_value(proto_tree *tree, tvbuff_t *tvb, const gint start,
1837                const gint length, const guint encoding, nstime_t *time_stamp,
1838                const gboolean is_relative)
1839 {
1840         guint32     tmpsecs;
1841         guint64     tmp64secs;
1842         guint64     todusecs;
1843
1844         switch (encoding) {
1845
1846                 case ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN:
1847                         /*
1848                          * If the length is 16, 8-byte seconds, followed
1849                          * by 8-byte fractional time in nanoseconds,
1850                          * both big-endian.
1851                          *
1852                          * If the length is 12, 8-byte seconds, followed
1853                          * by 4-byte fractional time in nanoseconds,
1854                          * both big-endian.
1855                          *
1856                          * If the length is 8, 4-byte seconds, followed
1857                          * by 4-byte fractional time in nanoseconds,
1858                          * both big-endian.
1859                          *
1860                          * For absolute times, the seconds are seconds
1861                          * since the UN*X epoch.
1862                          */
1863                         if (length == 16) {
1864                                 time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
1865                                 time_stamp->nsecs = (guint32)tvb_get_ntoh64(tvb, start+8);
1866                         } else if (length == 12) {
1867                                 time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
1868                                 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1869                         } else if (length == 8) {
1870                                 time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
1871                                 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1872                         } else if (length == 4) {
1873                                 /*
1874                                  * Backwards compatibility.
1875                                  * ENC_TIME_SECS_NSECS is 0; using
1876                                  * ENC_BIG_ENDIAN by itself with a 4-byte
1877                                  * time-in-seconds value was done in the
1878                                  * past.
1879                                  */
1880                                 time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
1881                                 time_stamp->nsecs = 0;
1882                         } else {
1883                                 time_stamp->secs  = 0;
1884                                 time_stamp->nsecs = 0;
1885                                 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1886                         }
1887                         break;
1888
1889                 case ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN:
1890                         /*
1891                          * If the length is 16, 8-byte seconds, followed
1892                          * by 8-byte fractional time in nanoseconds,
1893                          * both little-endian.
1894                          *
1895                          * If the length is 12, 8-byte seconds, followed
1896                          * by 4-byte fractional time in nanoseconds,
1897                          * both little-endian.
1898                          *
1899                          * If the length is 8, 4-byte seconds, followed
1900                          * by 4-byte fractional time in nanoseconds,
1901                          * both little-endian.
1902                          *
1903                          * For absolute times, the seconds are seconds
1904                          * since the UN*X epoch.
1905                          */
1906                         if (length == 16) {
1907                                 time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
1908                                 time_stamp->nsecs = (guint32)tvb_get_letoh64(tvb, start+8);
1909                         } else if (length == 12) {
1910                                 time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
1911                                 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1912                         } else if (length == 8) {
1913                                 time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
1914                                 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1915                         } else if (length == 4) {
1916                                 /*
1917                                  * Backwards compatibility.
1918                                  * ENC_TIME_SECS_NSECS is 0; using
1919                                  * ENC_LITTLE_ENDIAN by itself with a 4-byte
1920                                  * time-in-seconds value was done in the
1921                                  * past.
1922                                  */
1923                                 time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
1924                                 time_stamp->nsecs = 0;
1925                         } else {
1926                                 time_stamp->secs  = 0;
1927                                 time_stamp->nsecs = 0;
1928                                 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1929                         }
1930                         break;
1931
1932                 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1933                         /*
1934                          * NTP time stamp, big-endian.
1935                          * Only supported for absolute times.
1936                          */
1937                         DISSECTOR_ASSERT(!is_relative);
1938
1939                         /* We need a temporary variable here so the unsigned math
1940                          * works correctly (for years > 2036 according to RFC 2030
1941                          * chapter 3).
1942                          *
1943                          * If bit 0 is set, the UTC time is in the range 1968-2036 and
1944                          * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
1945                          * If bit 0 is not set, the time is in the range 2036-2104 and
1946                          * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
1947                          */
1948                         tmpsecs  = tvb_get_ntohl(tvb, start);
1949                         if ((tmpsecs & 0x80000000) != 0)
1950                                 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
1951                         else
1952                                 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
1953
1954                         if (length == 8) {
1955                                 /*
1956                                  * Convert 1/2^32s of a second to nanoseconds.
1957                                  */
1958                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1959                                 if ((time_stamp->nsecs == 0) && (tmpsecs == 0)) {
1960                                         //This is "NULL" time
1961                                         time_stamp->secs = 0;
1962                                 }
1963                         } else if (length == 4) {
1964                                 /*
1965                                  * Backwards compatibility.
1966                                  */
1967                                 if (tmpsecs == 0) {
1968                                         //This is "NULL" time
1969                                         time_stamp->secs = 0;
1970                                 }
1971                                 time_stamp->nsecs = 0;
1972                         } else {
1973                                 time_stamp->secs  = 0;
1974                                 time_stamp->nsecs = 0;
1975                                 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
1976                         }
1977                         break;
1978
1979                 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1980                         /*
1981                          * NTP time stamp, little-endian.
1982                          * Only supported for absolute times.
1983                          */
1984                         DISSECTOR_ASSERT(!is_relative);
1985
1986                         /* We need a temporary variable here so the unsigned math
1987                          * works correctly (for years > 2036 according to RFC 2030
1988                          * chapter 3).
1989                          *
1990                          * If bit 0 is set, the UTC time is in the range 1968-2036 and
1991                          * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
1992                          * If bit 0 is not set, the time is in the range 2036-2104 and
1993                          * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
1994                          */
1995                         tmpsecs  = tvb_get_letohl(tvb, start);
1996                         if ((tmpsecs & 0x80000000) != 0)
1997                                 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
1998                         else
1999                                 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2000
2001                         if (length == 8) {
2002                                 /*
2003                                  * Convert 1/2^32s of a second to nanoseconds.
2004                                  */
2005                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2006                                 if ((time_stamp->nsecs == 0) && (tmpsecs == 0)) {
2007                                         //This is "NULL" time
2008                                         time_stamp->secs = 0;
2009                                 }
2010                         } else if (length == 4) {
2011                                 /*
2012                                  * Backwards compatibility.
2013                                  */
2014                                 if (tmpsecs == 0) {
2015                                         //This is "NULL" time
2016                                         time_stamp->secs = 0;
2017                                 }
2018                                 time_stamp->nsecs = 0;
2019                         } else {
2020                                 time_stamp->secs  = 0;
2021                                 time_stamp->nsecs = 0;
2022                                 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2023                         }
2024                         break;
2025
2026                 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
2027                         /*
2028                          * S/3x0 and z/Architecture TOD clock time stamp,
2029                          * big-endian.  The epoch is January 1, 1900,
2030                          * 00:00:00 (proleptic?) UTC.
2031                          *
2032                          * Only supported for absolute times.
2033                          */
2034                         DISSECTOR_ASSERT(!is_relative);
2035                         DISSECTOR_ASSERT(length == 8);
2036
2037                         if (length == 8) {
2038                                 todusecs  = tvb_get_ntoh64(tvb, start) >> 12;
2039                                 time_stamp->secs = (time_t)((todusecs  / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
2040                                 time_stamp->nsecs = (int)((todusecs  % 1000000) * 1000);
2041                         } else {
2042                                 time_stamp->secs  = 0;
2043                                 time_stamp->nsecs = 0;
2044                                 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2045                         }
2046                         break;
2047
2048                 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
2049                         /*
2050                          * S/3x0 and z/Architecture TOD clock time stamp,
2051                          * little-endian.  The epoch is January 1, 1900,
2052                          * 00:00:00 (proleptic?) UTC.
2053                          *
2054                          * Only supported for absolute times.
2055                          */
2056                         DISSECTOR_ASSERT(!is_relative);
2057
2058                         if (length == 8) {
2059                                 todusecs  = tvb_get_letoh64(tvb, start) >> 12 ;
2060                                 time_stamp->secs = (time_t)((todusecs  / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
2061                                 time_stamp->nsecs = (int)((todusecs  % 1000000) * 1000);
2062                         } else {
2063                                 time_stamp->secs  = 0;
2064                                 time_stamp->nsecs = 0;
2065                                 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2066                         }
2067                         break;
2068
2069                 case ENC_TIME_RTPS|ENC_BIG_ENDIAN:
2070                         /*
2071                          * Time stamp using the same seconds/fraction format
2072                          * as NTP, but with the origin of the time stamp being
2073                          * the UNIX epoch rather than the NTP epoch; big-
2074                          * endian.
2075                          *
2076                          * Only supported for absolute times.
2077                          */
2078                         DISSECTOR_ASSERT(!is_relative);
2079
2080                         if (length == 8) {
2081                                 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2082                                 /*
2083                                  * Convert 1/2^32s of a second to nanoseconds.
2084                                  */
2085                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2086                         } else {
2087                                 time_stamp->secs  = 0;
2088                                 time_stamp->nsecs = 0;
2089                                 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2090                         }
2091                         break;
2092
2093                 case ENC_TIME_RTPS|ENC_LITTLE_ENDIAN:
2094                         /*
2095                          * Time stamp using the same seconds/fraction format
2096                          * as NTP, but with the origin of the time stamp being
2097                          * the UNIX epoch rather than the NTP epoch; little-
2098                          * endian.
2099                          *
2100                          * Only supported for absolute times.
2101                          */
2102                         DISSECTOR_ASSERT(!is_relative);
2103
2104                         if (length == 8) {
2105                                 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2106                                 /*
2107                                  * Convert 1/2^32s of a second to nanoseconds.
2108                                  */
2109                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2110                         } else {
2111                                 time_stamp->secs  = 0;
2112                                 time_stamp->nsecs = 0;
2113                                 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2114                         }
2115                         break;
2116
2117                 case ENC_TIME_MIP6 | ENC_BIG_ENDIAN:
2118                         /*
2119                         * MIP6 time stamp, big-endian.
2120                         * A 64-bit unsigned integer field containing a timestamp.  The
2121                         * value indicates the number of seconds since January 1, 1970,
2122                         * 00:00 UTC, by using a fixed point format.  In this format, the
2123                         * integer number of seconds is contained in the first 48 bits of
2124                         * the field, and the remaining 16 bits indicate the number of
2125                         * 1/65536 fractions of a second.
2126
2127                         * Only supported for absolute times.
2128                         */
2129                         DISSECTOR_ASSERT(!is_relative);
2130
2131                         if (length == 8) {
2132                                 /* We need a temporary variable here so the casting and fractions
2133                                 * of a second work correctly.
2134                                 */
2135                                 tmp64secs = tvb_get_ntoh48(tvb, start);
2136                                 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2137                                 tmpsecs <<= 16;
2138
2139                                 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2140                                         //This is "NULL" time
2141                                         time_stamp->secs = 0;
2142                                         time_stamp->nsecs = 0;
2143                                 } else {
2144                                         time_stamp->secs = (time_t)tmp64secs;
2145                                         time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2146                                 }
2147                         } else {
2148                                 time_stamp->secs = 0;
2149                                 time_stamp->nsecs = 0;
2150                                 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2151                         }
2152                         break;
2153
2154                 case ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN:
2155                         /*
2156                          * 4-byte seconds, followed by 4-byte fractional
2157                          * time in microseconds, both big-endian.
2158                          * For absolute times, the seconds are seconds
2159                          * since the UN*X epoch.
2160                          */
2161                         if (length == 8) {
2162                                 time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
2163                                 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2164                         } else {
2165                                 time_stamp->secs  = 0;
2166                                 time_stamp->nsecs = 0;
2167                                 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2168                         }
2169                         break;
2170
2171                 case ENC_TIME_SECS_USECS|ENC_LITTLE_ENDIAN:
2172                         /*
2173                          * 4-byte seconds, followed by 4-byte fractional
2174                          * time in microseconds, both little-endian.
2175                          * For absolute times, the seconds are seconds
2176                          * since the UN*X epoch.
2177                          */
2178                         if (length == 8) {
2179                                 time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
2180                                 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2181                         } else {
2182                                 time_stamp->secs  = 0;
2183                                 time_stamp->nsecs = 0;
2184                                 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2185                         }
2186                         break;
2187
2188                 case ENC_TIME_SECS|ENC_BIG_ENDIAN:
2189                 case ENC_TIME_SECS|ENC_LITTLE_ENDIAN:
2190                         /*
2191                          * Seconds, 1 to 8 bytes.
2192                          * For absolute times, it's seconds since the
2193                          * UN*X epoch.
2194                          */
2195                         if (length >= 1 && length <= 8) {
2196                                 time_stamp->secs  = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2197                                 time_stamp->nsecs = 0;
2198                         } else {
2199                                 time_stamp->secs  = 0;
2200                                 time_stamp->nsecs = 0;
2201                                 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2202                         }
2203                         break;
2204
2205                 case ENC_TIME_MSECS|ENC_BIG_ENDIAN:
2206                 case ENC_TIME_MSECS|ENC_LITTLE_ENDIAN:
2207                         /*
2208                          * Milliseconds, 1 to 8 bytes.
2209                          * For absolute times, it's milliseconds since the
2210                          * UN*X epoch.
2211                          */
2212                         if (length >= 1 && length <= 8) {
2213                                 guint64 msecs;
2214
2215                                 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2216                                 time_stamp->secs  = (time_t)(msecs / 1000);
2217                                 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2218                         } else {
2219                                 time_stamp->secs  = 0;
2220                                 time_stamp->nsecs = 0;
2221                                 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2222                         }
2223                         break;
2224
2225                 case ENC_TIME_NSECS|ENC_BIG_ENDIAN:
2226                 case ENC_TIME_NSECS|ENC_LITTLE_ENDIAN:
2227                         /*
2228                          * nanoseconds, 1 to 8 bytes.
2229                          * For absolute times, it's nanoseconds since the
2230                          * UN*X epoch.
2231                          */
2232
2233                         if (length >= 1 && length <= 8) {
2234                                 guint64 nsecs;
2235
2236                                 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2237                                 time_stamp->secs  = (time_t)(nsecs / 1000000000);
2238                                 time_stamp->nsecs = (int)(nsecs % 1000000000);
2239                         } else {
2240                                 time_stamp->secs  = 0;
2241                                 time_stamp->nsecs = 0;
2242                                 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2243                         }
2244                         break;
2245
2246                 case ENC_TIME_RFC_3971|ENC_BIG_ENDIAN:
2247                         /*
2248                          * 1/64ths of a second since the UN*X epoch,
2249                          * big-endian.
2250                          *
2251                          * Only supported for absolute times.
2252                          */
2253                         DISSECTOR_ASSERT(!is_relative);
2254
2255                         if (length == 8) {
2256                                 /*
2257                                  * The upper 48 bits are seconds since the
2258                                  * UN*X epoch.
2259                                  */
2260                                 time_stamp->secs  = (time_t)tvb_get_ntoh48(tvb, start);
2261                                 /*
2262                                  * The lower 16 bits are 1/2^16s of a second;
2263                                  * convert them to nanoseconds.
2264                                  *
2265                                  * XXX - this may give the impression of higher
2266                                  * precision than you actually get.
2267                                  */
2268                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2269                         } else {
2270                                 time_stamp->secs  = 0;
2271                                 time_stamp->nsecs = 0;
2272                                 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2273                         }
2274                         break;
2275
2276                 case ENC_TIME_RFC_3971|ENC_LITTLE_ENDIAN:
2277                         /*
2278                          * 1/64ths of a second since the UN*X epoch,
2279                          * little-endian.
2280                          *
2281                          * Only supported for absolute times.
2282                          */
2283                         DISSECTOR_ASSERT(!is_relative);
2284
2285                         if (length == 8) {
2286                                 /*
2287                                  * XXX - this is assuming that, if anybody
2288                                  * were ever to use this format - RFC 3971
2289                                  * doesn't, because that's an Internet
2290                                  * protocol, and those use network byte
2291                                  * order, i.e. big-endian - they'd treat it
2292                                  * as a 64-bit count of 1/2^16s of a second,
2293                                  * putting the upper 48 bits at the end.
2294                                  *
2295                                  * The lower 48 bits are seconds since the
2296                                  * UN*X epoch.
2297                                  */
2298                                 time_stamp->secs  = (time_t)tvb_get_letoh48(tvb, start+2);
2299                                 /*
2300                                  * The upper 16 bits are 1/2^16s of a second;
2301                                  * convert them to nanoseconds.
2302                                  *
2303                                  * XXX - this may give the impression of higher
2304                                  * precision than you actually get.
2305                                  */
2306                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2307                         } else {
2308                                 time_stamp->secs  = 0;
2309                                 time_stamp->nsecs = 0;
2310                                 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2311                         }
2312                         break;
2313
2314                 case ENC_TIME_SECS_NTP|ENC_BIG_ENDIAN:
2315                         /*
2316                          * NTP time stamp, with 1-second resolution (i.e.,
2317                          * seconds since the NTP epoch), big-endian.
2318                          * Only supported for absolute times.
2319                          */
2320                         DISSECTOR_ASSERT(!is_relative);
2321
2322                         if (length == 4) {
2323                                 /*
2324                                 * We need a temporary variable here so the unsigned math
2325                                 * works correctly (for years > 2036 according to RFC 2030
2326                                 * chapter 3).
2327                                 *
2328                                 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2329                                 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2330                                 * If bit 0 is not set, the time is in the range 2036-2104 and
2331                                 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2332                                 */
2333                                 tmpsecs  = tvb_get_ntohl(tvb, start);
2334                                 if ((tmpsecs & 0x80000000) != 0)
2335                                         time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2336                                 else
2337                                         time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2338                                 time_stamp->nsecs = 0;
2339                         } else {
2340                                 time_stamp->secs  = 0;
2341                                 time_stamp->nsecs = 0;
2342                                 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2343                         }
2344                         break;
2345
2346                 case ENC_TIME_SECS_NTP|ENC_LITTLE_ENDIAN:
2347                         /*
2348                          * NTP time stamp, with 1-second resolution (i.e.,
2349                          * seconds since the NTP epoch), little-endian.
2350                          * Only supported for absolute times.
2351                          */
2352                         DISSECTOR_ASSERT(!is_relative);
2353
2354                         /*
2355                          * We need a temporary variable here so the unsigned math
2356                          * works correctly (for years > 2036 according to RFC 2030
2357                          * chapter 3).
2358                          *
2359                          * If bit 0 is set, the UTC time is in the range 1968-2036 and
2360                          * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2361                          * If bit 0 is not set, the time is in the range 2036-2104 and
2362                          * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2363                          */
2364                         if (length == 4) {
2365                                 tmpsecs  = tvb_get_letohl(tvb, start);
2366                                 if ((tmpsecs & 0x80000000) != 0)
2367                                         time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2368                                 else
2369                                         time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2370                                 time_stamp->nsecs = 0;
2371                         } else {
2372                                 time_stamp->secs  = 0;
2373                                 time_stamp->nsecs = 0;
2374                                 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2375                         }
2376                         break;
2377                 case ENC_TIME_MSEC_NTP | ENC_BIG_ENDIAN:
2378                         /*
2379                         * Milliseconds, 1 to 8 bytes.
2380                         * For absolute times, it's milliseconds since the
2381                         * NTP epoch.
2382                         */
2383                         if (length >= 1 && length <= 8) {
2384                                 guint64 msecs;
2385
2386                                 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2387                                 tmpsecs = (guint32)(msecs / 1000);
2388                                 /*
2389                                 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2390                                 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2391                                 * If bit 0 is not set, the time is in the range 2036-2104 and
2392                                 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2393                                 */
2394                                 if ((tmpsecs & 0x80000000) != 0)
2395                                         time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2396                                 else
2397                                         time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2398                                 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2399                         }
2400                         else {
2401                                 time_stamp->secs  = 0;
2402                                 time_stamp->nsecs = 0;
2403                                 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 4));
2404                         }
2405                         break;
2406
2407                 case ENC_TIME_CLASSIC_MAC_OS_SECS|ENC_BIG_ENDIAN:
2408                         /*
2409                          * Classic Mac OS time stamps, big-endian.
2410                          * Only supported for absolute times.
2411                          */
2412                         DISSECTOR_ASSERT(!is_relative);
2413
2414                         if (length == 8) {
2415                                 tmp64secs  = tvb_get_ntoh64(tvb, start);
2416                                 time_stamp->secs = (time_t)(gint64)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
2417                                 time_stamp->nsecs = 0;
2418                         } else if (length == 4) {
2419                                 tmpsecs  = tvb_get_ntohl(tvb, start);
2420                                 time_stamp->secs = (time_t)(gint32)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
2421                                 time_stamp->nsecs = 0;
2422                         } else {
2423                                 time_stamp->secs  = 0;
2424                                 time_stamp->nsecs = 0;
2425                                 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2426                         }
2427                         break;
2428
2429                 default:
2430                         DISSECTOR_ASSERT_NOT_REACHED();
2431                         break;
2432         }
2433 }
2434
2435 static void
2436 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2437 {
2438         const header_field_info *hfinfo = fi->hfinfo;
2439
2440         if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
2441                 GPtrArray *ptrs = NULL;
2442
2443                 if (tree_data->interesting_hfids == NULL) {
2444                         /* Initialize the hash because we now know that it is needed */
2445                         tree_data->interesting_hfids =
2446                                 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
2447                 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2448                         ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2449                                            GINT_TO_POINTER(hfinfo->id));
2450                 }
2451
2452                 if (!ptrs) {
2453                         /* First element triggers the creation of pointer array */
2454                         ptrs = g_ptr_array_new();
2455                         g_hash_table_insert(tree_data->interesting_hfids,
2456                                             GINT_TO_POINTER(hfinfo->id), ptrs);
2457                 }
2458
2459                 g_ptr_array_add(ptrs, fi);
2460         }
2461 }
2462
2463
2464 /*
2465  * Validates that field length bytes are available starting from
2466  * start (pos/neg). Throws an exception if they aren't.
2467  */
2468 static void
2469 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2470             gint start, gint length, const guint encoding)
2471 {
2472         gint size = length;
2473
2474         if (!tvb)
2475                 return;
2476
2477         if ((hfinfo->type == FT_STRINGZ) ||
2478             ((encoding & (ENC_VARIANT_MASK)) &&
2479              (IS_FT_UINT(hfinfo->type) || IS_FT_INT(hfinfo->type)))) {
2480                 /* If we're fetching until the end of the TVB, only validate
2481                  * that the offset is within range.
2482                  */
2483                 if (length == -1)
2484                         size = 0;
2485         }
2486
2487         tvb_ensure_bytes_exist(tvb, start, size);
2488 }
2489
2490 static void
2491 detect_trailing_stray_characters(guint encoding, const char *string, gint length, proto_item *pi)
2492 {
2493         gboolean found_stray_character = FALSE;
2494
2495         if (!string)
2496                 return;
2497
2498         switch (encoding & ENC_CHARENCODING_MASK) {
2499                 case ENC_ASCII:
2500                 case ENC_UTF_8:
2501                         for (gint i = (gint)strlen(string); i < length; i++) {
2502                                 if (string[i] != '\0') {
2503                                         found_stray_character = TRUE;
2504                                         break;
2505                                 }
2506                         }
2507                         break;
2508
2509                 default:
2510                         break;
2511         }
2512
2513         if (found_stray_character) {
2514                 expert_add_info(NULL, pi, &ei_string_trailing_characters);
2515         }
2516 }
2517
2518 /* Add an item to a proto_tree, using the text label registered to that item;
2519    the item is extracted from the tvbuff handed to it. */
2520 static proto_item *
2521 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2522                     tvbuff_t *tvb, gint start, gint length,
2523                     guint encoding)
2524 {
2525         proto_item *pi;
2526         guint32     value, n;
2527         guint64     value64;
2528         ws_in4_addr ipv4_value;
2529         float       floatval;
2530         double      doubleval;
2531         const char *stringval = NULL;
2532         nstime_t    time_stamp;
2533         gboolean    length_error;
2534
2535         switch (new_fi->hfinfo->type) {
2536                 case FT_NONE:
2537                         /* no value to set for FT_NONE */
2538                         break;
2539
2540                 case FT_PROTOCOL:
2541                         proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
2542                         break;
2543
2544                 case FT_BYTES:
2545                         proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2546                         break;
2547
2548                 case FT_UINT_BYTES:
2549                         n = get_uint_value(tree, tvb, start, length, encoding);
2550                         proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2551
2552                         /* Instead of calling proto_item_set_len(), since we don't yet
2553                          * have a proto_item, we set the field_info's length ourselves. */
2554                         new_fi->length = n + length;
2555                         break;
2556
2557                 case FT_BOOLEAN:
2558                         /*
2559                          * Map all non-zero values to little-endian for
2560                          * backwards compatibility.
2561                          */
2562                         if (encoding)
2563                                 encoding = ENC_LITTLE_ENDIAN;
2564                         proto_tree_set_boolean(new_fi,
2565                                 get_uint64_value(tree, tvb, start, length, encoding));
2566                         break;
2567
2568                 case FT_CHAR:
2569                 /* XXX - make these just FT_UINT? */
2570                 case FT_UINT8:
2571                 case FT_UINT16:
2572                 case FT_UINT24:
2573                 case FT_UINT32:
2574                         if (encoding & ENC_VARINT_PROTOBUF) {
2575                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2576                                 new_fi->flags |= FI_VARINT;
2577                                 value = (guint32)value64;
2578                         } else if (encoding & ENC_VARINT_QUIC) {
2579                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2580                                 value = (guint32)value64;
2581                         } else if (encoding & ENC_VARINT_ZIGZAG) {
2582                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2583                                 new_fi->flags |= FI_VARINT;
2584                                 value = (guint32)value64;
2585                         }
2586                         else {
2587                                 /*
2588                                  * Map all non-zero values to little-endian for
2589                                  * backwards compatibility.
2590                                  */
2591                                 if (encoding)
2592                                         encoding = ENC_LITTLE_ENDIAN;
2593
2594                                 value = get_uint_value(tree, tvb, start, length, encoding);
2595                         }
2596                         proto_tree_set_uint(new_fi, value);
2597                         break;
2598
2599                 case FT_UINT40:
2600                 case FT_UINT48:
2601                 case FT_UINT56:
2602                 case FT_UINT64:
2603
2604                         if (encoding & ENC_VARINT_PROTOBUF) {
2605                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2606                                 new_fi->flags |= FI_VARINT;
2607                         } else if (encoding & ENC_VARINT_QUIC) {
2608                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2609                         } else if (encoding & ENC_VARINT_ZIGZAG) {
2610                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2611                                 new_fi->flags |= FI_VARINT;
2612                         }
2613                         else {
2614                                 /*
2615                                  * Map all other non-zero values to little-endian for
2616                                  * backwards compatibility.
2617                                  */
2618                                 if (encoding)
2619                                         encoding = ENC_LITTLE_ENDIAN;
2620
2621                                 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2622                         }
2623                         proto_tree_set_uint64(new_fi, value64);
2624                         break;
2625
2626                 /* XXX - make these just FT_INT? */
2627                 case FT_INT8:
2628                 case FT_INT16:
2629                 case FT_INT24:
2630                 case FT_INT32:
2631                         /*
2632                          * Map all non-zero values to little-endian for
2633                          * backwards compatibility.
2634                          */
2635                         if (encoding)
2636                                 encoding = ENC_LITTLE_ENDIAN;
2637                         proto_tree_set_int(new_fi,
2638                                 get_int_value(tree, tvb, start, length, encoding));
2639                         break;
2640
2641                 case FT_INT40:
2642                 case FT_INT48:
2643                 case FT_INT56:
2644                 case FT_INT64:
2645                         /*
2646                          * Map all non-zero values to little-endian for
2647                          * backwards compatibility.
2648                          */
2649                         if (encoding)
2650                                 encoding = ENC_LITTLE_ENDIAN;
2651                         proto_tree_set_int64(new_fi,
2652                                 get_int64_value(tree, tvb, start, length, encoding));
2653                         break;
2654
2655                 case FT_IPv4:
2656                         /*
2657                          * Map all non-zero values to little-endian for
2658                          * backwards compatibility.
2659                          */
2660                         if (encoding)
2661                                 encoding = ENC_LITTLE_ENDIAN;
2662                         if (length != FT_IPv4_LEN) {
2663                                 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
2664                                 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2665                         }
2666                         ipv4_value = tvb_get_ipv4(tvb, start);
2667                         /*
2668                          * NOTE: to support code written when
2669                          * proto_tree_add_item() took a gboolean as its
2670                          * last argument, with FALSE meaning "big-endian"
2671                          * and TRUE meaning "little-endian", we treat any
2672                          * non-zero value of "encoding" as meaning
2673                          * "little-endian".
2674                          */
2675                         proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value) : ipv4_value);
2676                         break;
2677
2678                 case FT_IPXNET:
2679                         if (length != FT_IPXNET_LEN) {
2680                                 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
2681                                 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2682                         }
2683                         proto_tree_set_ipxnet(new_fi,
2684                                 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
2685                         break;
2686
2687                 case FT_IPv6:
2688                         if (length != FT_IPv6_LEN) {
2689                                 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
2690                                 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2691                         }
2692                         proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2693                         break;
2694
2695                 case FT_FCWWN:
2696                         if (length != FT_FCWWN_LEN) {
2697                                 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2698                                 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2699                         }
2700                         proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2701                         break;
2702
2703                 case FT_AX25:
2704                         if (length != 7) {
2705                                 length_error = length < 7 ? TRUE : FALSE;
2706                                 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2707                         }
2708                         proto_tree_set_ax25_tvb(new_fi, tvb, start);
2709                         break;
2710
2711                 case FT_VINES:
2712                         if (length != VINES_ADDR_LEN) {
2713                                 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2714                                 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2715                         }
2716                         proto_tree_set_vines_tvb(new_fi, tvb, start);
2717                         break;
2718
2719                 case FT_ETHER:
2720                         if (length != FT_ETHER_LEN) {
2721                                 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2722                                 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2723                         }
2724                         proto_tree_set_ether_tvb(new_fi, tvb, start);
2725                         break;
2726
2727                 case FT_EUI64:
2728                         /*
2729                          * Map all non-zero values to little-endian for
2730                          * backwards compatibility.
2731                          */
2732                         if (encoding)
2733                                 encoding = ENC_LITTLE_ENDIAN;
2734                         if (length != FT_EUI64_LEN) {
2735                                 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2736                                 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2737                         }
2738                         proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2739                         break;
2740                 case FT_GUID:
2741                         /*
2742                          * Map all non-zero values to little-endian for
2743                          * backwards compatibility.
2744                          */
2745                         if (encoding)
2746                                 encoding = ENC_LITTLE_ENDIAN;
2747                         if (length != FT_GUID_LEN) {
2748                                 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2749                                 report_type_length_mismatch(tree, "a GUID", length, length_error);
2750                         }
2751                         proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2752                         break;
2753
2754                 case FT_OID:
2755                 case FT_REL_OID:
2756                         proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2757                         break;
2758
2759                 case FT_SYSTEM_ID:
2760                         proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2761                         break;
2762
2763                 case FT_FLOAT:
2764                         /*
2765                          * NOTE: to support code written when
2766                          * proto_tree_add_item() took a gboolean as its
2767                          * last argument, with FALSE meaning "big-endian"
2768                          * and TRUE meaning "little-endian", we treat any
2769                          * non-zero value of "encoding" as meaning
2770                          * "little-endian".
2771                          *
2772                          * At some point in the future, we might
2773                          * support non-IEEE-binary floating-point
2774                          * formats in the encoding as well
2775                          * (IEEE decimal, System/3x0, VAX).
2776                          */
2777                         if (encoding)
2778                                 encoding = ENC_LITTLE_ENDIAN;
2779                         if (length != 4) {
2780                                 length_error = length < 4 ? TRUE : FALSE;
2781                                 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2782                         }
2783                         if (encoding)
2784                                 floatval = tvb_get_letohieee_float(tvb, start);
2785                         else
2786                                 floatval = tvb_get_ntohieee_float(tvb, start);
2787                         proto_tree_set_float(new_fi, floatval);
2788                         break;
2789
2790                 case FT_DOUBLE:
2791                         /*
2792                          * NOTE: to support code written when
2793                          * proto_tree_add_item() took a gboolean as its
2794                          * last argument, with FALSE meaning "big-endian"
2795                          * and TRUE meaning "little-endian", we treat any
2796                          * non-zero value of "encoding" as meaning
2797                          * "little-endian".
2798                          *
2799                          * At some point in the future, we might
2800                          * support non-IEEE-binary floating-point
2801                          * formats in the encoding as well
2802                          * (IEEE decimal, System/3x0, VAX).
2803                          */
2804                         if (encoding == TRUE)
2805                                 encoding = ENC_LITTLE_ENDIAN;
2806                         if (length != 8) {
2807                                 length_error = length < 8 ? TRUE : FALSE;
2808                                 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2809                         }
2810                         if (encoding)
2811                                 doubleval = tvb_get_letohieee_double(tvb, start);
2812                         else
2813                                 doubleval = tvb_get_ntohieee_double(tvb, start);
2814                         proto_tree_set_double(new_fi, doubleval);
2815                         break;
2816
2817                 case FT_STRING:
2818                         stringval = get_string_value(wmem_packet_scope(),
2819                             tvb, start, length, &length, encoding);
2820                         proto_tree_set_string(new_fi, stringval);
2821
2822                         /* Instead of calling proto_item_set_len(), since we
2823                          * don't yet have a proto_item, we set the
2824                          * field_info's length ourselves.
2825                          *
2826                          * XXX - our caller can't use that length to
2827                          * advance an offset unless they arrange that
2828                          * there always be a protocol tree into which
2829                          * we're putting this item.
2830                          */
2831                         new_fi->length = length;
2832                         break;
2833
2834                 case FT_STRINGZ:
2835                         stringval = get_stringz_value(wmem_packet_scope(),
2836                             tree, tvb, start, length, &length, encoding);
2837                         proto_tree_set_string(new_fi, stringval);
2838
2839                         /* Instead of calling proto_item_set_len(),
2840                          * since we don't yet have a proto_item, we
2841                          * set the field_info's length ourselves.
2842                          *
2843                          * XXX - our caller can't use that length to
2844                          * advance an offset unless they arrange that
2845                          * there always be a protocol tree into which
2846                          * we're putting this item.
2847                          */
2848                         new_fi->length = length;
2849                         break;
2850
2851                 case FT_UINT_STRING:
2852                         /*
2853                          * NOTE: to support code written when
2854                          * proto_tree_add_item() took a gboolean as its
2855                          * last argument, with FALSE meaning "big-endian"
2856                          * and TRUE meaning "little-endian", if the
2857                          * encoding value is TRUE, treat that as
2858                          * ASCII with a little-endian length.
2859                          *
2860                          * This won't work for code that passes
2861                          * arbitrary non-zero values; that code
2862                          * will need to be fixed.
2863                          */
2864                         if (encoding == TRUE)
2865                                 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2866                         stringval = get_uint_string_value(wmem_packet_scope(),
2867                             tree, tvb, start, length, &length, encoding);
2868                         proto_tree_set_string(new_fi, stringval);
2869
2870                         /* Instead of calling proto_item_set_len(), since we
2871                          * don't yet have a proto_item, we set the
2872                          * field_info's length ourselves.
2873                          *
2874                          * XXX - our caller can't use that length to
2875                          * advance an offset unless they arrange that
2876                          * there always be a protocol tree into which
2877                          * we're putting this item.
2878                          */
2879                         new_fi->length = length;
2880                         break;
2881
2882                 case FT_STRINGZPAD:
2883                         stringval = get_stringzpad_value(wmem_packet_scope(),
2884                             tvb, start, length, &length, encoding);
2885                         proto_tree_set_string(new_fi, stringval);
2886
2887                         /* Instead of calling proto_item_set_len(), since we
2888                          * don't yet have a proto_item, we set the
2889                          * field_info's length ourselves.
2890                          *
2891                          * XXX - our caller can't use that length to
2892                          * advance an offset unless they arrange that
2893                          * there always be a protocol tree into which
2894                          * we're putting this item.
2895                          */
2896                         new_fi->length = length;
2897                         break;
2898
2899                 case FT_STRINGZTRUNC:
2900                         stringval = get_stringztrunc_value(wmem_packet_scope(),
2901                             tvb, start, length, &length, encoding);
2902                         proto_tree_set_string(new_fi, stringval);
2903
2904                         /* Instead of calling proto_item_set_len(), since we
2905                          * don't yet have a proto_item, we set the
2906                          * field_info's length ourselves.
2907                          *
2908                          * XXX - our caller can't use that length to
2909                          * advance an offset unless they arrange that
2910                          * there always be a protocol tree into which
2911                          * we're putting this item.
2912                          */
2913                         new_fi->length = length;
2914                         break;
2915
2916                 case FT_ABSOLUTE_TIME:
2917                         /*
2918                          * Absolute times can be in any of a number of
2919                          * formats, and they can be big-endian or
2920                          * little-endian.
2921                          *
2922                          * Historically FT_TIMEs were only timespecs;
2923                          * the only question was whether they were stored
2924                          * in big- or little-endian format.
2925                          *
2926                          * For backwards compatibility, we interpret an
2927                          * encoding of 1 as meaning "little-endian timespec",
2928                          * so that passing TRUE is interpreted as that.
2929                          */
2930                         if (encoding == TRUE)
2931                                 encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2932
2933                         get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
2934
2935                         proto_tree_set_time(new_fi, &time_stamp);
2936                         break;
2937
2938                 case FT_RELATIVE_TIME:
2939                         /*
2940                          * Relative times can be in any of a number of
2941                          * formats, and they can be big-endian or
2942                          * little-endian.
2943                          *
2944                          * Historically FT_TIMEs were only timespecs;
2945                          * the only question was whether they were stored
2946                          * in big- or little-endian format.
2947                          *
2948                          * For backwards compatibility, we interpret an
2949                          * encoding of 1 as meaning "little-endian timespec",
2950                          * so that passing TRUE is interpreted as that.
2951                          */
2952                         if (encoding == TRUE)
2953                                 encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2954
2955                         get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
2956
2957                         proto_tree_set_time(new_fi, &time_stamp);
2958                         break;
2959                 case FT_IEEE_11073_SFLOAT:
2960                         if (encoding)
2961                                 encoding = ENC_LITTLE_ENDIAN;
2962                         if (length != 2) {
2963                                 length_error = length < 2 ? TRUE : FALSE;
2964                                 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2965                         }
2966
2967                         fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2968
2969                         break;
2970                 case FT_IEEE_11073_FLOAT:
2971                         if (encoding)
2972                                 encoding = ENC_LITTLE_ENDIAN;
2973                         if (length != 4) {
2974                                 length_error = length < 4 ? TRUE : FALSE;
2975                                 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2976                         }
2977
2978                         break;
2979                 default:
2980                         REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",
2981                                              new_fi->hfinfo->abbrev,
2982                                              new_fi->hfinfo->type,
2983                                              ftype_name(new_fi->hfinfo->type));
2984                         break;
2985         }
2986         FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2987
2988         /* Don't add new node to proto_tree until now so that any exceptions
2989          * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2990         /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2991          *      to know which item caused exception? */
2992         pi = proto_tree_add_node(tree, new_fi);
2993
2994         switch (new_fi->hfinfo->type) {
2995
2996         case FT_STRING:
2997                 detect_trailing_stray_characters(encoding, stringval, length, pi);
2998                 break;
2999
3000         default:
3001                 break;
3002         }
3003
3004         return pi;
3005 }
3006
3007 proto_item *
3008 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3009                             const gint start, gint length,
3010                             const guint encoding, gint32 *retval)
3011 {
3012         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3013         field_info        *new_fi;
3014         gint32             value;
3015
3016         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3017
3018         switch (hfinfo->type) {
3019         case FT_INT8:
3020         case FT_INT16:
3021         case FT_INT24:
3022         case FT_INT32:
3023                 break;
3024         case FT_INT64:
3025                 REPORT_DISSECTOR_BUG("64-bit signed integer field %s used with proto_tree_add_item_ret_int()",
3026                     hfinfo->abbrev);
3027         default:
3028                 REPORT_DISSECTOR_BUG("Non-signed-integer field %s used with proto_tree_add_item_ret_int()",
3029                     hfinfo->abbrev);
3030         }
3031
3032         /* length validation for native number encoding caught by get_uint_value() */
3033         /* length has to be -1 or > 0 regardless of encoding */
3034         if (length < -1 || length == 0)
3035                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_int",
3036                         length);
3037
3038         if (encoding & ENC_STRING) {
3039                 REPORT_DISSECTOR_BUG("wrong encoding");
3040         }
3041         /* I believe it's ok if this is called with a NULL tree */
3042         value = get_int_value(tree, tvb, start, length, encoding);
3043
3044         if (retval) {
3045                 gint no_of_bits;
3046                 *retval = value;
3047                 if (hfinfo->bitmask) {
3048                         /* Mask out irrelevant portions */
3049                         *retval &= (guint32)(hfinfo->bitmask);
3050                         /* Shift bits */
3051                         *retval >>= hfinfo_bitshift(hfinfo);
3052                 }
3053                 no_of_bits = ws_count_ones(hfinfo->bitmask);
3054                 *retval = ws_sign_ext32(*retval, no_of_bits);
3055         }
3056
3057         CHECK_FOR_NULL_TREE(tree);
3058
3059         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3060
3061         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3062
3063         proto_tree_set_int(new_fi, value);
3064
3065         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3066
3067         return proto_tree_add_node(tree, new_fi);
3068 }
3069
3070 proto_item *
3071 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3072                              const gint start, gint length,
3073                              const guint encoding, guint32 *retval)
3074 {
3075         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3076         field_info        *new_fi;
3077         guint32            value;
3078
3079         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3080
3081         switch (hfinfo->type) {
3082         case FT_CHAR:
3083         case FT_UINT8:
3084         case FT_UINT16:
3085         case FT_UINT24:
3086         case FT_UINT32:
3087                 break;
3088         default:
3089                 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
3090                     hfinfo->abbrev);
3091         }
3092
3093         /* length validation for native number encoding caught by get_uint_value() */
3094         /* length has to be -1 or > 0 regardless of encoding */
3095         if (length < -1 || length == 0)
3096                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3097                         length);
3098
3099         if (encoding & ENC_STRING) {
3100                 REPORT_DISSECTOR_BUG("wrong encoding");
3101         }
3102         /* I believe it's ok if this is called with a NULL tree */
3103         /* XXX - modify if we ever support EBCDIC FT_CHAR */
3104         if (encoding & (ENC_VARIANT_MASK)) {
3105                 guint64 temp64;
3106                 tvb_get_varint(tvb, start, length, &temp64, encoding);
3107                 value = (guint32)temp64;
3108         } else {
3109                 value = get_uint_value(tree, tvb, start, length, encoding);
3110         }
3111
3112         if (retval) {
3113                 *retval = value;
3114                 if (hfinfo->bitmask) {
3115                         /* Mask out irrelevant portions */
3116                         *retval &= (guint32)(hfinfo->bitmask);
3117                         /* Shift bits */
3118                         *retval >>= hfinfo_bitshift(hfinfo);
3119                 }
3120         }
3121
3122         CHECK_FOR_NULL_TREE(tree);
3123
3124         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3125
3126         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3127
3128         proto_tree_set_uint(new_fi, value);
3129
3130         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3131         if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
3132                 new_fi->flags |= FI_VARINT;
3133         }
3134         return proto_tree_add_node(tree, new_fi);
3135 }
3136
3137 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3138  * and returns proto_item* and uint value retreived*/
3139 proto_item *
3140 ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, gint length,
3141               const guint encoding, guint32 *retval)
3142 {
3143         field_info        *new_fi;
3144         header_field_info *hfinfo;
3145         gint               item_length;
3146         int                offset;
3147         guint32            value;
3148
3149         offset = ptvc->offset;
3150         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3151
3152         switch (hfinfo->type) {
3153         case FT_CHAR:
3154         case FT_UINT8:
3155         case FT_UINT16:
3156         case FT_UINT24:
3157         case FT_UINT32:
3158                 break;
3159         default:
3160                 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
3161                     hfinfo->abbrev);
3162         }
3163
3164         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3165         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3166
3167         /* I believe it's ok if this is called with a NULL tree */
3168         /* XXX - modify if we ever support EBCDIC FT_CHAR */
3169         value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3170
3171         if (retval) {
3172                 *retval = value;
3173                 if (hfinfo->bitmask) {
3174                         /* Mask out irrelevant portions */
3175                         *retval &= (guint32)(hfinfo->bitmask);
3176                         /* Shift bits */
3177                         *retval >>= hfinfo_bitshift(hfinfo);
3178                 }
3179         }
3180
3181         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3182             item_length, encoding);
3183
3184         CHECK_FOR_NULL_TREE(ptvc->tree);
3185
3186         /* Coast clear. Try and fake it */
3187         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3188
3189         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3190
3191         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3192                 offset, length, encoding);
3193 }
3194
3195 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3196  * and returns proto_item* and int value retreived*/
3197 proto_item *
3198 ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, gint length,
3199               const guint encoding, gint32 *retval)
3200 {
3201         field_info        *new_fi;
3202         header_field_info *hfinfo;
3203         gint               item_length;
3204         int                offset;
3205         guint32            value;
3206
3207         offset = ptvc->offset;
3208         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3209
3210         switch (hfinfo->type) {
3211         case FT_INT8:
3212         case FT_INT16:
3213         case FT_INT24:
3214         case FT_INT32:
3215                 break;
3216         default:
3217                 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
3218                     hfinfo->abbrev);
3219         }
3220
3221         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3222         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3223
3224         /* I believe it's ok if this is called with a NULL tree */
3225         /* XXX - modify if we ever support EBCDIC FT_CHAR */
3226         value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3227
3228         if (retval) {
3229                 gint no_of_bits;
3230                 *retval = value;
3231                 if (hfinfo->bitmask) {
3232                         /* Mask out irrelevant portions */
3233                         *retval &= (guint32)(hfinfo->bitmask);
3234                         /* Shift bits */
3235                         *retval >>= hfinfo_bitshift(hfinfo);
3236                 }
3237                 no_of_bits = ws_count_ones(hfinfo->bitmask);
3238                 *retval = ws_sign_ext32(*retval, no_of_bits);
3239         }
3240
3241         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3242             item_length, encoding);
3243
3244         CHECK_FOR_NULL_TREE(ptvc->tree);
3245
3246         /* Coast clear. Try and fake it */
3247         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3248
3249         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3250
3251         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3252                 offset, length, encoding);
3253 }
3254
3255 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3256  * and returns proto_item* and string value retreived */
3257 proto_item*
3258 ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, wmem_allocator_t *scope, const guint8 **retval)
3259 {
3260         header_field_info *hfinfo;
3261         field_info              *new_fi;
3262         const guint8    *value;
3263         gint                    item_length;
3264         int                             offset;
3265
3266         offset = ptvc->offset;
3267
3268         PROTO_REGISTRAR_GET_NTH(hf, hfinfo);
3269
3270         switch (hfinfo->type) {
3271         case FT_STRING:
3272                 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3273                 break;
3274         case FT_STRINGZ:
3275                 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3276                 break;
3277         case FT_UINT_STRING:
3278                 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3279                 break;
3280         case FT_STRINGZPAD:
3281                 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3282                 break;
3283         case FT_STRINGZTRUNC:
3284                 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3285                 break;
3286         default:
3287                 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
3288                     hfinfo->abbrev);
3289         }
3290
3291         if (retval)
3292                 *retval = value;
3293
3294         ptvc->offset += item_length;
3295
3296         CHECK_FOR_NULL_TREE(ptvc->tree);
3297
3298         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3299
3300         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3301
3302         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3303                 offset, length, encoding);
3304 }
3305
3306 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3307  * and returns proto_item* and boolean value retreived */
3308 proto_item*
3309 ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, gint length, const guint encoding, gboolean *retval)
3310 {
3311         header_field_info *hfinfo;
3312         field_info              *new_fi;
3313         gint                    item_length;
3314         int                             offset;
3315         guint64                 value, bitval;
3316
3317         offset = ptvc->offset;
3318         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3319
3320         if (hfinfo->type != FT_BOOLEAN) {
3321                 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3322                     hfinfo->abbrev);
3323         }
3324
3325         /* length validation for native number encoding caught by get_uint64_value() */
3326         /* length has to be -1 or > 0 regardless of encoding */
3327         if (length < -1 || length == 0)
3328                 REPORT_DISSECTOR_BUG("Invalid length %d passed to ptvcursor_add_ret_boolean",
3329                         length);
3330
3331         if (encoding & ENC_STRING) {
3332                 REPORT_DISSECTOR_BUG("wrong encoding");
3333         }
3334
3335         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3336         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3337
3338         /* I believe it's ok if this is called with a NULL tree */
3339         value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3340
3341         if (retval) {
3342                 bitval = value;
3343                 if (hfinfo->bitmask) {
3344                         /* Mask out irrelevant portions */
3345                         bitval &= hfinfo->bitmask;
3346                 }
3347                 *retval = (bitval != 0);
3348         }
3349
3350         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3351             item_length, encoding);
3352
3353         CHECK_FOR_NULL_TREE(ptvc->tree);
3354
3355         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3356
3357         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3358
3359         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3360                 offset, length, encoding);
3361 }
3362
3363 proto_item *
3364 proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3365     const gint start, gint length, const guint encoding, guint64 *retval)
3366 {
3367         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3368         field_info        *new_fi;
3369         guint64            value;
3370
3371         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3372
3373         switch (hfinfo->type) {
3374         case FT_UINT40:
3375         case FT_UINT48:
3376         case FT_UINT56:
3377         case FT_UINT64:
3378                 break;
3379         default:
3380                 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
3381                     hfinfo->abbrev);
3382         }
3383
3384         /* length validation for native number encoding caught by get_uint64_value() */
3385         /* length has to be -1 or > 0 regardless of encoding */
3386         if (length < -1 || length == 0)
3387                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint64",
3388                         length);
3389
3390         if (encoding & ENC_STRING) {
3391                 REPORT_DISSECTOR_BUG("wrong encoding");
3392         }
3393         /* I believe it's ok if this is called with a NULL tree */
3394         if (encoding & (ENC_VARIANT_MASK)) {
3395                 tvb_get_varint(tvb, start, length, &value, encoding);
3396         } else {
3397                 value = get_uint64_value(tree, tvb, start, length, encoding);
3398         }
3399
3400         if (retval) {
3401                 *retval = value;
3402                 if (hfinfo->bitmask) {
3403                         /* Mask out irrelevant portions */
3404                         *retval &= hfinfo->bitmask;
3405                         /* Shift bits */
3406                         *retval >>= hfinfo_bitshift(hfinfo);
3407                 }
3408         }
3409
3410         CHECK_FOR_NULL_TREE(tree);
3411
3412         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3413
3414         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3415
3416         proto_tree_set_uint64(new_fi, value);
3417
3418         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3419         if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
3420                 new_fi->flags |= FI_VARINT;
3421         }
3422
3423         return proto_tree_add_node(tree, new_fi);
3424 }
3425
3426 proto_item *
3427 proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3428         const gint start, gint length, const guint encoding, gint64 *retval)
3429 {
3430         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3431         field_info        *new_fi;
3432         gint64             value;
3433
3434         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3435
3436         switch (hfinfo->type) {
3437         case FT_INT40:
3438         case FT_INT48:
3439         case FT_INT56:
3440         case FT_INT64:
3441                 break;
3442         default:
3443                 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
3444                         hfinfo->abbrev);
3445         }
3446
3447         /* length validation for native number encoding caught by get_uint64_value() */
3448         /* length has to be -1 or > 0 regardless of encoding */
3449         if (length < -1 || length == 0)
3450                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_int64",
3451                         length);
3452
3453         if (encoding & ENC_STRING) {
3454                 REPORT_DISSECTOR_BUG("wrong encoding");
3455         }
3456         /* I believe it's ok if this is called with a NULL tree */
3457         if (encoding & (ENC_VARIANT_MASK)) {
3458                 tvb_get_varint(tvb, start, length, &value, encoding);
3459         }
3460         else {
3461                 value = get_int64_value(tree, tvb, start, length, encoding);
3462         }
3463
3464         if (retval) {
3465                 *retval = value;
3466         }
3467
3468         CHECK_FOR_NULL_TREE(tree);
3469
3470         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3471
3472         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3473
3474         proto_tree_set_int64(new_fi, value);
3475
3476         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3477         if (encoding & (ENC_VARINT_PROTOBUF | ENC_VARINT_ZIGZAG)) {
3478                 new_fi->flags |= FI_VARINT;
3479         }
3480
3481         return proto_tree_add_node(tree, new_fi);
3482 }
3483
3484 proto_item *
3485 proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3486     const gint start, gint length, const guint encoding, guint64 *retval, gint *lenretval)
3487 {
3488         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3489         field_info      *new_fi;
3490         guint64         value;
3491
3492         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3493
3494         if ((!IS_FT_INT(hfinfo->type)) && (!IS_FT_UINT(hfinfo->type))) {
3495                 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",
3496                     hfinfo->abbrev);
3497         }
3498
3499         /* length validation for native number encoding caught by get_uint64_value() */
3500         /* length has to be -1 or > 0 regardless of encoding */
3501         if (length == 0)
3502                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",
3503                         length);
3504
3505         if (encoding & ENC_STRING) {
3506                 REPORT_DISSECTOR_BUG("wrong encoding");
3507         }
3508
3509         length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value, encoding);
3510
3511         if (retval) {
3512                 *retval = value;
3513                 if (hfinfo->bitmask) {
3514                         /* Mask out irrelevant portions */
3515                         *retval &= hfinfo->bitmask;
3516                         /* Shift bits */
3517                         *retval >>= hfinfo_bitshift(hfinfo);
3518                 }
3519         }
3520
3521         if (lenretval) {
3522                 *lenretval = length;
3523         }
3524
3525         CHECK_FOR_NULL_TREE(tree);
3526
3527         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3528
3529         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3530
3531         proto_tree_set_uint64(new_fi, value);
3532
3533         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3534         if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
3535                 new_fi->flags |= FI_VARINT;
3536         }
3537
3538         return proto_tree_add_node(tree, new_fi);
3539
3540 }
3541
3542 proto_item *
3543 proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3544                                 const gint start, gint length,
3545                                 const guint encoding, gboolean *retval)
3546 {
3547         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3548         field_info        *new_fi;
3549         guint64            value, bitval;
3550
3551         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3552
3553         if (hfinfo->type != FT_BOOLEAN) {
3554                 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3555                     hfinfo->abbrev);
3556         }
3557
3558         /* length validation for native number encoding caught by get_uint64_value() */
3559         /* length has to be -1 or > 0 regardless of encoding */
3560         if (length < -1 || length == 0)
3561                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_boolean",
3562                         length);
3563
3564         if (encoding & ENC_STRING) {
3565                 REPORT_DISSECTOR_BUG("wrong encoding");
3566         }
3567         /* I believe it's ok if this is called with a NULL tree */
3568         value = get_uint64_value(tree, tvb, start, length, encoding);
3569
3570         if (retval) {
3571                 bitval = value;
3572                 if (hfinfo->bitmask) {
3573                         /* Mask out irrelevant portions */
3574                         bitval &= hfinfo->bitmask;
3575                 }
3576                 *retval = (bitval != 0);
3577         }
3578
3579         CHECK_FOR_NULL_TREE(tree);
3580
3581         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3582
3583         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3584
3585         proto_tree_set_boolean(new_fi, value);
3586
3587         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3588
3589         return proto_tree_add_node(tree, new_fi);
3590 }
3591
3592 proto_item *
3593 proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3594                              const gint start, gint length,
3595                              const guint encoding, ws_in4_addr *retval)
3596 {
3597         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3598         field_info        *new_fi;
3599         ws_in4_addr        value;
3600
3601         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3602
3603         switch (hfinfo->type) {
3604         case FT_IPv4:
3605                 break;
3606         default:
3607                 REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv4",
3608                     hfinfo->abbrev);
3609         }
3610
3611         if (length != FT_IPv4_LEN)
3612                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv4",
3613                         length);
3614
3615         if (encoding & (ENC_STRING | ENC_VARIANT_MASK | ENC_VARINT_PROTOBUF | ENC_VARINT_ZIGZAG)) {
3616                 REPORT_DISSECTOR_BUG("wrong encoding");
3617         }
3618
3619         /*
3620          * NOTE: to support code written when proto_tree_add_item() took
3621          * a gboolean as its last argument, with FALSE meaning "big-endian"
3622          * and TRUE meaning "little-endian", we treat any non-zero value
3623          * of "encoding" as meaning "little-endian".
3624          */
3625         value = tvb_get_ipv4(tvb, start);
3626         if (encoding)
3627                 value = GUINT32_SWAP_LE_BE(value);
3628
3629         if (retval) {
3630                 *retval = value;
3631         }
3632
3633         CHECK_FOR_NULL_TREE(tree);
3634
3635         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3636
3637         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3638
3639         proto_tree_set_ipv4(new_fi, value);
3640
3641         new_fi->flags |= encoding ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3642         return proto_tree_add_node(tree, new_fi);
3643 }
3644
3645 proto_item *
3646 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
3647                                           tvbuff_t *tvb,
3648                                           const gint start, gint length,
3649                                           const guint encoding,
3650                                           wmem_allocator_t *scope,
3651                                           const guint8 **retval,
3652                                           gint *lenretval)
3653 {
3654         proto_item *pi;
3655         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3656         field_info        *new_fi;
3657         const guint8      *value;
3658
3659         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3660
3661         switch (hfinfo->type) {
3662         case FT_STRING:
3663                 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
3664                 break;
3665         case FT_STRINGZ:
3666                 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
3667                 break;
3668         case FT_UINT_STRING:
3669                 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
3670                 break;
3671         case FT_STRINGZPAD:
3672                 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
3673                 break;
3674         case FT_STRINGZTRUNC:
3675                 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
3676                 break;
3677         default:
3678                 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
3679                     hfinfo->abbrev);
3680         }
3681
3682         if (retval)
3683                 *retval = value;
3684
3685         CHECK_FOR_NULL_TREE(tree);
3686
3687         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3688
3689         new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
3690
3691         proto_tree_set_string(new_fi, value);
3692
3693         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3694
3695         pi = proto_tree_add_node(tree, new_fi);
3696
3697         switch (hfinfo->type) {
3698
3699         case FT_STRINGZ:
3700         case FT_STRINGZPAD:
3701         case FT_STRINGZTRUNC:
3702         case FT_UINT_STRING:
3703                 break;
3704
3705         case FT_STRING:
3706                 detect_trailing_stray_characters(encoding, value, length, pi);
3707                 break;
3708
3709         default:
3710                 g_assert_not_reached();
3711         }
3712
3713         return pi;
3714 }
3715
3716 proto_item *
3717 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3718                                const gint start, gint length,
3719                                const guint encoding, wmem_allocator_t *scope,
3720                                const guint8 **retval)
3721 {
3722         return proto_tree_add_item_ret_string_and_length(tree, hfindex,
3723             tvb, start, length, encoding, scope, retval, &length);
3724 }
3725
3726 proto_item *
3727 proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
3728                                                   tvbuff_t *tvb,
3729                                                   const gint start, gint length,
3730                                                   const guint encoding,
3731                                                   wmem_allocator_t *scope,
3732                                                   char **retval,
3733                                                   gint *lenretval)
3734 {
3735         proto_item *pi;
3736         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3737         field_info        *new_fi;
3738         const guint8      *value;
3739         guint32            n = 0;
3740
3741         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3742
3743         switch (hfinfo->type) {
3744         case FT_STRING:
3745                 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
3746                 *retval = hfinfo_format_text(scope, hfinfo, value);
3747                 break;
3748         case FT_STRINGZ:
3749                 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
3750                 *retval = hfinfo_format_text(scope, hfinfo, value);
3751                 break;
3752         case FT_UINT_STRING:
3753                 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
3754                 *retval = hfinfo_format_text(scope, hfinfo, value);
3755                 break;
3756         case FT_STRINGZPAD:
3757                 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
3758                 *retval = hfinfo_format_text(scope, hfinfo, value);
3759                 break;
3760         case FT_STRINGZTRUNC:
3761                 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
3762                 *retval = hfinfo_format_text(scope, hfinfo, value);
3763                 break;
3764         case FT_BYTES:
3765                 value = tvb_get_ptr(tvb, start, length);
3766                 *retval = hfinfo_format_bytes(scope, hfinfo, value, length);
3767                 *lenretval = length;
3768                 break;
3769         case FT_UINT_BYTES:
3770                 n = get_uint_value(tree, tvb, start, length, encoding);
3771                 value = tvb_get_ptr(tvb, start + length, n);
3772                 *retval = hfinfo_format_bytes(scope, hfinfo, value, n);
3773                 *lenretval = length + n;
3774                 break;
3775         default:
3776                 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES",
3777                     hfinfo->abbrev);
3778         }
3779
3780         CHECK_FOR_NULL_TREE(tree);
3781
3782         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3783
3784         new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
3785
3786         switch (hfinfo->type) {
3787
3788         case FT_STRING:
3789         case FT_STRINGZ:
3790         case FT_UINT_STRING:
3791         case FT_STRINGZPAD:
3792         case FT_STRINGZTRUNC:
3793                 proto_tree_set_string(new_fi, value);
3794                 break;
3795
3796         case FT_BYTES:
3797                 proto_tree_set_bytes(new_fi, value, length);
3798                 break;
3799
3800         case FT_UINT_BYTES:
3801                 proto_tree_set_bytes(new_fi, value, n);
3802                 break;
3803
3804         default:
3805                 g_assert_not_reached();
3806         }
3807
3808         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3809
3810         pi = proto_tree_add_node(tree, new_fi);
3811
3812         switch (hfinfo->type) {
3813
3814         case FT_STRINGZ:
3815         case FT_STRINGZPAD:
3816         case FT_STRINGZTRUNC:
3817         case FT_UINT_STRING:
3818                 break;
3819
3820         case FT_STRING:
3821                 detect_trailing_stray_characters(encoding, value, length, pi);
3822                 break;
3823
3824         case FT_BYTES:
3825         case FT_UINT_BYTES:
3826                 break;
3827
3828         default:
3829                 g_assert_not_reached();
3830         }
3831
3832         return pi;
3833 }
3834
3835 proto_item *
3836 proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
3837                                        tvbuff_t *tvb,
3838                                        const gint start, gint length,
3839                                        const guint encoding,
3840                                        wmem_allocator_t *scope,
3841                                        char **retval)
3842 {
3843         return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
3844             tvb, start, length, encoding, scope, retval, &length);
3845 }
3846
3847 proto_item *
3848 proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
3849         tvbuff_t *tvb,
3850         const gint start, gint length, const guint encoding,
3851         wmem_allocator_t *scope, char **retval)
3852 {
3853         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3854         field_info        *new_fi;
3855         nstime_t    time_stamp;
3856
3857         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3858
3859         switch (hfinfo->type) {
3860         case FT_ABSOLUTE_TIME:
3861                 get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
3862                 *retval = abs_time_to_str(scope, &time_stamp, (absolute_time_display_e)hfinfo->display, TRUE);
3863                 break;
3864         case FT_RELATIVE_TIME:
3865                 get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
3866                 *retval = rel_time_to_secs_str(scope, &time_stamp);
3867                 break;
3868         default:
3869                 REPORT_DISSECTOR_BUG("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME",
3870                         hfinfo->abbrev);
3871         }
3872
3873         CHECK_FOR_NULL_TREE(tree);
3874
3875         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3876
3877         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3878
3879         switch (hfinfo->type) {
3880
3881         case FT_ABSOLUTE_TIME:
3882         case FT_RELATIVE_TIME:
3883                 proto_tree_set_time(new_fi, &time_stamp);
3884                 break;
3885         default:
3886                 g_assert_not_reached();
3887         }
3888
3889         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3890
3891         return proto_tree_add_node(tree, new_fi);
3892 }
3893
3894 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3895    and returns proto_item* */
3896 proto_item *
3897 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
3898               const guint encoding)
3899 {
3900         field_info        *new_fi;
3901         header_field_info *hfinfo;
3902         gint               item_length;
3903         int                offset;
3904
3905         offset = ptvc->offset;
3906         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3907         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3908         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3909
3910         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3911             item_length, encoding);
3912
3913         CHECK_FOR_NULL_TREE(ptvc->tree);
3914
3915         /* Coast clear. Try and fake it */
3916         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3917
3918         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3919
3920         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3921                 offset, length, encoding);
3922 }
3923
3924 /* Add an item to a proto_tree, using the text label registered to that item;
3925    the item is extracted from the tvbuff handed to it. */
3926 proto_item *
3927 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
3928                         const gint start, gint length, const guint encoding)
3929 {
3930         field_info        *new_fi;
3931         gint              item_length;
3932
3933         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3934
3935         get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3936         test_length(hfinfo, tvb, start, item_length, encoding);
3937
3938         CHECK_FOR_NULL_TREE(tree);
3939
3940         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3941
3942         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3943
3944         return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3945 }
3946
3947 proto_item *
3948 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3949                     const gint start, gint length, const guint encoding)
3950 {
3951         register header_field_info *hfinfo;
3952
3953         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3954         return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
3955 }
3956
3957 /* Add an item to a proto_tree, using the text label registered to that item;
3958    the item is extracted from the tvbuff handed to it.
3959
3960    Return the length of the item through the pointer. */
3961 proto_item *
3962 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
3963                                    tvbuff_t *tvb, const gint start,
3964                                    gint length, const guint encoding,
3965                                    gint *lenretval)
3966 {
3967         field_info        *new_fi;
3968         gint              item_length;
3969         proto_item       *item;
3970
3971         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3972
3973         get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3974         test_length(hfinfo, tvb, start, item_length, encoding);
3975
3976         if (!tree) {
3977                 /*
3978                  * We need to get the correct item length here.
3979                  * That's normally done by proto_tree_new_item(),
3980                  * but we won't be calling it.
3981                  */
3982                 *lenretval = get_full_length(hfinfo, tvb, start, length,
3983                     item_length, encoding);
3984                 return NULL;
3985         }
3986
3987         TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
3988                 /*
3989                  * Even if the tree item is not referenced (and thus faked),
3990                  * the caller must still be informed of the actual length.
3991                  */
3992                 *lenretval = get_full_length(hfinfo, tvb, start, length,
3993                     item_length, encoding);
3994         });
3995
3996         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3997
3998         item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3999         *lenretval = new_fi->length;
4000         return item;
4001 }
4002
4003 proto_item *
4004 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4005                                const gint start, gint length,
4006                                const guint encoding, gint *lenretval)
4007 {
4008         register header_field_info *hfinfo;
4009
4010         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4011         return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4012 }
4013
4014 /* which FT_ types can use proto_tree_add_bytes_item() */
4015 static inline gboolean
4016 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4017 {
4018         return (type == FT_BYTES      ||
4019                 type == FT_UINT_BYTES ||
4020                 type == FT_OID        ||
4021                 type == FT_REL_OID    ||
4022                 type == FT_SYSTEM_ID  );
4023 }
4024
4025 /* Note: this does no validation that the byte array of an FT_OID or
4026    FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4027    so I think it's ok to continue not validating it?
4028  */
4029 proto_item *
4030 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4031                            const gint start, gint length, const guint encoding,
4032                            GByteArray *retval, gint *endoff, gint *err)
4033 {
4034         field_info        *new_fi;
4035         GByteArray        *bytes = retval;
4036         GByteArray        *created_bytes = NULL;
4037         gint               saved_err = 0;
4038         guint32            n = 0;
4039         header_field_info *hfinfo;
4040         gboolean           generate = (bytes || tree) ? TRUE : FALSE;
4041
4042         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4043
4044         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4045
4046         DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
4047                 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
4048
4049         /* length has to be -1 or > 0 regardless of encoding */
4050         /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
4051         if (length < -1 || length == 0) {
4052                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_bytes_item for %s",
4053                     length, ftype_name(hfinfo->type));
4054         }
4055
4056         if (encoding & ENC_STR_NUM) {
4057                 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
4058         }
4059
4060         if (generate && (encoding & ENC_STR_HEX)) {
4061                 if (hfinfo->type == FT_UINT_BYTES) {
4062                         /* can't decode FT_UINT_BYTES from strings */
4063                         REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
4064                             "FT_UINT_BYTES type, but as ENC_STR_HEX");
4065                 }
4066
4067                 if (!bytes) {
4068                         /* caller doesn't care about return value, but we need it to
4069                            call tvb_get_string_bytes() and set the tree later */
4070                         bytes = created_bytes = g_byte_array_new();
4071                 }
4072
4073                 /* bytes might be NULL after this, but can't add expert error until later */
4074                 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
4075
4076                 /* grab the errno now before it gets overwritten */
4077                 saved_err = errno;
4078         }
4079         else if (generate) {
4080                 tvb_ensure_bytes_exist(tvb, start, length);
4081
4082                 if (!bytes) {
4083                         /* caller doesn't care about return value, but we need it to
4084                            call tvb_get_string_bytes() and set the tree later */
4085                         bytes = created_bytes = g_byte_array_new();
4086                 }
4087
4088                 if (hfinfo->type == FT_UINT_BYTES) {
4089                         n = length; /* n is now the "header" length */
4090                         length = get_uint_value(tree, tvb, start, n, encoding);
4091                         /* length is now the value's length; only store the value in the array */
4092                         g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4093                 }
4094                 else if (length > 0) {
4095                         g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4096                 }
4097
4098                 if (endoff)
4099                     *endoff = start + n + length;
4100         }
4101
4102         if (err) *err = saved_err;
4103
4104         CHECK_FOR_NULL_TREE_AND_FREE(tree,
4105                 {
4106                     if (created_bytes)
4107                         g_byte_array_free(created_bytes, TRUE);
4108                     created_bytes = NULL;
4109                     bytes = NULL;
4110                 } );
4111
4112         TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
4113                 {
4114                     if (created_bytes)
4115                         g_byte_array_free(created_bytes, TRUE);
4116                     created_bytes = NULL;
4117                     bytes = NULL;
4118                 } );
4119
4120         /* n will be zero except when it's a FT_UINT_BYTES */
4121         new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4122
4123         if (encoding & ENC_STRING) {
4124                 if (saved_err == ERANGE)
4125                     expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
4126                 else if (!bytes || saved_err != 0)
4127                     expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
4128
4129                 if (bytes)
4130                     proto_tree_set_bytes_gbytearray(new_fi, bytes);
4131                 else
4132                     proto_tree_set_bytes(new_fi, NULL, 0);
4133
4134                 if (created_bytes)
4135                     g_byte_array_free(created_bytes, TRUE);
4136         }
4137         else {
4138                 /* n will be zero except when it's a FT_UINT_BYTES */
4139                 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4140
4141                 FI_SET_FLAG(new_fi,
4142                         (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
4143         }
4144
4145         return proto_tree_add_node(tree, new_fi);
4146 }
4147
4148
4149 proto_item *
4150 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4151                            const gint start, gint length, const guint encoding,
4152                            nstime_t *retval, gint *endoff, gint *err)
4153 {
4154         field_info        *new_fi;
4155         nstime_t           time_stamp;
4156         gint               saved_err = 0;
4157         header_field_info *hfinfo;
4158
4159         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4160
4161         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4162
4163         DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
4164
4165         /* length has to be -1 or > 0 regardless of encoding */
4166         if (length < -1 || length == 0) {
4167                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_time_item",
4168                     length);
4169         }
4170
4171         time_stamp.secs  = 0;
4172         time_stamp.nsecs = 0;
4173
4174         if (encoding & ENC_STR_TIME_MASK) {
4175                 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
4176                 /* grab the errno now before it gets overwritten */
4177                 saved_err = errno;
4178         }
4179         else {
4180                 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
4181
4182                 tvb_ensure_bytes_exist(tvb, start, length);
4183                 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4184                 if (endoff) *endoff = length;
4185         }
4186
4187         if (err) *err = saved_err;
4188
4189         if (retval) {
4190                 retval->secs  = time_stamp.secs;
4191                 retval->nsecs = time_stamp.nsecs;
4192         }
4193
4194         CHECK_FOR_NULL_TREE(tree);
4195
4196         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4197
4198         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4199
4200         proto_tree_set_time(new_fi, &time_stamp);
4201
4202         if (encoding & ENC_STRING) {
4203                 if (saved_err == ERANGE)
4204                     expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
4205                 else if (saved_err == EDOM)
4206                     expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
4207         }
4208         else {
4209                 FI_SET_FLAG(new_fi,
4210                         (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
4211         }
4212
4213         return proto_tree_add_node(tree, new_fi);
4214 }
4215
4216 /* Add a FT_NONE to a proto_tree */
4217 proto_item *
4218 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4219                            const gint start, gint length, const char *format,
4220                            ...)
4221 {
4222         proto_item        *pi;
4223         va_list            ap;
4224         header_field_info *hfinfo;
4225
4226         CHECK_FOR_NULL_TREE(tree);
4227
4228         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4229
4230         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
4231
4232         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4233
4234         TRY_TO_FAKE_THIS_REPR(pi);
4235
4236         va_start(ap, format);
4237         proto_tree_set_representation(pi, format, ap);
4238         va_end(ap);
4239
4240         /* no value to set for FT_NONE */
4241         return pi;
4242 }
4243
4244 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4245  * offset, and returns proto_item* */
4246 proto_item *
4247 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
4248                          const guint encoding)
4249 {
4250         proto_item *item;
4251
4252         item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4253                                    length, encoding);
4254
4255         return item;
4256 }
4257
4258 /* Advance the ptvcursor's offset within its tvbuff without
4259  * adding anything to the proto_tree. */
4260 void
4261 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
4262 {
4263         ptvc->offset += length;
4264 }
4265
4266
4267 static void
4268 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
4269 {
4270         fvalue_set_protocol(&fi->value, tvb, field_data);
4271 }
4272
4273 /* Add a FT_PROTOCOL to a proto_tree */
4274 proto_item *
4275 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4276                                gint start, gint length, const char *format, ...)
4277 {
4278         proto_item        *pi;
4279         tvbuff_t          *protocol_tvb;
4280         va_list            ap;
4281         header_field_info *hfinfo;
4282         gchar* protocol_rep;
4283
4284         CHECK_FOR_NULL_TREE(tree);
4285
4286         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4287
4288         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
4289
4290         /*
4291          * This can throw an exception, so do it before we allocate anything.
4292          */
4293         protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4294
4295         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4296
4297         va_start(ap, format);
4298         protocol_rep = g_strdup_vprintf(format, ap);
4299         proto_tree_set_protocol_tvb(PNODE_FINFO(pi), protocol_tvb, protocol_rep);
4300         g_free(protocol_rep);
4301         va_end(ap);
4302
4303         TRY_TO_FAKE_THIS_REPR(pi);
4304
4305         va_start(ap, format);
4306         proto_tree_set_representation(pi, format, ap);
4307         va_end(ap);
4308
4309         return pi;
4310 }
4311
4312 /* Add a FT_BYTES to a proto_tree */
4313 proto_item *
4314 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4315                      gint length, const guint8 *start_ptr)
4316 {
4317         proto_item        *pi;
4318         header_field_info *hfinfo;
4319         gint              item_length;
4320
4321         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4322         get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
4323         test_length(hfinfo, tvb, start, item_length, ENC_NA);
4324
4325         CHECK_FOR_NULL_TREE(tree);
4326
4327         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4328
4329         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
4330
4331         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4332         proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
4333
4334         return pi;
4335 }
4336
4337 /* Add a FT_BYTES to a proto_tree */
4338 proto_item *
4339 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4340              gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
4341 {
4342         proto_item    *pi;
4343         header_field_info *hfinfo;
4344         gint          item_length;
4345
4346         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4347         get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA);
4348         test_length(hfinfo, tvb, start, item_length, ENC_NA);
4349
4350         CHECK_FOR_NULL_TREE(tree);
4351
4352         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4353
4354         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
4355
4356         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4357         proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
4358
4359         return pi;
4360 }
4361
4362 proto_item *
4363 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4364                                   gint start, gint length,
4365                                   const guint8 *start_ptr,
4366                                   const char *format, ...)
4367 {
4368         proto_item        *pi;
4369         va_list            ap;
4370
4371         if (start_ptr == NULL)
4372                 start_ptr = tvb_get_ptr(tvb, start, length);
4373
4374         pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4375
4376         TRY_TO_FAKE_THIS_REPR_NESTED(pi);
4377
4378         va_start(ap, format);
4379         proto_tree_set_representation_value(pi, format, ap);
4380         va_end(ap);
4381
4382         return pi;
4383 }
4384
4385 proto_item *
4386 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4387                             gint start, gint length, const guint8 *start_ptr,
4388                             const char *format, ...)
4389 {
4390         proto_item        *pi;
4391         va_list            ap;
4392
4393         if (start_ptr == NULL)
4394                 start_ptr = tvb_get_ptr(tvb, start, length);
4395
4396         pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4397
4398         TRY_TO_FAKE_THIS_REPR_NESTED(pi);
4399
4400         va_start(ap, format);
4401         proto_tree_set_representation(pi, format, ap);
4402         va_end(ap);
4403
4404         return pi;
4405 }
4406
4407 static void
4408 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
4409 {
4410         GByteArray *bytes;
4411
4412         DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
4413
4414         bytes = g_byte_array_new();
4415         if (length > 0) {
4416                 g_byte_array_append(bytes, start_ptr, length);
4417         }
4418         fvalue_set_byte_array(&fi->value, bytes);
4419 }
4420
4421
4422 static void
4423 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
4424 {
4425         proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4426 }
4427
4428 static void
4429 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4430 {
4431         GByteArray *bytes;
4432
4433         DISSECTOR_ASSERT(value != NULL);
4434
4435         bytes = byte_array_dup(value);
4436
4437         fvalue_set_byte_array(&fi->value, bytes);
4438 }
4439
4440 /* Add a FT_*TIME to a proto_tree */
4441 proto_item *
4442 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4443                     gint length, const nstime_t *value_ptr)
4444 {
4445         proto_item        *pi;
4446         header_field_info *hfinfo;
4447
4448         CHECK_FOR_NULL_TREE(tree);
4449
4450         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4451
4452         DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
4453
4454         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4455         proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
4456
4457         return pi;
4458 }
4459
4460 proto_item *
4461 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4462                                  gint start, gint length, nstime_t *value_ptr,
4463                                  const char *format, ...)
4464 {
4465         proto_item        *pi;
4466         va_list            ap;
4467
4468         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4469         if (pi != tree) {
4470                 va_start(ap, format);
4471                 proto_tree_set_representation_value(pi, format, ap);
4472                 va_end(ap);
4473         }
4474
4475         return pi;
4476 }
4477
4478 proto_item *
4479 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4480                            gint start, gint length, nstime_t *value_ptr,
4481                            const char *format, ...)
4482 {
4483         proto_item        *pi;
4484         va_list            ap;
4485
4486         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4487         if (pi != tree) {
4488                 TRY_TO_FAKE_THIS_REPR(pi);
4489
4490                 va_start(ap, format);
4491                 proto_tree_set_representation(pi, format, ap);
4492                 va_end(ap);
4493         }
4494
4495         return pi;
4496 }
4497
4498 /* Set the FT_*TIME value */
4499 static void
4500 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4501 {
4502         DISSECTOR_ASSERT(value_ptr != NULL);
4503
4504         fvalue_set_time(&fi->value, value_ptr);
4505 }
4506
4507 /* Add a FT_IPXNET to a proto_tree */
4508 proto_item *
4509 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4510                       gint length, guint32 value)
4511 {
4512         proto_item        *pi;
4513         header_field_info *hfinfo;
4514
4515         CHECK_FOR_NULL_TREE(tree);
4516
4517         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4518
4519         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
4520
4521         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4522         proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
4523
4524         return pi;
4525 }
4526
4527 proto_item *
4528 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4529                                    gint start, gint length, guint32 value,
4530                                    const char *format, ...)
4531 {
4532         proto_item        *pi;
4533         va_list            ap;
4534
4535         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4536         if (pi != tree) {
4537                 va_start(ap, format);
4538                 proto_tree_set_representation_value(pi, format, ap);
4539                 va_end(ap);
4540         }
4541
4542         return pi;
4543 }
4544
4545 proto_item *
4546 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4547                              gint start, gint length, guint32 value,
4548                              const char *format, ...)
4549 {
4550         proto_item        *pi;
4551         va_list            ap;
4552
4553         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4554         if (pi != tree) {
4555                 TRY_TO_FAKE_THIS_REPR(pi);
4556
4557                 va_start(ap, format);
4558                 proto_tree_set_representation(pi, format, ap);
4559                 va_end(ap);
4560         }
4561
4562         return pi;
4563 }
4564
4565 /* Set the FT_IPXNET value */
4566 static void
4567 proto_tree_set_ipxnet(field_info *fi, guint32 value)
4568 {
4569         fvalue_set_uinteger(&fi->value, value);
4570 }
4571
4572 /* Add a FT_IPv4 to a proto_tree */
4573 proto_item *
4574 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4575                     gint length, ws_in4_addr value)
4576 {
4577         proto_item        *pi;
4578         header_field_info *hfinfo;
4579
4580         CHECK_FOR_NULL_TREE(tree);
4581
4582         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4583
4584         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
4585
4586         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4587         proto_tree_set_ipv4(PNODE_FINFO(pi), value);
4588
4589         return pi;
4590 }
4591
4592 proto_item *
4593 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4594                                  gint start, gint length, ws_in4_addr value,
4595                                  const char *format, ...)
4596 {
4597         proto_item        *pi;
4598         va_list            ap;
4599
4600         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
4601         if (pi != tree) {
4602                 va_start(ap, format);
4603                 proto_tree_set_representation_value(pi, format, ap);
4604                 va_end(ap);
4605         }
4606
4607         return pi;
4608 }
4609
4610 proto_item *
4611 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4612                            gint start, gint length, ws_in4_addr value,
4613                            const char *format, ...)
4614 {
4615         proto_item        *pi;
4616         va_list            ap;
4617
4618         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
4619         if (pi != tree) {
4620                 TRY_TO_FAKE_THIS_REPR(pi);
4621
4622                 va_start(ap, format);
4623                 proto_tree_set_representation(pi, format, ap);
4624                 va_end(ap);
4625         }
4626
4627         return pi;
4628 }
4629
4630 /* Set the FT_IPv4 value */
4631 static void
4632 proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
4633 {
4634         fvalue_set_uinteger(&fi->value, value);
4635 }
4636
4637 /* Add a FT_IPv6 to a proto_tree */
4638 proto_item *
4639 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4640                     gint length, const ws_in6_addr *value_ptr)
4641 {
4642         proto_item        *pi;
4643         header_field_info *hfinfo;
4644
4645         CHECK_FOR_NULL_TREE(tree);
4646
4647         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4648
4649         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
4650
4651         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4652         proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
4653
4654         return pi;
4655 }
4656
4657 proto_item *
4658 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4659                                  gint start, gint length,
4660                                  const ws_in6_addr *value_ptr,
4661                                  const char *format, ...)
4662 {
4663         proto_item        *pi;
4664         va_list            ap;
4665
4666         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
4667         if (pi != tree) {
4668                 va_start(ap, format);
4669                 proto_tree_set_representation_value(pi, format, ap);
4670                 va_end(ap);
4671         }
4672
4673         return pi;
4674 }
4675
4676 proto_item *
4677 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4678                            gint start, gint length,
4679                            const ws_in6_addr *value_ptr,
4680                            const char *format, ...)
4681 {
4682         proto_item        *pi;
4683         va_list            ap;
4684
4685         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
4686         if (pi != tree) {
4687                 TRY_TO_FAKE_THIS_REPR(pi);
4688
4689                 va_start(ap, format);
4690                 proto_tree_set_representation(pi, format, ap);
4691                 va_end(ap);
4692         }
4693
4694         return pi;
4695 }
4696
4697 /* Set the FT_IPv6 value */
4698 static void
4699 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
4700 {
4701         DISSECTOR_ASSERT(value_ptr != NULL);
4702         fvalue_set_bytes(&fi->value, value_ptr);
4703 }
4704
4705 static void
4706 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4707 {
4708         proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
4709 }
4710
4711 /* Set the FT_FCWWN value */
4712 static void
4713 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
4714 {
4715         DISSECTOR_ASSERT(value_ptr != NULL);
4716         fvalue_set_bytes(&fi->value, value_ptr);
4717 }
4718
4719 static void
4720 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4721 {
4722         proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
4723 }
4724
4725 /* Add a FT_GUID to a proto_tree */
4726 proto_item *
4727 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4728                     gint length, const e_guid_t *value_ptr)
4729 {
4730         proto_item        *pi;
4731         header_field_info *hfinfo;
4732
4733         CHECK_FOR_NULL_TREE(tree);
4734
4735         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4736
4737         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
4738
4739         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4740         proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
4741
4742         return pi;
4743 }
4744
4745 proto_item *
4746 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4747                                  gint start, gint length,
4748                                  const e_guid_t *value_ptr,
4749                                  const char *format, ...)
4750 {
4751         proto_item        *pi;
4752         va_list            ap;
4753
4754         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4755         if (pi != tree) {
4756                 va_start(ap, format);
4757                 proto_tree_set_representation_value(pi, format, ap);
4758                 va_end(ap);
4759         }
4760
4761         return pi;
4762 }
4763
4764 proto_item *
4765 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4766                            gint start, gint length, const e_guid_t *value_ptr,
4767                            const char *format, ...)
4768 {
4769         proto_item        *pi;
4770         va_list            ap;
4771
4772         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4773         if (pi != tree) {
4774                 TRY_TO_FAKE_THIS_REPR(pi);
4775
4776                 va_start(ap, format);
4777                 proto_tree_set_representation(pi, format, ap);
4778                 va_end(ap);
4779         }
4780
4781         return pi;
4782 }
4783
4784 /* Set the FT_GUID value */
4785 static void
4786 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
4787 {
4788         DISSECTOR_ASSERT(value_ptr != NULL);
4789         fvalue_set_guid(&fi->value, value_ptr);
4790 }
4791
4792 static void
4793 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
4794                         const guint encoding)
4795 {
4796         e_guid_t guid;
4797
4798         tvb_get_guid(tvb, start, &guid, encoding);
4799         proto_tree_set_guid(fi, &guid);
4800 }
4801
4802 /* Add a FT_OID to a proto_tree */
4803 proto_item *
4804 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4805                    gint length, const guint8* value_ptr)
4806 {
4807         proto_item        *pi;
4808         header_field_info *hfinfo;
4809
4810         CHECK_FOR_NULL_TREE(tree);
4811
4812         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4813
4814         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
4815
4816         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4817         proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
4818
4819         return pi;
4820 }
4821
4822 proto_item *
4823 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4824                                 gint start, gint length,
4825                                 const guint8* value_ptr,
4826                                 const char *format, ...)
4827 {
4828         proto_item        *pi;
4829         va_list            ap;
4830
4831         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4832         if (pi != tree) {
4833                 va_start(ap, format);
4834                 proto_tree_set_representation_value(pi, format, ap);
4835                 va_end(ap);
4836         }
4837
4838         return pi;
4839 }
4840
4841 proto_item *
4842 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4843                           gint start, gint length, const guint8* value_ptr,
4844                           const char *format, ...)
4845 {
4846         proto_item        *pi;
4847         va_list            ap;
4848
4849         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4850         if (pi != tree) {
4851                 TRY_TO_FAKE_THIS_REPR(pi);
4852
4853                 va_start(ap, format);
4854                 proto_tree_set_representation(pi, format, ap);
4855                 va_end(ap);
4856         }
4857
4858         return pi;
4859 }
4860
4861 /* Set the FT_OID value */
4862 static void
4863 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
4864 {
4865         GByteArray *bytes;
4866
4867         DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4868
4869         bytes = g_byte_array_new();
4870         if (length > 0) {
4871                 g_byte_array_append(bytes, value_ptr, length);
4872         }
4873         fvalue_set_byte_array(&fi->value, bytes);
4874 }
4875
4876 static void
4877 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4878 {
4879         proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
4880 }
4881
4882 /* Set the FT_SYSTEM_ID value */
4883 static void
4884 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
4885 {
4886         GByteArray *bytes;
4887
4888         DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4889
4890         bytes = g_byte_array_new();
4891         if (length > 0) {
4892                 g_byte_array_append(bytes, value_ptr, length);
4893         }
4894         fvalue_set_byte_array(&fi->value, bytes);
4895 }
4896
4897 static void
4898 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4899 {
4900         proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
4901 }
4902
4903 /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
4904  * proto_tree. Creates own copy of string, and frees it when the proto_tree
4905  * is destroyed. */
4906 proto_item *
4907 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4908                       gint length, const char* value)
4909 {
4910         proto_item        *pi;
4911         header_field_info *hfinfo;
4912         gint              item_length;
4913
4914         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4915         get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
4916         /*
4917          * Special case - if the length is 0, skip the test, so that
4918          * we can have an empty string right after the end of the
4919          * packet.  (This handles URL-encoded forms where the last field
4920          * has no value so the form ends right after the =.)
4921          */
4922         if (item_length != 0)
4923                 test_length(hfinfo, tvb, start, item_length, ENC_NA);
4924
4925         CHECK_FOR_NULL_TREE(tree);
4926
4927         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4928
4929         DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
4930
4931         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4932         DISSECTOR_ASSERT(length >= 0);
4933         proto_tree_set_string(PNODE_FINFO(pi), value);
4934
4935         return pi;
4936 }
4937
4938 proto_item *
4939 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4940                                    gint start, gint length, const char* value,
4941                                    const char *format,
4942                                    ...)
4943 {
4944         proto_item        *pi;
4945         va_list            ap;
4946
4947         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4948         if (pi != tree) {
4949                 va_start(ap, format);
4950                 proto_tree_set_representation_value(pi, format, ap);
4951                 va_end(ap);
4952         }
4953
4954         return pi;
4955 }
4956
4957 proto_item *
4958 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4959                              gint start, gint length, const char* value,
4960                              const char *format, ...)
4961 {
4962         proto_item        *pi;
4963         va_list            ap;
4964
4965         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4966         if (pi != tree) {
4967                 TRY_TO_FAKE_THIS_REPR(pi);
4968
4969                 va_start(ap, format);
4970                 proto_tree_set_representation(pi, format, ap);
4971                 va_end(ap);
4972         }
4973
4974         return pi;
4975 }
4976
4977 /* Set the FT_STRING value */
4978 static void
4979 proto_tree_set_string(field_info *fi, const char* value)
4980 {
4981         if (value) {
4982                 fvalue_set_string(&fi->value, value);
4983         } else {
4984                 /*
4985                  * XXX - why is a null value for a string field
4986                  * considered valid?
4987                  */
4988                 fvalue_set_string(&fi->value, "[ Null ]");
4989         }
4990 }
4991
4992 /* Set the FT_AX25 value */
4993 static void
4994 proto_tree_set_ax25(field_info *fi, const guint8* value)
4995 {
4996         fvalue_set_bytes(&fi->value, value);
4997 }
4998
4999 static void
5000 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
5001 {
5002         proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5003 }
5004
5005 /* Set the FT_VINES value */
5006 static void
5007 proto_tree_set_vines(field_info *fi, const guint8* value)
5008 {
5009         fvalue_set_bytes(&fi->value, value);
5010 }
5011
5012 static void
5013 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
5014 {
5015         proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
5016 }
5017
5018 /* Add a FT_ETHER to a proto_tree */
5019 proto_item *
5020 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5021                      gint length, const guint8* value)
5022 {
5023         proto_item        *pi;
5024         header_field_info *hfinfo;
5025
5026         CHECK_FOR_NULL_TREE(tree);
5027
5028         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5029
5030         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
5031
5032         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5033         proto_tree_set_ether(PNODE_FINFO(pi), value);
5034
5035         return pi;
5036 }
5037
5038 proto_item *
5039 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5040                                   gint start, gint length, const guint8* value,
5041                                   const char *format, ...)
5042 {
5043         proto_item        *pi;
5044         va_list            ap;
5045
5046         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5047         if (pi != tree) {
5048                 va_start(ap, format);
5049                 proto_tree_set_representation_value(pi, format, ap);
5050                 va_end(ap);
5051         }
5052
5053         return pi;
5054 }
5055
5056 proto_item *
5057 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5058                             gint start, gint length, const guint8* value,
5059                             const char *format, ...)
5060 {
5061         proto_item        *pi;
5062         va_list            ap;
5063
5064         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5065         if (pi != tree) {
5066                 TRY_TO_FAKE_THIS_REPR(pi);
5067
5068                 va_start(ap, format);
5069                 proto_tree_set_representation(pi, format, ap);
5070                 va_end(ap);
5071         }
5072
5073         return pi;
5074 }
5075
5076 /* Set the FT_ETHER value */
5077 static void
5078 proto_tree_set_ether(field_info *fi, const guint8* value)
5079 {
5080         fvalue_set_bytes(&fi->value, value);
5081 }
5082
5083 static void
5084 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
5085 {
5086         proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
5087 }
5088
5089 /* Add a FT_BOOLEAN to a proto_tree */
5090 proto_item *
5091 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5092                        gint length, guint32 value)
5093 {
5094         proto_item        *pi;
5095         header_field_info *hfinfo;
5096
5097         CHECK_FOR_NULL_TREE(tree);
5098
5099         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5100
5101         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
5102
5103         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5104         proto_tree_set_boolean(PNODE_FINFO(pi), value);
5105
5106         return pi;
5107 }
5108
5109 proto_item *
5110 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5111                                     tvbuff_t *tvb, gint start, gint length,
5112                                     guint32 value, const char *format, ...)
5113 {
5114         proto_item        *pi;
5115         va_list            ap;
5116
5117         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5118         if (pi != tree) {
5119                 va_start(ap, format);
5120                 proto_tree_set_representation_value(pi, format, ap);
5121                 va_end(ap);
5122         }
5123
5124         return pi;
5125 }
5126
5127 proto_item *
5128 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5129                               gint start, gint length, guint32 value,
5130                               const char *format, ...)
5131 {
5132         proto_item        *pi;
5133         va_list            ap;
5134
5135         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5136         if (pi != tree) {
5137                 TRY_TO_FAKE_THIS_REPR(pi);
5138
5139                 va_start(ap, format);
5140                 proto_tree_set_representation(pi, format, ap);
5141                 va_end(ap);
5142         }
5143
5144         return pi;
5145 }
5146
5147 static proto_item *
5148 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5149                          gint length, guint64 value)
5150 {
5151         proto_item        *pi;
5152         header_field_info *hfinfo;
5153
5154         CHECK_FOR_NULL_TREE(tree);
5155
5156         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5157
5158         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
5159
5160         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5161         proto_tree_set_boolean(PNODE_FINFO(pi), value);
5162
5163         return pi;
5164 }
5165
5166 /* Set the FT_BOOLEAN value */
5167 static void
5168 proto_tree_set_boolean(field_info *fi, guint64 value)
5169 {
5170         proto_tree_set_uint64(fi, value);
5171 }
5172
5173 /* Generate, into "buf", a string showing the bits of a bitfield.
5174    Return a pointer to the character after that string. */
5175 static char *
5176 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
5177 {
5178         int i;
5179         guint64 bit;
5180         char *p;
5181
5182         i = 0;
5183         p = buf;
5184
5185         /* This is a devel error. It is safer to stop here. */
5186         DISSECTOR_ASSERT(width >= 1);
5187
5188         bit = G_GUINT64_CONSTANT(1) << (width - 1);
5189         for (;;) {
5190                 if (mask & bit) {
5191                         /* This bit is part of the field.  Show its value. */
5192                         if (val & bit)
5193                                 *p++ = '1';
5194                         else
5195                                 *p++ = '0';
5196                 } else {
5197                         /* This bit is not part of the field. */
5198                         *p++ = '.';
5199                 }
5200                 bit >>= 1;
5201                 i++;
5202                 if (i >= width)
5203                         break;
5204                 if (i % 4 == 0)
5205                         *p++ = ' ';
5206         }
5207         *p = '\0';
5208         return p;
5209 }
5210
5211 static char *
5212 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
5213 {
5214         char *p;
5215
5216         p = other_decode_bitfield_value(buf, val, mask, width);
5217         p = g_stpcpy(p, " = ");
5218
5219         return p;
5220 }
5221
5222 static char *
5223 other_decode_bitfield_varint_value(char *buf, guint64 val, guint64 mask, const int width)
5224 {
5225         int i = 0;
5226         guint64 bit;
5227         char *p;
5228
5229         p = buf;
5230         bit = G_GUINT64_CONSTANT(1) << (width - 1);
5231         for (;;) {
5232                 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5233                         (mask & bit)) {
5234                         /* This bit is part of the field.  Show its value. */
5235                         if (val & bit)
5236                                 *p++ = '1';
5237                         else
5238                                 *p++ = '0';
5239                 } else {
5240                         /* This bit is not part of the field. */
5241                         *p++ = '.';
5242                 }
5243                 bit >>= 1;
5244                 i++;
5245                 if (i >= width)
5246                         break;
5247                 if (i % 4 == 0)
5248                         *p++ = ' ';
5249         }
5250
5251         *p = '\0';
5252         return p;
5253 }
5254
5255 static char *
5256 decode_bitfield_varint_value(char *buf, const guint64 val, const guint64 mask, const int width)
5257 {
5258         char *p;
5259
5260         p = other_decode_bitfield_varint_value(buf, val, mask, width);
5261         p = g_stpcpy(p, " = ");
5262
5263         return p;
5264 }
5265
5266 /* Add a FT_FLOAT to a proto_tree */
5267 proto_item *
5268 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5269                      gint length, float value)
5270 {
5271         proto_item        *pi;
5272         header_field_info *hfinfo;
5273
5274         CHECK_FOR_NULL_TREE(tree);
5275
5276         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5277
5278         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
5279
5280         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5281         proto_tree_set_float(PNODE_FINFO(pi), value);
5282
5283         return pi;
5284 }
5285
5286 proto_item *
5287 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5288                                   gint start, gint length, float value,
5289                                   const char *format, ...)
5290 {
5291         proto_item        *pi;
5292         va_list            ap;
5293
5294         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5295         if (pi != tree) {
5296                 va_start(ap, format);
5297                 proto_tree_set_representation_value(pi, format, ap);
5298                 va_end(ap);
5299         }
5300
5301         return pi;
5302 }
5303
5304 proto_item *
5305 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5306                             gint start, gint length, float value,
5307                             const char *format, ...)
5308 {
5309         proto_item        *pi;
5310         va_list            ap;
5311
5312         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5313         if (pi != tree) {
5314                 TRY_TO_FAKE_THIS_REPR(pi);
5315
5316                 va_start(ap, format);
5317                 proto_tree_set_representation(pi, format, ap);
5318                 va_end(ap);
5319         }
5320
5321         return pi;
5322 }
5323
5324 /* Set the FT_FLOAT value */
5325 static void
5326 proto_tree_set_float(field_info *fi, float value)
5327 {
5328         fvalue_set_floating(&fi->value, value);
5329 }
5330
5331 /* Add a FT_DOUBLE to a proto_tree */
5332 proto_item *
5333 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5334                       gint length, double value)
5335 {
5336         proto_item        *pi;
5337         header_field_info *hfinfo;
5338
5339         CHECK_FOR_NULL_TREE(tree);
5340
5341         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5342
5343         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
5344
5345         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5346         proto_tree_set_double(PNODE_FINFO(pi), value);
5347
5348         return pi;
5349 }
5350
5351 proto_item *
5352 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5353                                    gint start, gint length, double value,
5354                                    const char *format, ...)
5355 {
5356         proto_item        *pi;
5357         va_list            ap;
5358
5359         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5360         if (pi != tree) {
5361                 va_start(ap, format);
5362                 proto_tree_set_representation_value(pi, format, ap);
5363                 va_end(ap);
5364         }
5365
5366         return pi;
5367 }
5368
5369 proto_item *
5370 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5371                              gint start, gint length, double value,
5372                              const char *format, ...)
5373 {
5374         proto_item        *pi;
5375         va_list            ap;
5376
5377         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5378         if (pi != tree) {
5379                 TRY_TO_FAKE_THIS_REPR(pi);
5380
5381                 va_start(ap, format);
5382                 proto_tree_set_representation(pi, format, ap);
5383                 va_end(ap);
5384         }
5385
5386         return pi;
5387 }
5388
5389 /* Set the FT_DOUBLE value */
5390 static void
5391 proto_tree_set_double(field_info *fi, double value)
5392 {
5393         fvalue_set_floating(&fi->value, value);
5394 }
5395
5396 /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5397 proto_item *
5398 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5399                     gint length, guint32 value)
5400 {
5401         proto_item        *pi = NULL;
5402         header_field_info *hfinfo;
5403
5404         CHECK_FOR_NULL_TREE(tree);
5405
5406         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5407
5408         switch (hfinfo->type) {
5409                 case FT_CHAR:
5410                 case FT_UINT8:
5411                 case FT_UINT16:
5412                 case FT_UINT24:
5413                 case FT_UINT32:
5414                 case FT_FRAMENUM:
5415                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5416                         proto_tree_set_uint(PNODE_FINFO(pi), value);
5417                         break;
5418
5419                 default:
5420                         REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",
5421                             hfinfo->abbrev);
5422         }
5423
5424         return pi;
5425 }
5426
5427 proto_item *
5428 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5429                                  gint start, gint length, guint32 value,
5430                                  const char *format, ...)
5431 {
5432         proto_item        *pi;
5433         va_list            ap;
5434
5435         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5436         if (pi != tree) {
5437                 va_start(ap, format);
5438                 proto_tree_set_representation_value(pi, format, ap);
5439                 va_end(ap);
5440         }
5441
5442         return pi;
5443 }
5444
5445 proto_item *
5446 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5447                            gint start, gint length, guint32 value,
5448                            const char *format, ...)
5449 {
5450         proto_item        *pi;
5451         va_list            ap;
5452
5453         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5454         if (pi != tree) {
5455                 TRY_TO_FAKE_THIS_REPR(pi);
5456
5457                 va_start(ap, format);
5458                 proto_tree_set_representation(pi, format, ap);
5459                 va_end(ap);
5460         }
5461
5462         return pi;
5463 }
5464
5465 /* Set the FT_UINT{8,16,24,32} value */
5466 static void
5467 proto_tree_set_uint(field_info *fi, guint32 value)
5468 {
5469         header_field_info *hfinfo;
5470         guint32            integer;
5471
5472         hfinfo = fi->hfinfo;
5473         integer = value;
5474
5475         if (hfinfo->bitmask) {
5476                 /* Mask out irrelevant portions */
5477                 integer &= (guint32)(hfinfo->bitmask);
5478
5479                 /* Shift bits */
5480                 integer >>= hfinfo_bitshift(hfinfo);
5481
5482                 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5483                 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5484         }
5485
5486         fvalue_set_uinteger(&fi->value, integer);
5487 }
5488
5489 /* Add FT_UINT{40,48,56,64} to a proto_tree */
5490 proto_item *
5491 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5492                       gint length, guint64 value)
5493 {
5494         proto_item        *pi = NULL;
5495         header_field_info *hfinfo;
5496
5497         CHECK_FOR_NULL_TREE(tree);
5498
5499         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5500
5501         switch (hfinfo->type) {
5502                 case FT_UINT40:
5503                 case FT_UINT48:
5504                 case FT_UINT56:
5505                 case FT_UINT64:
5506                 case FT_FRAMENUM:
5507                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5508                         proto_tree_set_uint64(PNODE_FINFO(pi), value);
5509                         break;
5510
5511                 default:
5512                         REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",
5513                             hfinfo->abbrev);
5514         }
5515
5516         return pi;
5517 }
5518
5519 proto_item *
5520 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5521                                    gint start, gint length, guint64 value,
5522                                    const char *format, ...)
5523 {
5524         proto_item        *pi;
5525         va_list            ap;
5526
5527         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5528         if (pi != tree) {
5529                 va_start(ap, format);
5530                 proto_tree_set_representation_value(pi, format, ap);
5531                 va_end(ap);
5532         }
5533
5534         return pi;
5535 }
5536
5537 proto_item *
5538 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5539                              gint start, gint length, guint64 value,
5540                              const char *format, ...)
5541 {
5542         proto_item        *pi;
5543         va_list            ap;
5544
5545         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5546         if (pi != tree) {
5547                 TRY_TO_FAKE_THIS_REPR(pi);
5548
5549                 va_start(ap, format);
5550                 proto_tree_set_representation(pi, format, ap);
5551                 va_end(ap);
5552         }
5553
5554         return pi;
5555 }
5556
5557 /* Set the FT_UINT{40,48,56,64} value */
5558 static void
5559 proto_tree_set_uint64(field_info *fi, guint64 value)
5560 {
5561         header_field_info *hfinfo;
5562         guint64            integer;
5563
5564         hfinfo = fi->hfinfo;
5565         integer = value;
5566
5567         if (hfinfo->bitmask) {
5568                 /* Mask out irrelevant portions */
5569                 integer &= hfinfo->bitmask;
5570
5571                 /* Shift bits */
5572                 integer >>= hfinfo_bitshift(hfinfo);
5573
5574                 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5575                 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5576         }
5577
5578         fvalue_set_uinteger64(&fi->value, integer);
5579 }
5580
5581 /* Add FT_INT{8,16,24,32} to a proto_tree */
5582 proto_item *
5583 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5584                    gint length, gint32 value)
5585 {
5586         proto_item        *pi = NULL;
5587         header_field_info *hfinfo;
5588
5589         CHECK_FOR_NULL_TREE(tree);
5590
5591         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5592
5593         switch (hfinfo->type) {
5594                 case FT_INT8:
5595                 case FT_INT16:
5596                 case FT_INT24:
5597                 case FT_INT32:
5598                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5599                         proto_tree_set_int(PNODE_FINFO(pi), value);
5600                         break;
5601
5602                 default:
5603                         REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
5604                             hfinfo->abbrev);
5605         }
5606
5607         return pi;
5608 }
5609
5610 proto_item *
5611 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5612                                 gint start, gint length, gint32 value,
5613                                 const char *format, ...)
5614 {
5615         proto_item  *pi;
5616         va_list      ap;
5617
5618         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
5619         if (pi != tree) {
5620                 va_start(ap, format);
5621                 proto_tree_set_representation_value(pi, format, ap);
5622                 va_end(ap);
5623         }
5624
5625         return pi;
5626 }
5627
5628 proto_item *
5629 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5630                           gint start, gint length, gint32 value,
5631                           const char *format, ...)
5632 {
5633         proto_item *pi;
5634         va_list     ap;
5635
5636         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
5637         if (pi != tree) {
5638                 TRY_TO_FAKE_THIS_REPR(pi);
5639
5640                 va_start(ap, format);
5641                 proto_tree_set_representation(pi, format, ap);
5642                 va_end(ap);
5643         }
5644
5645         return pi;
5646 }
5647
5648 /* Set the FT_INT{8,16,24,32} value */
5649 static void
5650 proto_tree_set_int(field_info *fi, gint32 value)
5651 {
5652         header_field_info *hfinfo;
5653         guint32            integer;
5654         gint               no_of_bits;
5655
5656         hfinfo = fi->hfinfo;
5657         integer = (guint32) value;
5658
5659         if (hfinfo->bitmask) {
5660                 /* Mask out irrelevant portions */
5661                 integer &= (guint32)(hfinfo->bitmask);
5662
5663                 /* Shift bits */
5664                 integer >>= hfinfo_bitshift(hfinfo);
5665
5666                 no_of_bits = ws_count_ones(hfinfo->bitmask);
5667                 integer = ws_sign_ext32(integer, no_of_bits);
5668
5669                 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5670                 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5671         }
5672
5673         fvalue_set_sinteger(&fi->value, integer);
5674 }
5675
5676 /* Add FT_INT{40,48,56,64} to a proto_tree */
5677 proto_item *
5678 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5679                      gint length, gint64 value)
5680 {
5681         proto_item        *pi = NULL;
5682         header_field_info *hfinfo;
5683
5684         CHECK_FOR_NULL_TREE(tree);
5685
5686         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5687
5688         switch (hfinfo->type) {
5689                 case FT_INT40:
5690                 case FT_INT48:
5691                 case FT_INT56:
5692                 case FT_INT64:
5693                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5694                         proto_tree_set_int64(PNODE_FINFO(pi), value);
5695                         break;
5696
5697                 default:
5698                         REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
5699                             hfinfo->abbrev);
5700         }
5701
5702         return pi;
5703 }
5704
5705 proto_item *
5706 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5707                                   gint start, gint length, gint64 value,
5708                                   const char *format, ...)
5709 {
5710         proto_item        *pi;
5711         va_list            ap;
5712
5713         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
5714         if (pi != tree) {
5715                 va_start(ap, format);
5716                 proto_tree_set_representation_value(pi, format, ap);
5717                 va_end(ap);
5718         }
5719
5720         return pi;
5721 }
5722
5723 /* Set the FT_INT{40,48,56,64} value */
5724 static void
5725 proto_tree_set_int64(field_info *fi, gint64 value)
5726 {
5727         header_field_info *hfinfo;
5728         guint64            integer;
5729         gint               no_of_bits;
5730
5731         hfinfo = fi->hfinfo;
5732         integer = value;
5733
5734         if (hfinfo->bitmask) {
5735                 /* Mask out irrelevant portions */
5736                 integer &= hfinfo->bitmask;
5737
5738                 /* Shift bits */
5739                 integer >>= hfinfo_bitshift(hfinfo);
5740
5741                 no_of_bits = ws_count_ones(hfinfo->bitmask);
5742                 integer = ws_sign_ext64(integer, no_of_bits);
5743
5744                 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5745                 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5746         }
5747
5748         fvalue_set_sinteger64(&fi->value, integer);
5749 }
5750
5751 proto_item *
5752 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5753                            gint start, gint length, gint64 value,
5754                            const char *format, ...)
5755 {
5756         proto_item        *pi;
5757         va_list            ap;
5758
5759         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
5760         if (pi != tree) {
5761                 TRY_TO_FAKE_THIS_REPR(pi);
5762
5763                 va_start(ap, format);
5764                 proto_tree_set_representation(pi, format, ap);
5765                 va_end(ap);
5766         }
5767
5768         return pi;
5769 }
5770
5771 /* Add a FT_EUI64 to a proto_tree */
5772 proto_item *
5773 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5774                      gint length, const guint64 value)
5775 {
5776         proto_item        *pi;
5777         header_field_info *hfinfo;
5778
5779         CHECK_FOR_NULL_TREE(tree);
5780
5781         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5782
5783         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
5784
5785         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5786         proto_tree_set_eui64(PNODE_FINFO(pi), value);
5787
5788         return pi;
5789 }
5790
5791 proto_item *
5792 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5793                                   gint start, gint length, const guint64 value,
5794                                   const char *format, ...)
5795 {
5796         proto_item        *pi;
5797         va_list            ap;
5798
5799         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5800         if (pi != tree) {
5801                 va_start(ap, format);
5802                 proto_tree_set_representation_value(pi, format, ap);
5803                 va_end(ap);
5804         }
5805
5806         return pi;
5807 }
5808
5809 proto_item *
5810 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5811                             gint start, gint length, const guint64 value,
5812                             const char *format, ...)
5813 {
5814         proto_item        *pi;
5815         va_list            ap;
5816
5817         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5818         if (pi != tree) {
5819                 TRY_TO_FAKE_THIS_REPR(pi);
5820
5821                 va_start(ap, format);
5822                 proto_tree_set_representation(pi, format, ap);
5823                 va_end(ap);
5824         }
5825
5826         return pi;
5827 }
5828
5829 /* Set the FT_EUI64 value */
5830 static void
5831 proto_tree_set_eui64(field_info *fi, const guint64 value)
5832 {
5833         fvalue_set_uinteger64(&fi->value, value);
5834 }
5835 static void
5836 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
5837 {
5838         if (encoding)
5839         {
5840                 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
5841         } else {
5842                 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
5843         }
5844 }
5845
5846 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
5847 static proto_item *
5848 proto_tree_add_node(proto_tree *tree, field_info *fi)
5849 {
5850         proto_node *pnode, *tnode, *sibling;
5851         field_info *tfi;
5852         guint depth = 1;
5853
5854         /*
5855          * Restrict our depth. proto_tree_traverse_pre_order and
5856          * proto_tree_traverse_post_order (and possibly others) are recursive
5857          * so we need to be mindful of our stack size.
5858          */
5859         if (tree->first_child == NULL) {
5860                 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
5861                         depth++;
5862                         if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)) {
5863                                 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
5864                                                      "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",
5865                                                      prefs.gui_max_tree_depth,
5866                                                      fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
5867                         }
5868                 }
5869         }
5870
5871         /*
5872          * Make sure "tree" is ready to have subtrees under it, by
5873          * checking whether it's been given an ett_ value.
5874          *
5875          * "PNODE_FINFO(tnode)" may be null; that's the case for the root
5876          * node of the protocol tree.  That node is not displayed,
5877          * so it doesn't need an ett_ value to remember whether it
5878          * was expanded.
5879          */
5880         tnode = tree;
5881         tfi = PNODE_FINFO(tnode);
5882         if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
5883                 REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
5884                                      fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__);
5885                 /* XXX - is it safe to continue here? */
5886         }
5887
5888         pnode = wmem_new(PNODE_POOL(tree), proto_node);
5889         PROTO_NODE_INIT(pnode);
5890         pnode->parent = tnode;
5891         PNODE_FINFO(pnode) = fi;
5892         pnode->tree_data = PTREE_DATA(tree);
5893
5894         if (tnode->last_child != NULL) {
5895                 sibling = tnode->last_child;
5896                 DISSECTOR_ASSERT(sibling->next == NULL);
5897                 sibling->next = pnode;
5898         } else
5899                 tnode->first_child = pnode;
5900         tnode->last_child = pnode;
5901
5902         tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
5903
5904         return (proto_item *)pnode;
5905 }
5906
5907
5908 /* Generic way to allocate field_info and add to proto_tree.
5909  * Sets *pfi to address of newly-allocated field_info struct */
5910 static proto_item *
5911 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
5912                   gint *length)
5913 {
5914         proto_item *pi;
5915         field_info *fi;
5916         gint            item_length;
5917
5918         get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA);
5919         fi = new_field_info(tree, hfinfo, tvb, start, item_length);
5920         pi = proto_tree_add_node(tree, fi);
5921
5922         return pi;
5923 }
5924
5925
5926 static void
5927 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
5928                    gint *item_length, const guint encoding)
5929 {
5930         gint length_remaining;
5931
5932         /*
5933          * We only allow a null tvbuff if the item has a zero length,
5934          * i.e. if there's no data backing it.
5935          */
5936         DISSECTOR_ASSERT(tvb != NULL || *length == 0);
5937
5938         /*
5939          * XXX - in some protocols, there are 32-bit unsigned length
5940          * fields, so lengths in protocol tree and tvbuff routines
5941          * should really be unsigned.  We should have, for those
5942          * field types for which "to the end of the tvbuff" makes sense,
5943          * additional routines that take no length argument and
5944          * add fields that run to the end of the tvbuff.
5945          */
5946         if (*length == -1) {
5947                 /*
5948                  * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
5949                  * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
5950                  * of -1 means "set the length to what remains in the
5951                  * tvbuff".
5952                  *
5953                  * The assumption is either that
5954                  *
5955                  *      1) the length of the item can only be determined
5956                  *         by dissection (typically true of items with
5957                  *         subitems, which are probably FT_NONE or
5958                  *         FT_PROTOCOL)
5959                  *
5960                  * or
5961                  *
5962                  *      2) if the tvbuff is "short" (either due to a short
5963                  *         snapshot length or due to lack of reassembly of
5964                  *         fragments/segments/whatever), we want to display
5965                  *         what's available in the field (probably FT_BYTES
5966                  *         or FT_STRING) and then throw an exception later
5967                  *
5968                  * or
5969                  *
5970                  *      3) the field is defined to be "what's left in the
5971                  *         packet"
5972                  *
5973                  * so we set the length to what remains in the tvbuff so
5974                  * that, if we throw an exception while dissecting, it
5975                  * has what is probably the right value.
5976                  *
5977                  * For FT_STRINGZ, it means "the string is null-terminated,
5978                  * not null-padded; set the length to the actual length
5979                  * of the string", and if the tvbuff if short, we just
5980                  * throw an exception.
5981                  *
5982                  * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG, it means "find the end of the string",
5983                  * and if the tvbuff if short, we just throw an exception.
5984                  *
5985                  * It's not valid for any other type of field.  For those
5986                  * fields, we treat -1 the same way we treat other
5987                  * negative values - we assume the length is a Really
5988                  * Big Positive Number, and throw a ReportedBoundsError
5989                  * exception, under the assumption that the Really Big
5990                  * Length would run past the end of the packet.
5991                  */
5992                 if ((IS_FT_INT(hfinfo->type)) || (IS_FT_UINT(hfinfo->type))) {
5993                         if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
5994                                 /*
5995                                  * Leave the length as -1, so our caller knows
5996                                  * it was -1.
5997                                  */
5998                                 *item_length = *length;
5999                                 return;
6000                         } else if (encoding & ENC_VARINT_QUIC) {
6001                                 switch (tvb_get_guint8(tvb, start) >> 6)
6002                                 {
6003                                 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6004                                         *item_length = 1;
6005                                         break;
6006                                 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6007                                         *item_length = 2;
6008                                         break;
6009                                 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6010                                         *item_length = 4;
6011                                         break;
6012                                 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6013                                         *item_length = 8;
6014                                         break;
6015                                 }
6016                         }
6017                 }
6018
6019                 switch (hfinfo->type) {
6020
6021                 case FT_PROTOCOL:
6022                 case FT_NONE:
6023                 case FT_BYTES:
6024                 case FT_STRING:
6025                 case FT_STRINGZPAD:
6026                 case FT_STRINGZTRUNC:
6027                         /*
6028                          * We allow FT_PROTOCOLs to be zero-length -
6029                          * for example, an ONC RPC NULL procedure has
6030                          * neither arguments nor reply, so the
6031                          * payload for that protocol is empty.
6032                          *
6033                          * We also allow the others to be zero-length -
6034                          * because that's the way the code has been for a
6035                          * long, long time.
6036                          *
6037                          * However, we want to ensure that the start
6038                          * offset is not *past* the byte past the end
6039                          * of the tvbuff: we throw an exception in that
6040                          * case.
6041                          */
6042                         *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6043                         DISSECTOR_ASSERT(*length >= 0);
6044                         break;
6045
6046                 case FT_STRINGZ:
6047                         /*
6048                          * Leave the length as -1, so our caller knows
6049                          * it was -1.
6050                          */
6051                         break;
6052
6053                 default:
6054                         THROW(ReportedBoundsError);
6055                         DISSECTOR_ASSERT_NOT_REACHED();
6056                 }
6057                 *item_length = *length;
6058         } else {
6059                 *item_length = *length;
6060                 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6061                         /*
6062                          * These types are for interior nodes of the
6063                          * tree, and don't have data associated with
6064                          * them; if the length is negative (XXX - see
6065                          * above) or goes past the end of the tvbuff,
6066                          * cut it short at the end of the tvbuff.
6067                          * That way, if this field is selected in
6068                          * Wireshark, we don't highlight stuff past
6069                          * the end of the data.
6070                          */
6071                         /* XXX - what to do, if we don't have a tvb? */
6072                         if (tvb) {
6073                                 length_remaining = tvb_captured_length_remaining(tvb, start);
6074                                 if (*item_length < 0 ||
6075                                         (*item_length > 0 &&
6076                                           (length_remaining < *item_length)))
6077                                         *item_length = length_remaining;
6078                         }
6079                 }
6080                 if (*item_length < 0) {
6081                         THROW(ReportedBoundsError);
6082                 }
6083         }
6084 }
6085
6086 static gint
6087 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
6088                 gint length, guint item_length, const gint encoding)
6089 {
6090         guint32 n;
6091
6092         /*
6093          * We need to get the correct item length here.
6094          * That's normally done by proto_tree_new_item(),
6095          * but we won't be calling it.
6096          */
6097         switch (hfinfo->type) {
6098
6099         case FT_NONE:
6100         case FT_PROTOCOL:
6101         case FT_BYTES:
6102                 /*
6103                  * The length is the specified length.
6104                  */
6105                 break;
6106
6107         case FT_UINT_BYTES:
6108                 n = get_uint_value(NULL, tvb, start, length, encoding);
6109                 item_length += n;
6110                 break;
6111
6112         /* XXX - make these just FT_UINT? */
6113         case FT_UINT8:
6114         case FT_UINT16:
6115         case FT_UINT24:
6116         case FT_UINT32:
6117         case FT_UINT40:
6118         case FT_UINT48:
6119         case FT_UINT56:
6120         case FT_UINT64:
6121         /* XXX - make these just FT_INT? */
6122         case FT_INT8:
6123         case FT_INT16:
6124         case FT_INT24:
6125         case FT_INT32:
6126         case FT_INT40:
6127         case FT_INT48:
6128         case FT_INT56:
6129         case FT_INT64:
6130                 if (encoding & (ENC_VARIANT_MASK)) {
6131                         if (length < -1) {
6132                                 report_type_length_mismatch(NULL, "a FT_[U]INT", length, TRUE);
6133                         }
6134                         if (length == -1) {
6135                                 guint64 dummy;
6136                                 /* This can throw an exception */
6137                                 /* XXX - do this without fetching the varint? */
6138                                 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN, &dummy, encoding);
6139                                 if (length == 0) {
6140                                         THROW(ReportedBoundsError);
6141                                 }
6142                         }
6143                         item_length = length;
6144                         break;
6145                 }
6146
6147                 /*
6148                  * The length is the specified length.
6149                  */
6150                 break;
6151
6152         case FT_BOOLEAN:
6153         case FT_CHAR:
6154         case FT_IPv4:
6155         case FT_IPXNET:
6156         case FT_IPv6:
6157         case FT_FCWWN:
6158         case FT_AX25:
6159         case FT_VINES:
6160         case FT_ETHER:
6161         case FT_EUI64:
6162         case FT_GUID:
6163         case FT_OID:
6164         case FT_REL_OID:
6165         case FT_SYSTEM_ID:
6166         case FT_FLOAT:
6167         case FT_DOUBLE:
6168         case FT_STRING:
6169                 /*
6170                  * The length is the specified length.
6171                  */
6172                 break;
6173
6174         case FT_STRINGZ:
6175                 if (length < -1) {
6176                         report_type_length_mismatch(NULL, "a string", length, TRUE);
6177                 }
6178                 if (length == -1) {
6179                         /* This can throw an exception */
6180                         /* XXX - do this without fetching the string? */
6181                         tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
6182                 }
6183                 item_length = length;
6184                 break;
6185
6186         case FT_UINT_STRING:
6187                 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
6188                 item_length += n;
6189                 break;
6190
6191         case FT_STRINGZPAD:
6192         case FT_STRINGZTRUNC:
6193         case FT_ABSOLUTE_TIME:
6194         case FT_RELATIVE_TIME:
6195         case FT_IEEE_11073_SFLOAT:
6196         case FT_IEEE_11073_FLOAT:
6197                 /*
6198                  * The length is the specified length.
6199                  */
6200                 break;
6201
6202         default:
6203                 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in gset_full_length()",
6204                                      hfinfo->abbrev,
6205                                      hfinfo->type,
6206                                      ftype_name(hfinfo->type));
6207                 break;
6208         }
6209         return item_length;
6210 }
6211
6212 static field_info *
6213 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6214                const gint start, const gint item_length)
6215 {
6216         field_info *fi;
6217
6218         FIELD_INFO_NEW(PNODE_POOL(tree), fi);
6219
6220         fi->hfinfo     = hfinfo;
6221         fi->start      = start;
6222         fi->start     += (tvb)?tvb_raw_offset(tvb):0;
6223         fi->length     = item_length;
6224         fi->tree_type  = -1;
6225         fi->flags      = 0;
6226         if (!PTREE_DATA(tree)->visible)
6227                 FI_SET_FLAG(fi, FI_HIDDEN);
6228         fvalue_init(&fi->value, fi->hfinfo->type);
6229         fi->rep        = NULL;
6230
6231         /* add the data source tvbuff */
6232         fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
6233
6234         fi->appendix_start  = 0;
6235         fi->appendix_length = 0;
6236
6237         return fi;
6238 }
6239
6240 /* If the protocol tree is to be visible, set the representation of a
6241    proto_tree entry with the name of the field for the item and with
6242    the value formatted with the supplied printf-style format and
6243    argument list. */
6244 static void
6245 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6246 {
6247         g_assert(pi);
6248
6249         /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6250          * items string representation */
6251         if (PTREE_DATA(pi)->visible && !proto_item_is_hidden(pi)) {
6252                 int               ret = 0;
6253                 field_info        *fi = PITEM_FINFO(pi);
6254                 header_field_info *hf;
6255
6256                 DISSECTOR_ASSERT(fi);
6257
6258                 hf = fi->hfinfo;
6259
6260                 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6261                 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
6262                         guint64 val;
6263                         char *p;
6264
6265                         if (IS_FT_UINT32(hf->type))
6266                                 val = fvalue_get_uinteger(&fi->value);
6267                         else
6268                                 val = fvalue_get_uinteger64(&fi->value);
6269
6270                         val <<= hfinfo_bitshift(hf);
6271
6272                         p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6273                         ret = (int) (p - fi->rep->representation);
6274                 }
6275
6276                 /* put in the hf name */
6277                 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
6278
6279                 /* If possible, Put in the value of the string */
6280                 if (ret < ITEM_LABEL_LENGTH) {
6281                         ret += g_vsnprintf(fi->rep->representation + ret,
6282                                           ITEM_LABEL_LENGTH - ret, format, ap);
6283                 }
6284                 if (ret >= ITEM_LABEL_LENGTH) {
6285                         /* Uh oh, we don't have enough room.  Tell the user
6286                          * that the field is truncated.
6287                          */
6288                         LABEL_MARK_TRUNCATED_START(fi->rep->representation);
6289                 }
6290         }
6291 }
6292
6293 /* If the protocol tree is to be visible, set the representation of a
6294    proto_tree entry with the representation formatted with the supplied
6295    printf-style format and argument list. */
6296 static void
6297 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6298 {
6299         int         ret;        /*tmp return value */
6300         field_info *fi = PITEM_FINFO(pi);
6301
6302         DISSECTOR_ASSERT(fi);
6303
6304         if (!proto_item_is_hidden(pi)) {
6305                 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6306                 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
6307                                   format, ap);
6308                 if (ret >= ITEM_LABEL_LENGTH) {
6309                         /* Uh oh, we don't have enough room.  Tell the user
6310                          * that the field is truncated.
6311                          */
6312                         LABEL_MARK_TRUNCATED_START(fi->rep->representation);
6313                 }
6314         }
6315 }
6316
6317 static int
6318 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
6319 {
6320         gsize res = g_strlcpy(dest, src, dest_size);
6321
6322         if (res > dest_size)
6323                 res = dest_size;
6324         return (int) res;
6325 }
6326
6327 static header_field_info *
6328 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
6329 {
6330         header_field_info *dup_hfinfo;
6331
6332         if (hfinfo->same_name_prev_id == -1)
6333                 return NULL;
6334         PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
6335         return dup_hfinfo;
6336 }
6337
6338 static void
6339 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
6340 {
6341         g_free(last_field_name);
6342         last_field_name = NULL;
6343
6344         if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
6345                 /* No hfinfo with the same name */
6346                 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
6347                 return;
6348         }
6349
6350         if (hfinfo->same_name_next) {
6351                 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
6352         }
6353
6354         if (hfinfo->same_name_prev_id != -1) {
6355                 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
6356                 same_name_prev->same_name_next = hfinfo->same_name_next;
6357                 if (!hfinfo->same_name_next) {
6358                         /* It's always the latest added hfinfo which is stored in gpa_name_map */
6359                         g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
6360                 }
6361         }
6362 }
6363
6364 int
6365 proto_item_fill_display_label(field_info *finfo, gchar *display_label_str, const int label_str_size)
6366 {
6367         header_field_info *hfinfo = finfo->hfinfo;
6368         int label_len = 0;
6369         char *tmp_str;
6370         guint8 *bytes;
6371         guint32 number;
6372         guint64 number64;
6373         const true_false_string  *tfstring;
6374         const char *hf_str_val;
6375         char number_buf[48];
6376         const char *number_out;
6377         address addr;
6378         ws_in4_addr ipv4;
6379         ws_in6_addr *ipv6;
6380
6381         switch (hfinfo->type) {
6382
6383                 case FT_NONE:
6384                 case FT_PROTOCOL:
6385                         return protoo_strlcpy(display_label_str, UTF8_CHECK_MARK, label_str_size);
6386
6387                 case FT_UINT_BYTES:
6388                 case FT_BYTES:
6389                         tmp_str = hfinfo_format_bytes(NULL,
6390                                 hfinfo,
6391                                 (guint8 *)fvalue_get(&finfo->value),
6392                                 fvalue_length(&finfo->value));
6393                         label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6394                         wmem_free(NULL, tmp_str);
6395                         break;
6396
6397                 case FT_ABSOLUTE_TIME:
6398                         tmp_str = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
6399                         label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6400                         wmem_free(NULL, tmp_str);
6401                         break;
6402
6403                 case FT_RELATIVE_TIME:
6404                         tmp_str = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
6405                         label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6406                         wmem_free(NULL, tmp_str);
6407                         break;
6408
6409                 case FT_BOOLEAN:
6410                         number64 = fvalue_get_uinteger64(&finfo->value);
6411                         tfstring = &tfs_true_false;
6412                         if (hfinfo->strings) {
6413                                 tfstring = (const struct true_false_string*) hfinfo->strings;
6414                         }
6415                         label_len = protoo_strlcpy(display_label_str,
6416                                         tfs_get_string(!!number64, tfstring), label_str_size);
6417                         break;
6418
6419                 case FT_CHAR:
6420                         number = fvalue_get_uinteger(&finfo->value);
6421
6422                         if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6423                                 gchar tmp[ITEM_LABEL_LENGTH];
6424                                 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
6425
6426                                 DISSECTOR_ASSERT(fmtfunc);
6427                                 fmtfunc(tmp, number);
6428
6429                                 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
6430
6431                         } else if (hfinfo->strings) {
6432                                 number_out = hf_try_val_to_str(number, hfinfo);
6433
6434                                 if (!number_out) {
6435                                         number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
6436                                 }
6437
6438                                 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6439
6440                         } else {
6441                                 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
6442
6443                                 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6444                         }
6445
6446                         break;
6447
6448                 /* XXX - make these just FT_NUMBER? */
6449                 case FT_INT8:
6450                 case FT_INT16:
6451                 case FT_INT24:
6452                 case FT_INT32:
6453                 case FT_UINT8:
6454                 case FT_UINT16:
6455                 case FT_UINT24:
6456                 case FT_UINT32:
6457                 case FT_FRAMENUM:
6458                         hf_str_val = NULL;
6459                         number = IS_FT_INT(hfinfo->type) ?
6460                                 (guint32) fvalue_get_sinteger(&finfo->value) :
6461                                 fvalue_get_uinteger(&finfo->value);
6462
6463                         if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6464                                 gchar tmp[ITEM_LABEL_LENGTH];
6465                                 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
6466
6467                                 DISSECTOR_ASSERT(fmtfunc);
6468                                 fmtfunc(tmp, number);
6469
6470                                 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
6471
6472                         } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
6473                                 if (hfinfo->display & BASE_UNIT_STRING) {
6474                                         number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
6475                                         label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6476                                         hf_str_val = hf_try_val_to_str(number, hfinfo);
6477                                         label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
6478                                 } else {
6479                                         number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
6480
6481                                         if (!number_out) {
6482                                                 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
6483                                         }
6484
6485                                         label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6486                                 }
6487                         } else {
6488                                 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
6489
6490                                 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6491                         }
6492
6493                         break;
6494
6495                 case FT_INT40:
6496                 case FT_INT48:
6497                 case FT_INT56:
6498                 case FT_INT64:
6499                 case FT_UINT40:
6500                 case FT_UINT48:
6501                 case FT_UINT56:
6502                 case FT_UINT64:
6503                         hf_str_val = NULL;
6504                         number64 = IS_FT_INT(hfinfo->type) ?
6505                                 (guint64) fvalue_get_sinteger64(&finfo->value) :
6506                                 fvalue_get_uinteger64(&finfo->value);
6507
6508                         if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6509                                 gchar tmp[ITEM_LABEL_LENGTH];
6510                                 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
6511
6512                                 DISSECTOR_ASSERT(fmtfunc64);
6513                                 fmtfunc64(tmp, number64);
6514
6515                                 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
6516                         } else if (hfinfo->strings) {
6517                                 if (hfinfo->display & BASE_UNIT_STRING) {
6518                                         number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
6519                                         label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6520                                         hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6521                                         label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
6522                                 } else {
6523                                         number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6524
6525                                         if (!number_out)
6526                                                 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
6527
6528                                         label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6529                                 }
6530                         } else {
6531                                 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
6532
6533                                 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6534                         }
6535
6536                         break;
6537
6538                 case FT_EUI64:
6539                         tmp_str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
6540                         label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6541                         wmem_free(NULL, tmp_str);
6542                         break;
6543
6544                 case FT_IPv4:
6545                         ipv4 = fvalue_get_uinteger(&finfo->value);
6546                         set_address (&addr, AT_IPv4, 4, &ipv4);
6547                         address_to_str_buf(&addr, display_label_str, label_str_size);
6548                         label_len = (int)strlen(display_label_str);
6549                         break;
6550
6551                 case FT_IPv6:
6552                         ipv6 = (ws_in6_addr *)fvalue_get(&finfo->value);
6553                         set_address (&addr, AT_IPv6, sizeof(ws_in6_addr), ipv6);
6554                         address_to_str_buf(&addr, display_label_str, label_str_size);
6555                         label_len = (int)strlen(display_label_str);
6556                         break;
6557
6558                 case FT_FCWWN:
6559                         set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
6560                         address_to_str_buf(&addr, display_label_str, label_str_size);
6561                         label_len = (int)strlen(display_label_str);
6562                         break;
6563
6564                 case FT_ETHER:
6565                         set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
6566                         address_to_str_buf(&addr, display_label_str, label_str_size);
6567                         label_len = (int)strlen(display_label_str);
6568                         break;
6569
6570                 case FT_GUID:
6571                         tmp_str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
6572                         label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6573                         wmem_free(NULL, tmp_str);
6574                         break;
6575
6576                 case FT_REL_OID:
6577                         bytes = (guint8 *)fvalue_get(&finfo->value);
6578                         tmp_str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
6579                         label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6580                         wmem_free(NULL, tmp_str);
6581                         break;
6582
6583                 case FT_OID:
6584                         bytes = (guint8 *)fvalue_get(&finfo->value);
6585                         tmp_str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
6586                         label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6587                         wmem_free(NULL, tmp_str);
6588                         break;
6589
6590                 case FT_SYSTEM_ID:
6591                         bytes = (guint8 *)fvalue_get(&finfo->value);
6592                         tmp_str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
6593                         label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6594                         wmem_free(NULL, tmp_str);
6595                         break;
6596
6597                 case FT_FLOAT:
6598                         if (hfinfo->display & BASE_UNIT_STRING) {
6599                                 double d_value = fvalue_get_floating(&finfo->value);
6600                                 g_snprintf(display_label_str, label_str_size,
6601                                                 "%." G_STRINGIFY(FLT_DIG) "g%s", d_value,
6602                                                 unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
6603                         } else {
6604                                 g_snprintf(display_label_str, label_str_size,
6605                                                 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
6606                         }
6607                         label_len = (int)strlen(display_label_str);
6608                         break;
6609
6610                 case FT_DOUBLE:
6611                         if (hfinfo->display & BASE_UNIT_STRING) {
6612                                 double d_value = fvalue_get_floating(&finfo->value);
6613                                 g_snprintf(display_label_str, label_str_size,
6614                                                 "%." G_STRINGIFY(DBL_DIG) "g%s", d_value,
6615                                                 unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
6616                         } else {
6617                                 g_snprintf(display_label_str, label_str_size,
6618                                                 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
6619                         }
6620                         label_len = (int)strlen(display_label_str);
6621                         break;
6622
6623                 case FT_STRING:
6624                 case FT_STRINGZ:
6625                 case FT_UINT_STRING:
6626                 case FT_STRINGZPAD:
6627                 case FT_STRINGZTRUNC:
6628                         bytes = (guint8 *)fvalue_get(&finfo->value);
6629                         tmp_str = hfinfo_format_text(NULL, hfinfo, bytes);
6630                         label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6631                         wmem_free(NULL, tmp_str);
6632                         break;
6633
6634                 default:
6635                         /* First try ftype string representation */
6636                         tmp_str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
6637                         if (!tmp_str) {
6638                                 /* Default to show as bytes */
6639                                 bytes = (guint8 *)fvalue_get(&finfo->value);
6640                                 tmp_str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
6641                         }
6642                         label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6643                         wmem_free(NULL, tmp_str);
6644                         break;
6645         }
6646         return label_len;
6647 }
6648
6649 /* -------------------------- */
6650 const gchar *
6651 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
6652                  gchar *result, gchar *expr, const int size)
6653 {
6654         guint32             number;
6655         guint64             number64;
6656         guint8             *bytes;
6657
6658         int                 len, prev_len, last, i, offset_r = 0, offset_e = 0, label_len;
6659         GPtrArray          *finfos;
6660         field_info         *finfo         = NULL;
6661         header_field_info*  hfinfo;
6662         const gchar        *abbrev        = NULL;
6663
6664         const char *hf_str_val;
6665         char number_buf[48];
6666         const char *number_out;
6667         char *str;
6668         int *field_idx;
6669         int field_id;
6670         int ii = 0;
6671
6672         g_assert(field_ids != NULL);
6673         while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
6674                 field_id = *field_idx;
6675                 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
6676
6677                 /* do we need to rewind ? */
6678                 if (!hfinfo)
6679                         return "";
6680
6681                 if (occurrence < 0) {
6682                         /* Search other direction */
6683                         while (hfinfo->same_name_prev_id != -1) {
6684                                 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
6685                         }
6686                 }
6687
6688                 prev_len = 0; /* Reset handled occurrences */
6689
6690                 while (hfinfo) {
6691                         finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
6692
6693                         if (!finfos || !(len = g_ptr_array_len(finfos))) {
6694                                 if (occurrence < 0) {
6695                                         hfinfo = hfinfo->same_name_next;
6696                                 } else {
6697                                         hfinfo = hfinfo_same_name_get_prev(hfinfo);
6698                                 }
6699                                 continue;
6700                         }
6701
6702                         /* Are there enough occurrences of the field? */
6703                         if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
6704                                 if (occurrence < 0) {
6705                                         hfinfo = hfinfo->same_name_next;
6706                                 } else {
6707                                         hfinfo = hfinfo_same_name_get_prev(hfinfo);
6708                                 }
6709                                 prev_len += len;
6710                                 continue;
6711                         }
6712
6713                         /* Calculate single index or set outer bounderies */
6714                         if (occurrence < 0) {
6715                                 i = occurrence + len + prev_len;
6716                                 last = i;
6717                         } else if (occurrence > 0) {
6718                                 i = occurrence - 1 - prev_len;
6719                                 last = i;
6720                         } else {
6721                                 i = 0;
6722                                 last = len - 1;
6723                         }
6724
6725                         prev_len += len; /* Count handled occurrences */
6726
6727                         while (i <= last) {
6728                                 finfo = (field_info *)g_ptr_array_index(finfos, i);
6729
6730                                 if (offset_r && (offset_r < (size - 2)))
6731                                         result[offset_r++] = ',';
6732
6733                                 if (offset_e && (offset_e < (size - 2)))
6734                                         expr[offset_e++] = ',';
6735
6736                                 switch (hfinfo->type) {
6737
6738                                         case FT_NONE:
6739                                         case FT_PROTOCOL:
6740                                                 /* Prevent multiple check marks */
6741                                                 if (strstr(result, UTF8_CHECK_MARK ",") == NULL) {
6742                                                         offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6743                                                 } else {
6744                                                         result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
6745                                                 }
6746                                                 break;
6747
6748                                         case FT_BOOLEAN:
6749                                                 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6750
6751                                                 number64 = fvalue_get_uinteger64(&finfo->value);
6752                                                 offset_e += protoo_strlcpy(expr+offset_e,
6753                                                                 number64 ? "1" : "0", size-offset_e);
6754                                                 break;
6755
6756                                         case FT_CHAR:
6757                                                 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6758
6759                                                 number = fvalue_get_uinteger(&finfo->value);
6760
6761                                                 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6762                                                         hf_str_val = hf_try_val_to_str(number, hfinfo);
6763                                                         g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6764                                                 } else {
6765                                                         number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
6766
6767                                                         (void) g_strlcpy(expr+offset_e, number_out, size-offset_e);
6768                                                 }
6769
6770                                                 offset_e = (int)strlen(expr);
6771                                                 break;
6772
6773                                                 /* XXX - make these just FT_NUMBER? */
6774                                         case FT_INT8:
6775                                         case FT_INT16:
6776                                         case FT_INT24:
6777                                         case FT_INT32:
6778                                         case FT_UINT8:
6779                                         case FT_UINT16:
6780                                         case FT_UINT24:
6781                                         case FT_UINT32:
6782                                         case FT_FRAMENUM:
6783                                                 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6784
6785                                                 hf_str_val = NULL;
6786                                                 number = IS_FT_INT(hfinfo->type) ?
6787                                                         (guint32) fvalue_get_sinteger(&finfo->value) :
6788                                                         fvalue_get_uinteger(&finfo->value);
6789
6790                                                 if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
6791                                                         hf_str_val = hf_try_val_to_str(number, hfinfo);
6792                                                 }
6793
6794                                                 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6795
6796                                                         hf_str_val = hf_try_val_to_str(number, hfinfo);
6797                                                         g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6798                                                 } else {
6799                                                         number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
6800
6801                                                         (void) g_strlcpy(expr+offset_e, number_out, size-offset_e);
6802                                                 }
6803
6804                                                 offset_e = (int)strlen(expr);
6805                                                 break;
6806
6807                                         case FT_INT40:
6808                                         case FT_INT48:
6809                                         case FT_INT56:
6810                                         case FT_INT64:
6811                                         case FT_UINT40:
6812                                         case FT_UINT48:
6813                                         case FT_UINT56:
6814                                         case FT_UINT64:
6815                                                 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6816
6817                                                 hf_str_val = NULL;
6818                                                 number64 = IS_FT_INT(hfinfo->type) ?
6819                                                         (guint64) fvalue_get_sinteger64(&finfo->value) :
6820                                                         fvalue_get_uinteger64(&finfo->value);
6821
6822                                                 if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
6823                                                         hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6824                                                 }
6825
6826                                                 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6827                                                         g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6828                                                 } else {
6829                                                         number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
6830
6831                                                         (void) g_strlcpy(expr+offset_e, number_out, size-offset_e);
6832                                                 }
6833
6834                                                 offset_e = (int)strlen(expr);
6835                                                 break;
6836
6837                                         case FT_REL_OID:
6838                                                 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6839
6840                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
6841                                                 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
6842                                                 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6843                                                 wmem_free(NULL, str);
6844                                                 break;
6845
6846                                         case FT_OID:
6847                                                 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6848
6849                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
6850                                                 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
6851                                                 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6852                                                 wmem_free(NULL, str);
6853                                                 break;
6854
6855                                         case FT_SYSTEM_ID:
6856                                                 label_len = proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6857
6858                                                 offset_e += protoo_strlcpy(expr+offset_e, result+offset_r, size-offset_e);
6859
6860                                                 offset_r += label_len;
6861                                                 break;
6862
6863                                         default:
6864                                                 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6865                                                 break;
6866                                 }
6867                                 i++;
6868                         }
6869
6870                         switch (hfinfo->type) {
6871
6872                                 case FT_BOOLEAN:
6873                                 case FT_CHAR:
6874                                 case FT_UINT8:
6875                                 case FT_UINT16:
6876                                 case FT_UINT24:
6877                                 case FT_UINT32:
6878                                 case FT_UINT40:
6879                                 case FT_UINT48:
6880                                 case FT_UINT56:
6881                                 case FT_UINT64:
6882                                 case FT_FRAMENUM:
6883                                 case FT_INT8:
6884                                 case FT_INT16:
6885                                 case FT_INT24:
6886                                 case FT_INT32:
6887                                 case FT_INT40:
6888                                 case FT_INT48:
6889                                 case FT_INT56:
6890                                 case FT_INT64:
6891                                 case FT_OID:
6892                                 case FT_REL_OID:
6893                                 case FT_SYSTEM_ID:
6894                                         /* for these types, "expr" is filled in the loop above */
6895                                         break;
6896
6897                                 default:
6898                                         /* for all others, just copy "result" to "expr" */
6899                                         (void) g_strlcpy(expr, result, size);
6900                                         break;
6901                         }
6902
6903                         if (!abbrev) {
6904                                 /* Store abbrev for return value */
6905                                 abbrev = hfinfo->abbrev;
6906                         }
6907
6908                         if (occurrence == 0) {
6909                                 /* Fetch next hfinfo with same name (abbrev) */
6910                                 hfinfo = hfinfo_same_name_get_prev(hfinfo);
6911                         } else {
6912                                 hfinfo = NULL;
6913                         }
6914                 }
6915         }
6916
6917         return abbrev ? abbrev : "";
6918 }
6919
6920
6921 /* Set text of proto_item after having already been created. */
6922 void
6923 proto_item_set_text(proto_item *pi, const char *format, ...)
6924 {
6925         field_info *fi = NULL;
6926         va_list     ap;
6927
6928         TRY_TO_FAKE_THIS_REPR_VOID(pi);
6929
6930         fi = PITEM_FINFO(pi);
6931         if (fi == NULL)
6932                 return;
6933
6934         if (fi->rep) {
6935                 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
6936                 fi->rep = NULL;
6937         }
6938
6939         va_start(ap, format);
6940         proto_tree_set_representation(pi, format, ap);
6941         va_end(ap);
6942 }
6943
6944 /* Append to text of proto_item after having already been created. */
6945 void
6946 proto_item_append_text(proto_item *pi, const char *format, ...)
6947 {
6948         field_info *fi = NULL;
6949         size_t      curlen;
6950         va_list     ap;
6951
6952         TRY_TO_FAKE_THIS_REPR_VOID(pi);
6953
6954         fi = PITEM_FINFO(pi);
6955         if (fi == NULL) {
6956                 return;
6957         }
6958
6959         if (!proto_item_is_hidden(pi)) {
6960                 /*
6961                  * If we don't already have a representation,
6962                  * generate the default representation.
6963                  */
6964                 if (fi->rep == NULL) {
6965                         ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6966                         proto_item_fill_label(fi, fi->rep->representation);
6967                 }
6968
6969                 curlen = strlen(fi->rep->representation);
6970                 if (ITEM_LABEL_LENGTH > curlen) {
6971                         va_start(ap, format);
6972                         g_vsnprintf(fi->rep->representation + curlen,
6973                                 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
6974                         va_end(ap);
6975                 }
6976         }
6977 }
6978
6979 /* Prepend to text of proto_item after having already been created. */
6980 void
6981 proto_item_prepend_text(proto_item *pi, const char *format, ...)
6982 {
6983         field_info *fi = NULL;
6984         char        representation[ITEM_LABEL_LENGTH];
6985         va_list     ap;
6986
6987         TRY_TO_FAKE_THIS_REPR_VOID(pi);
6988
6989         fi = PITEM_FINFO(pi);
6990         if (fi == NULL) {
6991                 return;
6992         }
6993
6994         if (!proto_item_is_hidden(pi)) {
6995                 /*
6996                  * If we don't already have a representation,
6997                  * generate the default representation.
6998                  */
6999                 if (fi->rep == NULL) {
7000                         ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
7001                         proto_item_fill_label(fi, representation);
7002                 } else
7003                         (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
7004
7005                 va_start(ap, format);
7006                 g_vsnprintf(fi->rep->representation,
7007                         ITEM_LABEL_LENGTH, format, ap);
7008                 va_end(ap);
7009                 (void) g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
7010         }
7011 }
7012
7013 static void
7014 finfo_set_len(field_info *fi, const gint length)
7015 {
7016         gint length_remaining;
7017
7018         DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev);
7019         length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7020         if (length > length_remaining)
7021                 fi->length = length_remaining;
7022         else
7023                 fi->length = length;
7024
7025         /*
7026          * You cannot just make the "len" field of a GByteArray
7027          * larger, if there's no data to back that length;
7028          * you can only make it smaller.
7029          */
7030         if (fi->value.ftype->ftype == FT_BYTES && fi->length <= (gint)fi->value.value.bytes->len)
7031                 fi->value.value.bytes->len = fi->length;
7032 }
7033
7034 void
7035 proto_item_set_len(proto_item *pi, const gint length)
7036 {
7037         field_info *fi;
7038
7039         TRY_TO_FAKE_THIS_REPR_VOID(pi);
7040
7041         fi = PITEM_FINFO(pi);
7042         if (fi == NULL)
7043                 return;
7044
7045         finfo_set_len(fi, length);
7046 }
7047
7048 /*
7049  * Sets the length of the item based on its start and on the specified
7050  * offset, which is the offset past the end of the item; as the start
7051  * in the item is relative to the beginning of the data source tvbuff,
7052  * we need to pass in a tvbuff - the end offset is relative to the beginning
7053  * of that tvbuff.
7054  */
7055 void
7056 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
7057 {
7058         field_info *fi;
7059         gint length;
7060
7061         TRY_TO_FAKE_THIS_REPR_VOID(pi);
7062
7063         fi = PITEM_FINFO(pi);
7064         if (fi == NULL)
7065                 return;
7066
7067         end += tvb_raw_offset(tvb);
7068         DISSECTOR_ASSERT(end >= fi->start);
7069         length = end - fi->start;
7070
7071         finfo_set_len(fi, length);
7072 }
7073
7074 int
7075 proto_item_get_len(const proto_item *pi)
7076 {
7077         field_info *fi;
7078
7079         if (!pi)
7080                 return -1;
7081         fi = PITEM_FINFO(pi);
7082         return fi ? fi->length : -1;
7083 }
7084
7085 void
7086 proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7087         if (!ti) {
7088                 return;
7089         }
7090         FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_OFFSET(bits_offset));
7091         FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_SIZE(bits_len));
7092 }
7093
7094 char *
7095 proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7096 {
7097         field_info *fi;
7098
7099         if (!pi)
7100                 return "";
7101         fi = PITEM_FINFO(pi);
7102         DISSECTOR_ASSERT(fi->hfinfo != NULL);
7103         return fvalue_to_string_repr(scope, &fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7104 }
7105
7106 proto_tree *
7107 proto_tree_create_root(packet_info *pinfo)
7108 {
7109         proto_node *pnode;
7110
7111         /* Initialize the proto_node */
7112         pnode = g_slice_new(proto_tree);
7113         PROTO_NODE_INIT(pnode);
7114         pnode->parent = NULL;
7115         PNODE_FINFO(pnode) = NULL;
7116         pnode->tree_data = g_slice_new(tree_data_t);
7117
7118         /* Make sure we can access pinfo everywhere */
7119         pnode->tree_data->pinfo = pinfo;
7120
7121         /* Don't initialize the tree_data_t. Wait until we know we need it */
7122         pnode->tree_data->interesting_hfids = NULL;
7123
7124         /* Set the default to FALSE so it's easier to
7125          * find errors; if we expect to see the protocol tree
7126          * but for some reason the default 'visible' is not
7127          * changed, then we'll find out very quickly. */
7128         pnode->tree_data->visible = FALSE;
7129
7130         /* Make sure that we fake protocols (if possible) */
7131         pnode->tree_data->fake_protocols = TRUE;
7132
7133         /* Keep track of the number of children */
7134         pnode->tree_data->count = 0;
7135
7136         return (proto_tree *)pnode;
7137 }
7138
7139
7140 /* "prime" a proto_tree with a single hfid that a dfilter
7141  * is interested in. */
7142 void
7143 proto_tree_prime_with_hfid(proto_tree *tree _U_, const gint hfid)
7144 {
7145         header_field_info *hfinfo;
7146
7147         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
7148         /* this field is referenced by a filter so increase the refcount.
7149            also increase the refcount for the parent, i.e the protocol.
7150         */
7151         hfinfo->ref_type = HF_REF_TYPE_DIRECT;
7152         /* only increase the refcount if there is a parent.
7153            if this is a protocol and not a field then parent will be -1
7154            and there is no parent to add any refcounting for.
7155         */
7156         if (hfinfo->parent != -1) {
7157                 header_field_info *parent_hfinfo;
7158                 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
7159
7160                 /* Mark parent as indirectly referenced unless it is already directly
7161                  * referenced, i.e. the user has specified the parent in a filter.
7162                  */
7163                 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
7164                         parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
7165         }
7166 }
7167
7168 proto_tree *
7169 proto_item_add_subtree(proto_item *pi,  const gint idx) {
7170         field_info *fi;
7171
7172         if (!pi)
7173                 return NULL;
7174
7175         DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
7176
7177         fi = PITEM_FINFO(pi);
7178         if (!fi)
7179                 return (proto_tree *)pi;
7180
7181         fi->tree_type = idx;
7182
7183         return (proto_tree *)pi;
7184 }
7185
7186 proto_tree *
7187 proto_item_get_subtree(proto_item *pi) {
7188         field_info *fi;
7189
7190         if (!pi)
7191                 return NULL;
7192         fi = PITEM_FINFO(pi);
7193         if ( (!fi) || (fi->tree_type == -1) )
7194                 return NULL;
7195         return (proto_tree *)pi;
7196 }
7197
7198 proto_item *
7199 proto_item_get_parent(const proto_item *ti) {
7200         if (!ti)
7201                 return NULL;
7202         return ti->parent;
7203 }
7204
7205 proto_item *
7206 proto_item_get_parent_nth(proto_item *ti, int gen) {
7207         if (!ti)
7208                 return NULL;
7209         while (gen--) {
7210                 ti = ti->parent;
7211                 if (!ti)
7212                         return NULL;
7213         }
7214         return ti;
7215 }
7216
7217
7218 proto_item *
7219 proto_tree_get_parent(proto_tree *tree) {
7220         if (!tree)
7221                 return NULL;
7222         return (proto_item *)tree;
7223 }
7224
7225 proto_tree *
7226 proto_tree_get_parent_tree(proto_tree *tree) {
7227         if (!tree)
7228                 return NULL;
7229
7230         /* we're the root tree, there's no parent
7231            return ourselves so the caller has at least a tree to attach to */
7232         if (!tree->parent)
7233                 return tree;
7234
7235         return (proto_tree *)tree->parent;
7236 }
7237
7238 proto_tree *
7239 proto_tree_get_root(proto_tree *tree) {
7240         if (!tree)
7241                 return NULL;
7242         while (tree->parent) {
7243                 tree = tree->parent;
7244         }
7245         return tree;
7246 }
7247
7248 void
7249 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
7250                      proto_item *item_to_move)
7251 {
7252         /* This function doesn't generate any values. It only reorganizes the prococol tree
7253          * so we can bail out immediately if it isn't visible. */
7254         if (!tree || !PTREE_DATA(tree)->visible)
7255                 return;
7256
7257         DISSECTOR_ASSERT(item_to_move->parent == tree);
7258         DISSECTOR_ASSERT(fixed_item->parent == tree);
7259
7260         /*** cut item_to_move out ***/
7261
7262         /* is item_to_move the first? */
7263         if (tree->first_child == item_to_move) {
7264                 /* simply change first child to next */
7265                 tree->first_child = item_to_move->next;
7266
7267                 DISSECTOR_ASSERT(tree->last_child != item_to_move);
7268         } else {
7269                 proto_item *curr_item;
7270                 /* find previous and change it's next */
7271                 for (curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
7272                         if (curr_item->next == item_to_move) {
7273                                 break;
7274                         }
7275                 }
7276
7277                 DISSECTOR_ASSERT(curr_item);
7278
7279                 curr_item->next = item_to_move->next;
7280
7281                 /* fix last_child if required */
7282                 if (tree->last_child == item_to_move) {
7283                         tree->last_child = curr_item;
7284                 }
7285         }
7286
7287         /*** insert to_move after fixed ***/
7288         item_to_move->next = fixed_item->next;
7289         fixed_item->next = item_to_move;
7290         if (tree->last_child == fixed_item) {
7291                 tree->last_child = item_to_move;
7292         }
7293 }
7294
7295 void
7296 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
7297                         const gint length)
7298 {
7299         field_info *fi;
7300
7301         if (tree == NULL)
7302                 return;
7303
7304         fi = PTREE_FINFO(tree);
7305         if (fi == NULL)
7306                 return;
7307
7308         start += tvb_raw_offset(tvb);
7309         DISSECTOR_ASSERT(start >= 0);
7310         DISSECTOR_ASSERT(length >= 0);
7311
7312         fi->appendix_start = start;
7313         fi->appendix_length = length;
7314 }
7315
7316 static void
7317 check_valid_filter_name_or_fail(const char *filter_name)
7318 {
7319         gboolean found_invalid = proto_check_field_name(filter_name);
7320
7321         /* Additionally forbid upper case characters. */
7322         if (!found_invalid) {
7323                 for (guint i = 0; filter_name[i]; i++) {
7324                         if (g_ascii_isupper(filter_name[i])) {
7325                                 found_invalid = TRUE;
7326                                 break;
7327                         }
7328                 }
7329         }
7330
7331         if (found_invalid) {
7332                 ws_error("Protocol filter name \"%s\" has one or more invalid characters."
7333                         " Allowed are lower characters, digits, '-', '_' and non-repeating '.'."
7334                         " This might be caused by an inappropriate plugin or a development error.", filter_name);
7335         }
7336 }
7337
7338 int
7339 proto_register_protocol(const char *name, const char *short_name,
7340                         const char *filter_name)
7341 {
7342         protocol_t *protocol;
7343         header_field_info *hfinfo;
7344
7345         /*
7346          * Make sure there's not already a protocol with any of those
7347          * names.  Crash if there is, as that's an error in the code
7348          * or an inappropriate plugin.
7349          * This situation has to be fixed to not register more than one
7350          * protocol with the same name.
7351          */
7352
7353         if (g_hash_table_lookup(proto_names, name)) {
7354                 /* g_error will terminate the program */
7355                 ws_error("Duplicate protocol name \"%s\"!"
7356                         " This might be caused by an inappropriate plugin or a development error.", name);
7357         }
7358
7359         if (g_hash_table_lookup(proto_short_names, short_name)) {
7360                 ws_error("Duplicate protocol short_name \"%s\"!"
7361                         " This might be caused by an inappropriate plugin or a development error.", short_name);
7362         }
7363
7364         check_valid_filter_name_or_fail(filter_name);
7365
7366         if (g_hash_table_lookup(proto_filter_names, filter_name)) {
7367                 ws_error("Duplicate protocol filter_name \"%s\"!"
7368                         " This might be caused by an inappropriate plugin or a development error.", filter_name);
7369         }
7370
7371         /*
7372          * Add this protocol to the list of known protocols;
7373          * the list is sorted by protocol short name.
7374          */
7375         protocol = g_new(protocol_t, 1);
7376         protocol->name = name;
7377         protocol->short_name = short_name;
7378         protocol->filter_name = filter_name;
7379         protocol->fields = NULL; /* Delegate until actually needed */
7380         protocol->is_enabled = TRUE; /* protocol is enabled by default */
7381         protocol->enabled_by_default = TRUE; /* see previous comment */
7382         protocol->can_toggle = TRUE;
7383         protocol->parent_proto_id = -1;
7384         protocol->heur_list = NULL;
7385
7386         /* List will be sorted later by name, when all protocols completed registering */
7387         protocols = g_list_prepend(protocols, protocol);
7388         g_hash_table_insert(proto_names, (gpointer)name, protocol);
7389         g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
7390         g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
7391
7392         /* Here we allocate a new header_field_info struct */
7393         hfinfo = g_slice_new(header_field_info);
7394         hfinfo->name = name;
7395         hfinfo->abbrev = filter_name;
7396         hfinfo->type = FT_PROTOCOL;
7397         hfinfo->display = BASE_NONE;
7398         hfinfo->strings = protocol;
7399         hfinfo->bitmask = 0;
7400         hfinfo->ref_type = HF_REF_TYPE_NONE;
7401         hfinfo->blurb = NULL;
7402         hfinfo->parent = -1; /* This field differentiates protos and fields */
7403
7404         protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
7405         return protocol->proto_id;
7406 }
7407
7408 int
7409 proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
7410 {
7411         protocol_t *protocol;
7412         header_field_info *hfinfo;
7413
7414         /*
7415          * Helper protocols don't need the strict rules as a "regular" protocol
7416          * Just register it in a list and make a hf_ field from it
7417          */
7418         if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
7419                 ws_error("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name);
7420         }
7421
7422         if (parent_proto < 0) {
7423                 ws_error("Must have a valid parent protocol for helper protocol \"%s\"!"
7424                         " This might be caused by an inappropriate plugin or a development error.", name);
7425         }
7426
7427         check_valid_filter_name_or_fail(filter_name);
7428
7429         /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
7430         protocol = g_new(protocol_t, 1);
7431         protocol->name = name;
7432         protocol->short_name = short_name;
7433         protocol->filter_name = filter_name;
7434         protocol->fields = NULL; /* Delegate until actually needed */
7435
7436         /* Enabling and toggling is really determined by parent protocol,
7437            but provide default values here */
7438         protocol->is_enabled = TRUE;
7439         protocol->enabled_by_default = TRUE;
7440         protocol->can_toggle = TRUE;
7441
7442         protocol->parent_proto_id = parent_proto;
7443         protocol->heur_list = NULL;
7444
7445         /* List will be sorted later by name, when all protocols completed registering */
7446         protocols = g_list_prepend(protocols, protocol);
7447
7448         /* Here we allocate a new header_field_info struct */
7449         hfinfo = g_slice_new(header_field_info);
7450         hfinfo->name = name;
7451         hfinfo->abbrev = filter_name;
7452         hfinfo->type = field_type;
7453         hfinfo->display = BASE_NONE;
7454         if (field_type == FT_BYTES) {
7455                 hfinfo->display |= (BASE_NO_DISPLAY_VALUE|BASE_PROTOCOL_INFO);
7456         }
7457         hfinfo->strings = protocol;
7458         hfinfo->bitmask = 0;
7459         hfinfo->ref_type = HF_REF_TYPE_NONE;
7460         hfinfo->blurb = NULL;
7461         hfinfo->parent = -1; /* This field differentiates protos and fields */
7462
7463         protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
7464         return protocol->proto_id;
7465 }
7466
7467 gboolean
7468 proto_deregister_protocol(const char *short_name)
7469 {
7470         protocol_t *protocol;
7471         header_field_info *hfinfo;
7472         int proto_id;
7473         guint i;
7474
7475         proto_id = proto_get_id_by_short_name(short_name);
7476         protocol = find_protocol_by_id(proto_id);
7477         if (protocol == NULL)
7478                 return FALSE;
7479
7480         g_hash_table_remove(proto_names, protocol->name);
7481         g_hash_table_remove(proto_short_names, (gpointer)short_name);
7482         g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
7483
7484         if (protocol->fields) {
7485                 for (i = 0; i < protocol->fields->len; i++) {
7486                         hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
7487                         hfinfo_remove_from_gpa_name_map(hfinfo);
7488                         expert_deregister_expertinfo(hfinfo->abbrev);
7489                         g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
7490                 }
7491                 g_ptr_array_free(protocol->fields, TRUE);
7492                 protocol->fields = NULL;
7493         }
7494
7495         g_list_free(protocol->heur_list);
7496
7497         /* Remove this protocol from the list of known protocols */
7498         protocols = g_list_remove(protocols, protocol);
7499
7500         g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
7501         g_hash_table_steal(gpa_name_map, protocol->filter_name);
7502
7503         g_free(last_field_name);
7504         last_field_name = NULL;
7505
7506         return TRUE;
7507 }
7508
7509 void
7510 proto_register_alias(const int proto_id, const char *alias_name)
7511 {
7512         protocol_t *protocol;
7513
7514         protocol = find_protocol_by_id(proto_id);
7515         if (alias_name && protocol) {
7516                 g_hash_table_insert(gpa_protocol_aliases, (gpointer) alias_name, (gpointer)protocol->filter_name);
7517         }
7518 }
7519
7520 /*
7521  * Routines to use to iterate over the protocols.
7522  * The argument passed to the iterator routines is an opaque cookie to
7523  * their callers; it's the GList pointer for the current element in
7524  * the list.
7525  * The ID of the protocol is returned, or -1 if there is no protocol.
7526  */
7527 int
7528 proto_get_first_protocol(void **cookie)
7529 {
7530         protocol_t *protocol;
7531
7532         if (protocols == NULL)
7533                 return -1;
7534         *cookie = protocols;
7535         protocol = (protocol_t *)protocols->data;
7536         return protocol->proto_id;
7537 }
7538
7539 int
7540 proto_get_data_protocol(void *cookie)
7541 {
7542         GList *list_item = (GList *)cookie;
7543
7544         protocol_t *protocol = (protocol_t *)list_item->data;
7545         return protocol->proto_id;
7546 }
7547
7548 int
7549 proto_get_next_protocol(void **cookie)
7550 {
7551         GList      *list_item = (GList *)*cookie;
7552         protocol_t *protocol;
7553
7554         list_item = g_list_next(list_item);
7555         if (list_item == NULL)
7556                 return -1;
7557         *cookie = list_item;
7558         protocol = (protocol_t *)list_item->data;
7559         return protocol->proto_id;
7560 }
7561
7562 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
7563         assume that the cookie stored by
7564         proto_get_(first|next)_protocol_field() will never have a
7565         value of NULL. So, to preserve this semantic, the cookie value
7566         below is adjusted so that the cookie value stored is 1 + the
7567         current (zero-based) array index.
7568 */
7569 header_field_info *
7570 proto_get_first_protocol_field(const int proto_id, void **cookie)
7571 {
7572         protocol_t *protocol = find_protocol_by_id(proto_id);
7573
7574         if ((protocol == NULL) || (protocol->fields == NULL) || (protocol->fields->len == 0))
7575                 return NULL;
7576
7577         *cookie = GUINT_TO_POINTER(0 + 1);
7578         return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
7579 }
7580
7581 header_field_info *
7582 proto_get_next_protocol_field(const int proto_id, void **cookie)
7583 {
7584         protocol_t *protocol = find_protocol_by_id(proto_id);
7585         guint       i        = GPOINTER_TO_UINT(*cookie) - 1;
7586
7587         i++;
7588
7589         if ((protocol->fields == NULL) || (i >= protocol->fields->len))
7590                 return NULL;
7591
7592         *cookie = GUINT_TO_POINTER(i + 1);
7593         return (header_field_info *)g_ptr_array_index(protocol->fields, i);
7594 }
7595
7596 protocol_t *
7597 find_protocol_by_id(const int proto_id)
7598 {
7599         header_field_info *hfinfo;
7600
7601         if (proto_id < 0)
7602                 return NULL;
7603
7604         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
7605         if (hfinfo->type != FT_PROTOCOL) {
7606                 DISSECTOR_ASSERT(hfinfo->display & BASE_PROTOCOL_INFO);
7607         }
7608         return (protocol_t *)hfinfo->strings;
7609 }
7610
7611 int
7612 proto_get_id(const protocol_t *protocol)
7613 {
7614         return protocol->proto_id;
7615 }
7616
7617 gboolean
7618 proto_name_already_registered(const gchar *name)
7619 {
7620         DISSECTOR_ASSERT_HINT(name, "No name present");
7621
7622         if (g_hash_table_lookup(proto_names, name) != NULL)
7623                 return TRUE;
7624         return FALSE;
7625 }
7626
7627 int
7628 proto_get_id_by_filter_name(const gchar *filter_name)
7629 {
7630         const protocol_t *protocol = NULL;
7631
7632         DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
7633
7634         protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
7635
7636         if (protocol == NULL)
7637                 return -1;
7638         return protocol->proto_id;
7639 }
7640
7641 int
7642 proto_get_id_by_short_name(const gchar *short_name)
7643 {
7644         const protocol_t *protocol = NULL;
7645
7646         DISSECTOR_ASSERT_HINT(short_name, "No short name present");
7647
7648         protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
7649
7650         if (protocol == NULL)
7651                 return -1;
7652         return protocol->proto_id;
7653 }
7654
7655 const char *
7656 proto_get_protocol_name(const int proto_id)
7657 {
7658         protocol_t *protocol;
7659
7660         protocol = find_protocol_by_id(proto_id);
7661
7662         if (protocol == NULL)
7663                 return NULL;
7664         return protocol->name;
7665 }
7666
7667 const char *
7668 proto_get_protocol_short_name(const protocol_t *protocol)
7669 {
7670         if (protocol == NULL)
7671                 return "(none)";
7672         return protocol->short_name;
7673 }
7674
7675 const char *
7676 proto_get_protocol_long_name(const protocol_t *protocol)
7677 {
7678         if (protocol == NULL)
7679                 return "(none)";
7680         return protocol->name;
7681 }
7682
7683 const char *
7684 proto_get_protocol_filter_name(const int proto_id)
7685 {
7686         protocol_t *protocol;
7687
7688         protocol = find_protocol_by_id(proto_id);
7689         if (protocol == NULL)
7690                 return "(none)";
7691         return protocol->filter_name;
7692 }
7693
7694 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
7695 {
7696         heur_dtbl_entry_t* heuristic_dissector;
7697
7698         if (protocol == NULL)
7699                 return;
7700
7701         heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
7702         if (heuristic_dissector != NULL)
7703         {
7704                 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
7705         }
7706 }
7707
7708 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
7709 {
7710         if (protocol == NULL)
7711                 return;
7712
7713         g_list_foreach(protocol->heur_list, func, user_data);
7714 }
7715
7716 void
7717 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
7718                           gboolean *is_tcp, gboolean *is_udp,
7719                           gboolean *is_sctp, gboolean *is_tls,
7720                           gboolean *is_rtp,
7721                           gboolean *is_lte_rlc)
7722 {
7723         wmem_list_frame_t *protos = wmem_list_head(layers);
7724         int         proto_id;
7725         const char *proto_name;
7726
7727         /* Walk the list of a available protocols in the packet and
7728            attempt to find "major" ones. */
7729         /* It might make more sense to assemble and return a bitfield. */
7730         while (protos != NULL)
7731         {
7732                 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
7733                 proto_name = proto_get_protocol_filter_name(proto_id);
7734
7735                 if (is_ip && ((!strcmp(proto_name, "ip")) ||
7736                               (!strcmp(proto_name, "ipv6")))) {
7737                         *is_ip = TRUE;
7738                 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
7739                         *is_tcp = TRUE;
7740                 } else if (is_udp && !strcmp(proto_name, "udp")) {
7741                         *is_udp = TRUE;
7742                 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
7743                         *is_sctp = TRUE;
7744                 } else if (is_tls && !strcmp(proto_name, "tls")) {
7745                         *is_tls = TRUE;
7746                 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
7747                         *is_rtp = TRUE;
7748                 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
7749                         *is_lte_rlc = TRUE;
7750                 }
7751
7752                 protos = wmem_list_frame_next(protos);
7753         }
7754 }
7755
7756 gboolean
7757 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
7758 {
7759         wmem_list_frame_t *protos = wmem_list_head(layers);
7760         int         proto_id;
7761         const char *name;
7762
7763         /* Walk the list of a available protocols in the packet and
7764            attempt to find the specified protocol. */
7765         while (protos != NULL)
7766         {
7767                 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
7768                 name = proto_get_protocol_filter_name(proto_id);
7769
7770                 if (!strcmp(name, proto_name))
7771                 {
7772                         return TRUE;
7773                 }
7774
7775                 protos = wmem_list_frame_next(protos);
7776         }
7777
7778         return FALSE;
7779 }
7780
7781 gboolean
7782 proto_is_pino(const protocol_t *protocol)
7783 {
7784         return (protocol->parent_proto_id != -1);
7785 }
7786
7787 gboolean
7788 proto_is_protocol_enabled(const protocol_t *protocol)
7789 {
7790         if (protocol == NULL)
7791                 return FALSE;
7792
7793         //parent protocol determines enable/disable for helper dissectors
7794         if (proto_is_pino(protocol))
7795                 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
7796
7797         return protocol->is_enabled;
7798 }
7799
7800 gboolean
7801 proto_is_protocol_enabled_by_default(const protocol_t *protocol)
7802 {
7803         //parent protocol determines enable/disable for helper dissectors
7804         if (proto_is_pino(protocol))
7805                 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
7806
7807         return protocol->enabled_by_default;
7808 }
7809
7810 gboolean
7811 proto_can_toggle_protocol(const int proto_id)
7812 {
7813         protocol_t *protocol;
7814
7815         protocol = find_protocol_by_id(proto_id);
7816         //parent protocol determines toggling for helper dissectors
7817         if (proto_is_pino(protocol))
7818                 return proto_can_toggle_protocol(protocol->parent_proto_id);
7819
7820         return protocol->can_toggle;
7821 }
7822
7823 void
7824 proto_disable_by_default(const int proto_id)
7825 {
7826         protocol_t *protocol;
7827
7828         protocol = find_protocol_by_id(proto_id);
7829         DISSECTOR_ASSERT(protocol->can_toggle);
7830         DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
7831         protocol->is_enabled = FALSE;
7832         protocol->enabled_by_default = FALSE;
7833 }
7834
7835 void
7836 proto_set_decoding(const int proto_id, const gboolean enabled)
7837 {
7838         protocol_t *protocol;
7839
7840         protocol = find_protocol_by_id(proto_id);
7841         DISSECTOR_ASSERT(protocol->can_toggle);
7842         DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
7843         protocol->is_enabled = enabled;
7844 }
7845
7846 void
7847 proto_reenable_all(void)
7848 {
7849         protocol_t *protocol;
7850         GList      *list_item = protocols;
7851
7852         if (protocols == NULL)
7853                 return;
7854
7855         while (list_item) {
7856                 protocol = (protocol_t *)list_item->data;
7857                 if (protocol->can_toggle && protocol->enabled_by_default)
7858                         protocol->is_enabled = TRUE;
7859                 list_item = g_list_next(list_item);
7860         }
7861 }
7862
7863 void
7864 proto_set_cant_toggle(const int proto_id)
7865 {
7866         protocol_t *protocol;
7867
7868         protocol = find_protocol_by_id(proto_id);
7869         protocol->can_toggle = FALSE;
7870 }
7871
7872 static int
7873 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
7874 {
7875         if (proto != NULL) {
7876                 g_ptr_array_add(proto->fields, hfi);
7877         }
7878
7879         return proto_register_field_init(hfi, parent);
7880 }
7881
7882 /* for use with static arrays only, since we don't allocate our own copies
7883 of the header_field_info struct contained within the hf_register_info struct */
7884 void
7885 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
7886 {
7887         hf_register_info *ptr = hf;
7888         protocol_t       *proto;
7889         int               i;
7890
7891         proto = find_protocol_by_id(parent);
7892
7893         if (proto->fields == NULL) {
7894                 proto->fields = g_ptr_array_sized_new(num_records);
7895         }
7896
7897         for (i = 0; i < num_records; i++, ptr++) {
7898                 /*
7899                  * Make sure we haven't registered this yet.
7900                  * Most fields have variables associated with them
7901                  * that are initialized to -1; some have array elements,
7902                  * or possibly uninitialized variables, so we also allow
7903                  * 0 (which is unlikely to be the field ID we get back
7904                  * from "proto_register_field_init()").
7905                  */
7906                 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
7907                         fprintf(stderr,
7908                                 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
7909                                 ptr->hfinfo.abbrev);
7910                         return;
7911                 }
7912
7913                 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
7914         }
7915 }
7916
7917 void
7918 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
7919 {
7920         int               i;
7921         protocol_t       *proto;
7922
7923         proto = find_protocol_by_id(parent);
7924
7925         if (proto->fields == NULL) {
7926                 proto->fields = g_ptr_array_sized_new(num_records);
7927         }
7928
7929         for (i = 0; i < num_records; i++) {
7930                 /*
7931                  * Make sure we haven't registered this yet.
7932                  */
7933                 if (hfi[i].id != -1) {
7934                         fprintf(stderr,
7935                                 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7936                                 hfi[i].abbrev);
7937                         return;
7938                 }
7939
7940                 proto_register_field_common(proto, &hfi[i], parent);
7941         }
7942 }
7943
7944 void
7945 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
7946 {
7947         int               i;
7948         protocol_t       *proto;
7949
7950         proto = find_protocol_by_id(parent);
7951
7952         if (proto->fields == NULL) {
7953                 proto->fields = g_ptr_array_sized_new(num_records);
7954         }
7955
7956
7957         for (i = 0; i < num_records; i++) {
7958                 /*
7959                  * Make sure we haven't registered this yet.
7960                  */
7961                 if (hfi[i]->id != -1) {
7962                         fprintf(stderr,
7963                                 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7964                                 hfi[i]->abbrev);
7965                         return;
7966                 }
7967
7968                 proto_register_field_common(proto, hfi[i], parent);
7969         }
7970 }
7971
7972 /* deregister already registered fields */
7973 void
7974 proto_deregister_field (const int parent, gint hf_id)
7975 {
7976         header_field_info *hfi;
7977         protocol_t       *proto;
7978         guint             i;
7979
7980         g_free(last_field_name);
7981         last_field_name = NULL;
7982
7983         if (hf_id == -1 || hf_id == 0)
7984                 return;
7985
7986         proto = find_protocol_by_id (parent);
7987         if (!proto || proto->fields == NULL) {
7988                 return;
7989         }
7990
7991         for (i = 0; i < proto->fields->len; i++) {
7992                 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
7993                 if (hfi->id == hf_id) {
7994                         /* Found the hf_id in this protocol */
7995                         g_hash_table_steal(gpa_name_map, hfi->abbrev);
7996                         g_ptr_array_remove_index_fast(proto->fields, i);
7997                         g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
7998                         return;
7999                 }
8000         }
8001 }
8002
8003 void
8004 proto_add_deregistered_data (void *data)
8005 {
8006         g_ptr_array_add(deregistered_data, data);
8007 }
8008
8009 void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8010 {
8011         if (field_strings == NULL) {
8012                 return;
8013         }
8014
8015         switch (field_type) {
8016                 case FT_FRAMENUM:
8017                         /* This is just an integer represented as a pointer */
8018                         break;
8019                 case FT_PROTOCOL: {
8020                         protocol_t *protocol = (protocol_t *)field_strings;
8021                         g_free((gchar *)protocol->short_name);
8022                         break;
8023                 }
8024                 case FT_BOOLEAN: {
8025                         true_false_string *tf = (true_false_string *)field_strings;
8026                         g_free((gchar *)tf->true_string);
8027                         g_free((gchar *)tf->false_string);
8028                         break;
8029                 }
8030                 case FT_UINT40:
8031                 case FT_INT40:
8032                 case FT_UINT48:
8033                 case FT_INT48:
8034                 case FT_UINT56:
8035                 case FT_INT56:
8036                 case FT_UINT64:
8037                 case FT_INT64: {
8038                         /*
8039                          * XXX - if it's BASE_RANGE_STRING, or
8040                          * BASE_EXT_STRING, should we free it?
8041                          */
8042                         if (field_display & BASE_UNIT_STRING) {
8043                                 unit_name_string *unit = (unit_name_string *)field_strings;
8044                                 g_free((gchar *)unit->singular);
8045                                 g_free((gchar *)unit->plural);
8046                         } else {
8047                                 val64_string *vs64 = (val64_string *)field_strings;
8048                                 while (vs64->strptr) {
8049                                         g_free((gchar *)vs64->strptr);
8050                                         vs64++;
8051                                 }
8052                         }
8053                         break;
8054                 }
8055                 case FT_CHAR:
8056                 case FT_UINT8:
8057                 case FT_INT8:
8058                 case FT_UINT16:
8059                 case FT_INT16:
8060                 case FT_UINT24:
8061                 case FT_INT24:
8062                 case FT_UINT32:
8063                 case FT_INT32:
8064                 case FT_FLOAT:
8065                 case FT_DOUBLE: {
8066                         /*
8067                          * XXX - if it's BASE_RANGE_STRING, or
8068                          * BASE_EXT_STRING, should we free it?
8069                          */
8070                         if (field_display & BASE_UNIT_STRING) {
8071                                 unit_name_string *unit = (unit_name_string *)field_strings;
8072                                 g_free((gchar *)unit->singular);
8073                                 g_free((gchar *)unit->plural);
8074                         } else if (field_display & BASE_RANGE_STRING) {
8075                                 range_string *rs = (range_string *)field_strings;
8076                                 while (rs->strptr) {
8077                                         g_free((gchar *)rs->strptr);
8078                                         rs++;
8079                                 }
8080                         } else {
8081                                 value_string *vs = (value_string *)field_strings;
8082                                 while (vs->strptr) {
8083                                         g_free((gchar *)vs->strptr);
8084                                         vs++;
8085                                 }
8086                         }
8087                         break;
8088                 default:
8089                         break;
8090                 }
8091         }
8092
8093         if (field_type != FT_FRAMENUM) {
8094                 g_free((void *)field_strings);
8095         }
8096 }
8097
8098 static void
8099 free_deregistered_field (gpointer data, gpointer user_data _U_)
8100 {
8101         header_field_info *hfi = (header_field_info *) data;
8102         gint hf_id = hfi->id;
8103
8104         g_free((char *)hfi->name);
8105         g_free((char *)hfi->abbrev);
8106         g_free((char *)hfi->blurb);
8107
8108         proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
8109
8110         if (hfi->parent == -1)
8111                 g_slice_free(header_field_info, hfi);
8112
8113         gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
8114 }
8115
8116 static void
8117 free_deregistered_data (gpointer data, gpointer user_data _U_)
8118 {
8119         g_free (data);
8120 }
8121
8122 /* free deregistered fields and data */
8123 void
8124 proto_free_deregistered_fields (void)
8125 {
8126         expert_free_deregistered_expertinfos();
8127
8128         g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
8129         g_ptr_array_free(deregistered_fields, TRUE);
8130         deregistered_fields = g_ptr_array_new();
8131
8132         g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
8133         g_ptr_array_free(deregistered_data, TRUE);
8134         deregistered_data = g_ptr_array_new();
8135 }
8136
8137 /* chars allowed in field abbrev: alphanumerics, '-', "_", and ".". */
8138 static
8139 const guint8 fld_abbrev_chars[256] = {
8140         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
8141         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
8142         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.'      */
8143         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9'       */
8144         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O'       */
8145         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
8146         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o'       */
8147         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z'       */
8148         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
8149         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
8150         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
8151         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
8152         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
8153         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
8154         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
8155         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
8156 };
8157
8158 static const value_string hf_display[] = {
8159         { BASE_NONE,                      "BASE_NONE"                      },
8160         { BASE_DEC,                       "BASE_DEC"                       },
8161         { BASE_HEX,                       "BASE_HEX"                       },
8162         { BASE_OCT,                       "BASE_OCT"                       },
8163         { BASE_DEC_HEX,                   "BASE_DEC_HEX"                   },
8164         { BASE_HEX_DEC,                   "BASE_HEX_DEC"                   },
8165         { BASE_CUSTOM,                    "BASE_CUSTOM"                    },
8166         { BASE_NONE|BASE_RANGE_STRING,    "BASE_NONE|BASE_RANGE_STRING"    },
8167         { BASE_DEC|BASE_RANGE_STRING,     "BASE_DEC|BASE_RANGE_STRING"     },
8168         { BASE_HEX|BASE_RANGE_STRING,     "BASE_HEX|BASE_RANGE_STRING"     },
8169         { BASE_OCT|BASE_RANGE_STRING,     "BASE_OCT|BASE_RANGE_STRING"     },
8170         { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
8171         { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
8172         { BASE_CUSTOM|BASE_RANGE_STRING,  "BASE_CUSTOM|BASE_RANGE_STRING"  },
8173         { BASE_NONE|BASE_VAL64_STRING,    "BASE_NONE|BASE_VAL64_STRING"    },
8174         { BASE_DEC|BASE_VAL64_STRING,     "BASE_DEC|BASE_VAL64_STRING"     },
8175         { BASE_HEX|BASE_VAL64_STRING,     "BASE_HEX|BASE_VAL64_STRING"     },
8176         { BASE_OCT|BASE_VAL64_STRING,     "BASE_OCT|BASE_VAL64_STRING"     },
8177         { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
8178         { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
8179         { BASE_CUSTOM|BASE_VAL64_STRING,  "BASE_CUSTOM|BASE_VAL64_STRING"  },
8180         /* Alias: BASE_NONE { BASE_FLOAT,                       "BASE_FLOAT" }, */
8181         /* Alias: BASE_NONE { STR_ASCII,                          "STR_ASCII" }, */
8182         { STR_UNICODE,                    "STR_UNICODE" },
8183         { ABSOLUTE_TIME_LOCAL,            "ABSOLUTE_TIME_LOCAL"            },
8184         { ABSOLUTE_TIME_UTC,              "ABSOLUTE_TIME_UTC"              },
8185         { ABSOLUTE_TIME_DOY_UTC,          "ABSOLUTE_TIME_DOY_UTC"          },
8186         { BASE_PT_UDP,                    "BASE_PT_UDP"                    },
8187         { BASE_PT_TCP,                    "BASE_PT_TCP"                    },
8188         { BASE_PT_DCCP,                   "BASE_PT_DCCP"                   },
8189         { BASE_PT_SCTP,                   "BASE_PT_SCTP"                   },
8190         { BASE_OUI,                       "BASE_OUI"                       },
8191         { 0,                              NULL } };
8192
8193 const char* proto_field_display_to_string(int field_display)
8194 {
8195         return val_to_str_const(field_display, hf_display, "Unknown");
8196 }
8197
8198 static inline port_type
8199 display_to_port_type(field_display_e e)
8200 {
8201         switch (e) {
8202         case BASE_PT_UDP:
8203                 return PT_UDP;
8204         case BASE_PT_TCP:
8205                 return PT_TCP;
8206         case BASE_PT_DCCP:
8207                 return PT_DCCP;
8208         case BASE_PT_SCTP:
8209                 return PT_SCTP;
8210         default:
8211                 break;
8212         }
8213         return PT_NONE;
8214 }
8215
8216 /* temporary function containing assert part for easier profiling */
8217 static void
8218 tmp_fld_check_assert(header_field_info *hfinfo)
8219 {
8220         gchar* tmp_str;
8221
8222         /* The field must have a name (with length > 0) */
8223         if (!hfinfo->name || !hfinfo->name[0]) {
8224                 if (hfinfo->abbrev)
8225                         /* Try to identify the field */
8226                         ws_error("Field (abbrev='%s') does not have a name\n",
8227                                 hfinfo->abbrev);
8228                 else
8229                         /* Hum, no luck */
8230                         ws_error("Field does not have a name (nor an abbreviation)\n");
8231         }
8232
8233         /* fields with an empty string for an abbreviation aren't filterable */
8234         if (!hfinfo->abbrev || !hfinfo->abbrev[0])
8235                 ws_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
8236
8237         /*  These types of fields are allowed to have value_strings,
8238          *  true_false_strings or a protocol_t struct
8239          */
8240         if (hfinfo->strings != NULL) {
8241                 switch (hfinfo->type) {
8242                 case FT_CHAR:
8243                 case FT_UINT8:
8244                 case FT_UINT16:
8245                 case FT_UINT24:
8246                 case FT_UINT32:
8247                 case FT_UINT40:
8248                 case FT_UINT48:
8249                 case FT_UINT56:
8250                 case FT_UINT64:
8251                 case FT_INT8:
8252                 case FT_INT16:
8253                 case FT_INT24:
8254                 case FT_INT32:
8255                 case FT_INT40:
8256                 case FT_INT48:
8257                 case FT_INT56:
8258                 case FT_INT64:
8259                 case FT_BOOLEAN:
8260                 case FT_PROTOCOL:
8261                 case FT_FRAMENUM:
8262                         break;
8263                 case FT_FLOAT:
8264                 case FT_DOUBLE:
8265                         //allowed to support string if its a unit decsription
8266                         if (hfinfo->display & BASE_UNIT_STRING)
8267                                 break;
8268
8269                         //fallthrough
8270                 case FT_BYTES:
8271                         //allowed to support string if its a protocol (for pinos)
8272                         if (hfinfo->display & BASE_PROTOCOL_INFO)
8273                                 break;
8274
8275                         //fallthrough
8276                 default:
8277                         ws_error("Field '%s' (%s) has a 'strings' value but is of type %s"
8278                                 " (which is not allowed to have strings)\n",
8279                                 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
8280                 }
8281         }
8282
8283         /* TODO: This check may slow down startup, and output quite a few warnings.
8284            It would be good to be able to enable this (and possibly other checks?)
8285            in non-release builds.   */
8286 #ifdef ENABLE_CHECK_FILTER
8287         /* Check for duplicate value_string values.
8288            There are lots that have the same value *and* string, so for now only
8289            report those that have same value but different string. */
8290         if ((hfinfo->strings != NULL) &&
8291             !(hfinfo->display & BASE_RANGE_STRING) &&
8292             !(hfinfo->display & BASE_UNIT_STRING) &&
8293             !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
8294             (
8295                     (hfinfo->type == FT_CHAR)  ||
8296                     (hfinfo->type == FT_UINT8)  ||
8297                     (hfinfo->type == FT_UINT16) ||
8298                     (hfinfo->type == FT_UINT24) ||
8299                     (hfinfo->type == FT_UINT32) ||
8300                     (hfinfo->type == FT_INT8)   ||
8301                     (hfinfo->type == FT_INT16)  ||
8302                     (hfinfo->type == FT_INT24)  ||
8303                     (hfinfo->type == FT_INT32)  )) {
8304
8305                 if (hfinfo->display & BASE_EXT_STRING) {
8306                         if (hfinfo->display & BASE_VAL64_STRING) {
8307                                 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings);
8308                                 CHECK_HF_VALUE(val64_string, G_GINT64_MODIFIER, start_values);
8309                         } else {
8310                                 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings);
8311                                 CHECK_HF_VALUE(value_string, "", start_values);
8312                         }
8313                 } else {
8314                         const value_string *start_values = (const value_string*)hfinfo->strings;
8315                         CHECK_HF_VALUE(value_string, "", start_values);
8316                 }
8317         }
8318
8319         if (hfinfo->type == FT_BOOLEAN) {
8320                 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
8321                 if (tfs) {
8322                         if (strcmp(tfs->false_string, tfs->true_string) == 0) {
8323                                 ws_warning("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",
8324                                                    hfinfo->name, hfinfo->abbrev,
8325                                                    tfs->false_string, tfs->true_string);
8326                         }
8327                 }
8328         }
8329
8330         if (hfinfo->display & BASE_RANGE_STRING) {
8331                 const range_string *rs = (const range_string*)(hfinfo->strings);
8332                 if (rs) {
8333                         const range_string *this_it = rs;
8334
8335                         do {
8336                                 if (this_it->value_max < this_it->value_min) {
8337                                         ws_warning("value_range_string error:  %s (%s) entry for \"%s\" - max(%u 0x%x) is less than min(%u 0x%x)",
8338                                                           hfinfo->name, hfinfo->abbrev,
8339                                                           this_it->strptr,
8340                                                           this_it->value_max, this_it->value_max,
8341                                                           this_it->value_min, this_it->value_min);
8342                                         ++this_it;
8343                                         continue;
8344                                 }
8345
8346                                 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
8347                                         /* Not OK if this one is completely hidden by an earlier one! */
8348                                         if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
8349                                                 ws_warning("value_range_string error:  %s (%s) hidden by earlier entry "
8350                                                                   "(prev=\"%s\":  %u 0x%x -> %u 0x%x)  (this=\"%s\":  %u 0x%x -> %u 0x%x)",
8351                                                                   hfinfo->name, hfinfo->abbrev,
8352                                                                   prev_it->strptr, prev_it->value_min, prev_it->value_min,
8353                                                                   prev_it->value_max, prev_it->value_max,
8354                                                                   this_it->strptr, this_it->value_min, this_it->value_min,
8355                                                                   this_it->value_max, this_it->value_max);
8356                                         }
8357                                 }
8358                                 ++this_it;
8359                         } while (this_it->strptr);
8360                 }
8361         }
8362 #endif
8363
8364         switch (hfinfo->type) {
8365
8366                 case FT_CHAR:
8367                         /*  Require the char type to have BASE_HEX, BASE_OCT,
8368                          *  BASE_CUSTOM, or BASE_NONE as its base.
8369                          *
8370                          *  If the display value is BASE_NONE and there is a
8371                          *  strings conversion then the dissector writer is
8372                          *  telling us that the field's numerical value is
8373                          *  meaningless; we'll avoid showing the value to the
8374                          *  user.
8375                          */
8376                         switch (FIELD_DISPLAY(hfinfo->display)) {
8377                                 case BASE_HEX:
8378                                 case BASE_OCT:
8379                                 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
8380                                         break;
8381                                 case BASE_NONE:
8382                                         if (hfinfo->strings == NULL)
8383                                                 ws_error("Field '%s' (%s) is an integral value (%s)"
8384                                                         " but is being displayed as BASE_NONE but"
8385                                                         " without a strings conversion",
8386                                                         hfinfo->name, hfinfo->abbrev,
8387                                                         ftype_name(hfinfo->type));
8388                                         break;
8389                                 default:
8390                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8391                                         ws_error("Field '%s' (%s) is a character value (%s)"
8392                                                 " but is being displayed as %s\n",
8393                                                 hfinfo->name, hfinfo->abbrev,
8394                                                 ftype_name(hfinfo->type), tmp_str);
8395                                         wmem_free(NULL, tmp_str);
8396                         }
8397                         if (hfinfo->display & BASE_UNIT_STRING) {
8398                                 ws_error("Field '%s' (%s) is a character value (%s) but has a unit string\n",
8399                                         hfinfo->name, hfinfo->abbrev,
8400                                         ftype_name(hfinfo->type));
8401                         }
8402                         break;
8403                 case FT_INT8:
8404                 case FT_INT16:
8405                 case FT_INT24:
8406                 case FT_INT32:
8407                 case FT_INT40:
8408                 case FT_INT48:
8409                 case FT_INT56:
8410                 case FT_INT64:
8411                         /*      Hexadecimal and octal are, in printf() and everywhere
8412                          *      else, unsigned so don't allow dissectors to register a
8413                          *      signed field to be displayed unsigned.  (Else how would
8414                          *      we display negative values?)
8415                          */
8416                         switch (FIELD_DISPLAY(hfinfo->display)) {
8417                                 case BASE_HEX:
8418                                 case BASE_OCT:
8419                                 case BASE_DEC_HEX:
8420                                 case BASE_HEX_DEC:
8421                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8422                                         ws_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
8423                                                 hfinfo->name, hfinfo->abbrev,
8424                                                 ftype_name(hfinfo->type), tmp_str);
8425                                         wmem_free(NULL, tmp_str);
8426                         }
8427                         /* FALL THROUGH */
8428                 case FT_UINT8:
8429                 case FT_UINT16:
8430                 case FT_UINT24:
8431                 case FT_UINT32:
8432                 case FT_UINT40:
8433                 case FT_UINT48:
8434                 case FT_UINT56:
8435                 case FT_UINT64:
8436                         if (IS_BASE_PORT(hfinfo->display)) {
8437                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8438                                 if (hfinfo->type != FT_UINT16) {
8439                                         ws_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
8440                                                 hfinfo->name, hfinfo->abbrev,
8441                                                 tmp_str, ftype_name(hfinfo->type));
8442                                 }
8443                                 if (hfinfo->strings != NULL) {
8444                                         ws_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
8445                                                 hfinfo->name, hfinfo->abbrev,
8446                                                 ftype_name(hfinfo->type), tmp_str);
8447                                 }
8448                                 if (hfinfo->bitmask != 0) {
8449                                         ws_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
8450                                                 hfinfo->name, hfinfo->abbrev,
8451                                                 ftype_name(hfinfo->type), tmp_str);
8452                                 }
8453                                 wmem_free(NULL, tmp_str);
8454                                 break;
8455                         }
8456
8457                         if (hfinfo->display == BASE_OUI) {
8458                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8459                                 if (hfinfo->type != FT_UINT24) {
8460                                         ws_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s\n",
8461                                                 hfinfo->name, hfinfo->abbrev,
8462                                                 tmp_str, ftype_name(hfinfo->type));
8463                                 }
8464                                 if (hfinfo->strings != NULL) {
8465                                         ws_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
8466                                                 hfinfo->name, hfinfo->abbrev,
8467                                                 ftype_name(hfinfo->type), tmp_str);
8468                                 }
8469                                 if (hfinfo->bitmask != 0) {
8470                                         ws_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
8471                                                 hfinfo->name, hfinfo->abbrev,
8472                                                 ftype_name(hfinfo->type), tmp_str);
8473                                 }
8474                                 wmem_free(NULL, tmp_str);
8475                                 break;
8476                         }
8477
8478                         /*  Require integral types (other than frame number,
8479                          *  which is always displayed in decimal) to have a
8480                          *  number base.
8481                          *
8482                          *  If the display value is BASE_NONE and there is a
8483                          *  strings conversion then the dissector writer is
8484                          *  telling us that the field's numerical value is
8485                          *  meaningless; we'll avoid showing the value to the
8486                          *  user.
8487                          */
8488                         switch (FIELD_DISPLAY(hfinfo->display)) {
8489                                 case BASE_DEC:
8490                                 case BASE_HEX:
8491                                 case BASE_OCT:
8492                                 case BASE_DEC_HEX:
8493                                 case BASE_HEX_DEC:
8494                                 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
8495                                         break;
8496                                 case BASE_NONE:
8497                                         if (hfinfo->strings == NULL) {
8498                                                 ws_error("Field '%s' (%s) is an integral value (%s)"
8499                                                         " but is being displayed as BASE_NONE but"
8500                                                         " without a strings conversion",
8501                                                         hfinfo->name, hfinfo->abbrev,
8502                                                         ftype_name(hfinfo->type));
8503                                         }
8504                                         if (hfinfo->display & BASE_SPECIAL_VALS) {
8505                                                 ws_error("Field '%s' (%s) is an integral value (%s)"
8506                                                         " that is being displayed as BASE_NONE but"
8507                                                         " with BASE_SPECIAL_VALS",
8508                                                         hfinfo->name, hfinfo->abbrev,
8509                                                         ftype_name(hfinfo->type));
8510                                         }
8511                                         break;
8512
8513                                 default:
8514                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8515                                         ws_error("Field '%s' (%s) is an integral value (%s)"
8516                                                 " but is being displayed as %s\n",
8517                                                 hfinfo->name, hfinfo->abbrev,
8518                                                 ftype_name(hfinfo->type), tmp_str);
8519                                         wmem_free(NULL, tmp_str);
8520                         }
8521                         break;
8522                 case FT_BYTES:
8523                 case FT_UINT_BYTES:
8524                         /*  Require bytes to have a "display type" that could
8525                          *  add a character between displayed bytes.
8526                          */
8527                         switch (FIELD_DISPLAY(hfinfo->display)) {
8528                                 case BASE_NONE:
8529                                 case SEP_DOT:
8530                                 case SEP_DASH:
8531                                 case SEP_COLON:
8532                                 case SEP_SPACE:
8533                                         break;
8534                                 default:
8535                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8536                                         ws_error("Field '%s' (%s) is an byte array but is being displayed as %s instead of BASE_NONE, SEP_DOT, SEP_DASH, SEP_COLON, or SEP_SPACE\n",
8537                                                 hfinfo->name, hfinfo->abbrev, tmp_str);
8538                                         wmem_free(NULL, tmp_str);
8539                         }
8540                         if (hfinfo->bitmask != 0)
8541                                 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8542                                         hfinfo->name, hfinfo->abbrev,
8543                                         ftype_name(hfinfo->type));
8544                         //allowed to support string if its a protocol (for pinos)
8545                         if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_PROTOCOL_INFO)))
8546                                 ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8547                                         hfinfo->name, hfinfo->abbrev,
8548                                         ftype_name(hfinfo->type));
8549                         break;
8550
8551                 case FT_PROTOCOL:
8552                 case FT_FRAMENUM:
8553                         if (hfinfo->display != BASE_NONE) {
8554                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8555                                 ws_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
8556                                         hfinfo->name, hfinfo->abbrev,
8557                                         ftype_name(hfinfo->type), tmp_str);
8558                                 wmem_free(NULL, tmp_str);
8559                         }
8560                         if (hfinfo->bitmask != 0)
8561                                 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8562                                         hfinfo->name, hfinfo->abbrev,
8563                                         ftype_name(hfinfo->type));
8564                         break;
8565
8566                 case FT_BOOLEAN:
8567                         break;
8568
8569                 case FT_ABSOLUTE_TIME:
8570                         if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
8571                               hfinfo->display == ABSOLUTE_TIME_UTC   ||
8572                               hfinfo->display == ABSOLUTE_TIME_NTP_UTC   ||
8573                               hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
8574                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8575                                 ws_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
8576                                         hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
8577                                 wmem_free(NULL, tmp_str);
8578                         }
8579                         if (hfinfo->bitmask != 0)
8580                                 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8581                                         hfinfo->name, hfinfo->abbrev,
8582                                         ftype_name(hfinfo->type));
8583                         break;
8584
8585                 case FT_STRING:
8586                 case FT_STRINGZ:
8587                 case FT_UINT_STRING:
8588                 case FT_STRINGZPAD:
8589                 case FT_STRINGZTRUNC:
8590                         switch (hfinfo->display) {
8591                                 case STR_ASCII:
8592                                 case STR_UNICODE:
8593                                         break;
8594
8595                                 default:
8596                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8597                                         ws_error("Field '%s' (%s) is an string value (%s)"
8598                                                 " but is being displayed as %s\n",
8599                                                 hfinfo->name, hfinfo->abbrev,
8600                                                 ftype_name(hfinfo->type), tmp_str);
8601                                         wmem_free(NULL, tmp_str);
8602                         }
8603
8604                         if (hfinfo->bitmask != 0)
8605                                 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8606                                         hfinfo->name, hfinfo->abbrev,
8607                                         ftype_name(hfinfo->type));
8608                         if (hfinfo->strings != NULL)
8609                                 ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8610                                         hfinfo->name, hfinfo->abbrev,
8611                                         ftype_name(hfinfo->type));
8612                         break;
8613
8614                 case FT_IPv4:
8615                         switch (hfinfo->display) {
8616                                 case BASE_NONE:
8617                                 case BASE_NETMASK:
8618                                         break;
8619
8620                                 default:
8621                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8622                                         ws_error("Field '%s' (%s) is an IPv4 value (%s)"
8623                                                 " but is being displayed as %s\n",
8624                                                 hfinfo->name, hfinfo->abbrev,
8625                                                 ftype_name(hfinfo->type), tmp_str);
8626                                         wmem_free(NULL, tmp_str);
8627                                         break;
8628                         }
8629                         break;
8630                 case FT_FLOAT:
8631                 case FT_DOUBLE:
8632                         if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
8633                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8634                                 ws_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
8635                                         hfinfo->name, hfinfo->abbrev,
8636                                         ftype_name(hfinfo->type),
8637                                         tmp_str);
8638                                 wmem_free(NULL, tmp_str);
8639                         }
8640                         if (hfinfo->bitmask != 0)
8641                                 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8642                                         hfinfo->name, hfinfo->abbrev,
8643                                         ftype_name(hfinfo->type));
8644                         if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_UNIT_STRING)))
8645                                 ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8646                                         hfinfo->name, hfinfo->abbrev,
8647                                         ftype_name(hfinfo->type));
8648                         break;
8649                 default:
8650                         if (hfinfo->display != BASE_NONE) {
8651                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8652                                 ws_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
8653                                         hfinfo->name, hfinfo->abbrev,
8654                                         ftype_name(hfinfo->type),
8655                                         tmp_str);
8656                                 wmem_free(NULL, tmp_str);
8657                         }
8658                         if (hfinfo->bitmask != 0)
8659                                 ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8660                                         hfinfo->name, hfinfo->abbrev,
8661                                         ftype_name(hfinfo->type));
8662                         if (hfinfo->strings != NULL)
8663                                 ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8664                                         hfinfo->name, hfinfo->abbrev,
8665                                         ftype_name(hfinfo->type));
8666                         break;
8667         }
8668 }
8669
8670 #ifdef ENABLE_CHECK_FILTER
8671 static enum ftenum
8672 _ftype_common(enum ftenum type)
8673 {
8674         switch (type) {
8675                 case FT_INT8:
8676                 case FT_INT16:
8677                 case FT_INT24:
8678                 case FT_INT32:
8679                         return FT_INT32;
8680
8681                 case FT_CHAR:
8682                 case FT_UINT8:
8683                 case FT_UINT16:
8684                 case FT_UINT24:
8685                 case FT_UINT32:
8686                 case FT_IPXNET:
8687                 case FT_FRAMENUM:
8688                         return FT_UINT32;
8689
8690                 case FT_UINT64:
8691                 case FT_EUI64:
8692                         return FT_UINT64;
8693
8694                 case FT_STRING:
8695                 case FT_STRINGZ:
8696                 case FT_UINT_STRING:
8697                         return FT_STRING;
8698
8699                 case FT_FLOAT:
8700                 case FT_DOUBLE:
8701                         return FT_DOUBLE;
8702
8703                 case FT_BYTES:
8704                 case FT_UINT_BYTES:
8705                 case FT_ETHER:
8706                 case FT_OID:
8707                         return FT_BYTES;
8708
8709                 case FT_ABSOLUTE_TIME:
8710                 case FT_RELATIVE_TIME:
8711                         return FT_ABSOLUTE_TIME;
8712
8713                 default:
8714                         return type;
8715         }
8716 }
8717 #endif
8718
8719 static void
8720 register_type_length_mismatch(void)
8721 {
8722         static ei_register_info ei[] = {
8723                 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
8724                 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
8725         };
8726
8727         expert_module_t* expert_type_length_mismatch;
8728
8729         proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
8730
8731         expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
8732         expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
8733
8734         /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
8735            disabling them makes no sense. */
8736         proto_set_cant_toggle(proto_type_length_mismatch);
8737 }
8738
8739 static void
8740 register_number_string_decodinws_error(void)
8741 {
8742         static ei_register_info ei[] = {
8743                 { &ei_number_string_decoding_failed_error,
8744                         { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
8745                           "Failed to decode number from string", EXPFILL
8746                         }
8747                 },
8748                 { &ei_number_string_decoding_erange_error,
8749                         { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
8750                           "Decoded number from string is out of valid range", EXPFILL
8751                         }
8752                 },
8753         };
8754
8755         expert_module_t* expert_number_string_decoding_error;
8756
8757         proto_number_string_decoding_error =
8758                 proto_register_protocol("Number-String Decoding Error",
8759                                         "Number-string decoding error",
8760                                         "_ws.number_string.decoding_error");
8761
8762         expert_number_string_decoding_error =
8763                 expert_register_protocol(proto_number_string_decoding_error);
8764         expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
8765
8766         /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
8767            disabling them makes no sense. */
8768         proto_set_cant_toggle(proto_number_string_decoding_error);
8769 }
8770
8771 static void
8772 register_string_errors(void)
8773 {
8774         static ei_register_info ei[] = {
8775                 { &ei_string_trailing_characters,
8776                         { "_ws.string.trailing_stray_characters", PI_UNDECODED, PI_WARN, "Trailing stray characters", EXPFILL }
8777                 },
8778         };
8779
8780         expert_module_t* expert_string_errors;
8781
8782         proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
8783
8784         expert_string_errors = expert_register_protocol(proto_string_errors);
8785         expert_register_field_array(expert_string_errors, ei, array_length(ei));
8786
8787         /* "String Errors" isn't really a protocol, it's an error indication;
8788            disabling them makes no sense. */
8789         proto_set_cant_toggle(proto_string_errors);
8790 }
8791
8792 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (235000+PRE_ALLOC_EXPERT_FIELDS_MEM)
8793 static int
8794 proto_register_field_init(header_field_info *hfinfo, const int parent)
8795 {
8796
8797         tmp_fld_check_assert(hfinfo);
8798
8799         hfinfo->parent         = parent;
8800         hfinfo->same_name_next = NULL;
8801         hfinfo->same_name_prev_id = -1;
8802
8803         /* if we always add and never delete, then id == len - 1 is correct */
8804         if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
8805                 if (!gpa_hfinfo.hfi) {
8806                         gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
8807                         gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8808                 } else {
8809                         gpa_hfinfo.allocated_len += 1000;
8810                         gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
8811                                                    sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
8812                         /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
8813                 }
8814         }
8815         gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
8816         gpa_hfinfo.len++;
8817         hfinfo->id = gpa_hfinfo.len - 1;
8818
8819         /* if we have real names, enter this field in the name tree */
8820         if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
8821
8822                 header_field_info *same_name_next_hfinfo;
8823                 guchar c;
8824
8825                 /* Check that the filter name (abbreviation) is legal;
8826                  * it must contain only alphanumerics, '-', "_", and ".". */
8827                 c = proto_check_field_name(hfinfo->abbrev);
8828                 if (c) {
8829                         if (c == '.') {
8830                                 fprintf(stderr, "Invalid leading, duplicated or trailing '.' found in filter name '%s'\n", hfinfo->abbrev);
8831                         } else if (g_ascii_isprint(c)) {
8832                                 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
8833                         } else {
8834                                 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
8835                         }
8836                         DISSECTOR_ASSERT_NOT_REACHED();
8837                 }
8838
8839                 /* We allow multiple hfinfo's to be registered under the same
8840                  * abbreviation. This was done for X.25, as, depending
8841                  * on whether it's modulo-8 or modulo-128 operation,
8842                  * some bitfield fields may be in different bits of
8843                  * a byte, and we want to be able to refer to that field
8844                  * with one name regardless of whether the packets
8845                  * are modulo-8 or modulo-128 packets. */
8846
8847                 same_name_hfinfo = NULL;
8848
8849                 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
8850                 /* GLIB 2.x - if it is already present
8851                  * the previous hfinfo with the same name is saved
8852                  * to same_name_hfinfo by value destroy callback */
8853                 if (same_name_hfinfo) {
8854                         /* There's already a field with this name.
8855                          * Put the current field *before* that field
8856                          * in the list of fields with this name, Thus,
8857                          * we end up with an effectively
8858                          * doubly-linked-list of same-named hfinfo's,
8859                          * with the head of the list (stored in the
8860                          * hash) being the last seen hfinfo.
8861                          */
8862                         same_name_next_hfinfo =
8863                                 same_name_hfinfo->same_name_next;
8864
8865                         hfinfo->same_name_next = same_name_next_hfinfo;
8866                         if (same_name_next_hfinfo)
8867                                 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
8868
8869                         same_name_hfinfo->same_name_next = hfinfo;
8870                         hfinfo->same_name_prev_id = same_name_hfinfo->id;
8871 #ifdef ENABLE_CHECK_FILTER
8872                         while (same_name_hfinfo) {
8873                                 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
8874                                         ws_warning("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type));
8875                                 same_name_hfinfo = same_name_hfinfo->same_name_next;
8876                         }
8877 #endif
8878                 }
8879         }
8880
8881         return hfinfo->id;
8882 }
8883
8884 void
8885 proto_register_subtree_array(gint * const *indices, const int num_indices)
8886 {
8887         int     i;
8888         gint    *const *ptr = indices;
8889
8890         /*
8891          * If we've already allocated the array of tree types, expand
8892          * it; this lets plugins such as mate add tree types after
8893          * the initial startup.  (If we haven't already allocated it,
8894          * we don't allocate it; on the first pass, we just assign
8895          * ett values and keep track of how many we've assigned, and
8896          * when we're finished registering all dissectors we allocate
8897          * the array, so that we do only one allocation rather than
8898          * wasting CPU time and memory by growing the array for each
8899          * dissector that registers ett values.)
8900          */
8901         if (tree_is_expanded != NULL) {
8902                 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
8903
8904                 /* set new items to 0 */
8905                 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
8906                 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
8907                         tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
8908         }
8909
8910         /*
8911          * Assign "num_indices" subtree numbers starting at "num_tree_types",
8912          * returning the indices through the pointers in the array whose
8913          * first element is pointed to by "indices", and update
8914          * "num_tree_types" appropriately.
8915          */
8916         for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
8917                 if (**ptr != -1) {
8918                         /* g_error will terminate the program */
8919                         ws_error("register_subtree_array: subtree item type (ett_...) not -1 !"
8920                                 " This is a development error:"
8921                                 " Either the subtree item type has already been assigned or"
8922                                 " was not initialized to -1.");
8923                 }
8924                 **ptr = num_tree_types;
8925         }
8926 }
8927
8928 static inline gsize
8929 label_concat(char *label_str, gsize pos, const char *str)
8930 {
8931         if (pos < ITEM_LABEL_LENGTH)
8932                 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
8933
8934         return pos;
8935 }
8936
8937 static void
8938 label_mark_truncated(char *label_str, gsize name_pos)
8939 {
8940         static const char  trunc_str[] = " [truncated]";
8941         const size_t       trunc_len = sizeof(trunc_str)-1;
8942         gchar             *last_char;
8943
8944         /* ..... field_name: dataaaaaaaaaaaaa
8945          *                 |
8946          *                 ^^^^^ name_pos
8947          *
8948          * ..... field_name [truncated]: dataaaaaaaaaaaaa
8949          *
8950          * name_pos==0 means that we have only data or only a field_name
8951          */
8952
8953         if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
8954                 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
8955                 memcpy(label_str + name_pos, trunc_str, trunc_len);
8956
8957                 /* in general, label_str is UTF-8
8958                    we can truncate it only at the beginning of a new character
8959                    we go backwards from the byte right after our buffer and
8960                     find the next starting byte of a UTF-8 character, this is
8961                     where we cut
8962                    there's no need to use g_utf8_find_prev_char(), the search
8963                     will always succeed since we copied trunc_str into the
8964                     buffer */
8965                 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH - 1]);
8966                 *last_char = '\0';
8967
8968         } else if (name_pos < ITEM_LABEL_LENGTH)
8969                 (void) g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
8970 }
8971
8972 static gsize
8973 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
8974 {
8975         gsize name_pos;
8976
8977         /* "%s: %s", hfinfo->name, text */
8978         name_pos = pos = label_concat(label_str, pos, hfinfo->name);
8979         if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
8980                 pos = label_concat(label_str, pos, ": ");
8981                 pos = label_concat(label_str, pos, text ? text : "(null)");
8982         }
8983
8984         if (pos >= ITEM_LABEL_LENGTH) {
8985                 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8986                 label_mark_truncated(label_str, name_pos);
8987         }
8988
8989         return pos;
8990 }
8991
8992 static gsize
8993 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
8994 {
8995         gsize name_pos;
8996
8997         /* "%s: %s (%s)", hfinfo->name, text, descr */
8998         name_pos = pos = label_concat(label_str, pos, hfinfo->name);
8999         if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
9000                 pos = label_concat(label_str, pos, ": ");
9001                 if (hfinfo->display & BASE_UNIT_STRING) {
9002                         pos = label_concat(label_str, pos, descr ? descr : "(null)");
9003                         pos = label_concat(label_str, pos, text ? text : "(null)");
9004                 } else {
9005                         pos = label_concat(label_str, pos, text ? text : "(null)");
9006                         pos = label_concat(label_str, pos, " (");
9007                         pos = label_concat(label_str, pos, descr ? descr : "(null)");
9008                         pos = label_concat(label_str, pos, ")");
9009                 }
9010         }
9011
9012         if (pos >= ITEM_LABEL_LENGTH) {
9013                 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9014                 label_mark_truncated(label_str, name_pos);
9015         }
9016
9017         return pos;
9018 }
9019
9020 void
9021 proto_item_fill_label(field_info *fi, gchar *label_str)
9022 {
9023         header_field_info  *hfinfo;
9024         guint8             *bytes;
9025         guint32             integer;
9026         guint64             integer64;
9027         ws_in4_addr         ipv4;
9028         e_guid_t           *guid;
9029         gchar              *name;
9030         address             addr;
9031         char               *addr_str;
9032         char               *tmp;
9033
9034         if (!fi) {
9035                 if (label_str)
9036                         label_str[0]= '\0';
9037                 /* XXX: Check validity of hfinfo->type */
9038                 return;
9039         }
9040
9041         hfinfo = fi->hfinfo;
9042
9043         switch (hfinfo->type) {
9044                 case FT_NONE:
9045                 case FT_PROTOCOL:
9046                         (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
9047                         break;
9048
9049                 case FT_BOOLEAN:
9050                         fill_label_boolean(fi, label_str);
9051                         break;
9052
9053                 case FT_BYTES:
9054                 case FT_UINT_BYTES:
9055                         tmp = hfinfo_format_bytes(NULL, hfinfo,
9056                             (guint8 *)fvalue_get(&fi->value),
9057                             fvalue_length(&fi->value));
9058                         label_fill(label_str, 0, hfinfo, tmp);
9059                         wmem_free(NULL, tmp);
9060                         break;
9061
9062                 case FT_CHAR:
9063                         if (hfinfo->bitmask) {
9064                                 fill_label_bitfield_char(fi, label_str);
9065                         } else {
9066                                 fill_label_char(fi, label_str);
9067                         }
9068                         break;
9069
9070                 /* Four types of integers to take care of:
9071                  *      Bitfield, with val_string
9072                  *      Bitfield, w/o val_string
9073                  *      Non-bitfield, with val_string
9074                  *      Non-bitfield, w/o val_string
9075                  */
9076                 case FT_UINT8:
9077                 case FT_UINT16:
9078                 case FT_UINT24:
9079                 case FT_UINT32:
9080                         if (hfinfo->bitmask) {
9081                                 if (fi->flags & FI_VARINT) {
9082                                         fill_label_bitfield_varint(fi, label_str, FALSE);
9083                                 } else {
9084                                         fill_label_bitfield(fi, label_str, FALSE);
9085                                 }
9086                         } else {
9087                                 fill_label_number(fi, label_str, FALSE);
9088                         }
9089                         break;
9090
9091                 case FT_FRAMENUM:
9092                         fill_label_number(fi, label_str, FALSE);
9093                         break;
9094
9095                 case FT_UINT40:
9096                 case FT_UINT48:
9097                 case FT_UINT56:
9098                 case FT_UINT64:
9099                         if (hfinfo->bitmask) {
9100                                 if (fi->flags & FI_VARINT) {
9101                                         fill_label_bitfield_varint64(fi, label_str, FALSE);
9102                                 } else {
9103                                         fill_label_bitfield64(fi, label_str, FALSE);
9104                                 }
9105                         } else {
9106                                 fill_label_number64(fi, label_str, FALSE);
9107                         }
9108                         break;
9109
9110                 case FT_INT8:
9111                 case FT_INT16:
9112                 case FT_INT24:
9113                 case FT_INT32:
9114                         if (hfinfo->bitmask) {
9115                                 if (fi->flags & FI_VARINT) {
9116                                         fill_label_bitfield_varint(fi, label_str, TRUE);
9117                                 } else {
9118                                         fill_label_bitfield(fi, label_str, TRUE);
9119                                 }
9120                         } else {
9121                                 fill_label_number(fi, label_str, TRUE);
9122                         }
9123                         break;
9124
9125                 case FT_INT40:
9126                 case FT_INT48:
9127                 case FT_INT56:
9128                 case FT_INT64:
9129                         if (hfinfo->bitmask) {
9130                                 if (fi->flags & FI_VARINT) {
9131                                         fill_label_bitfield_varint64(fi, label_str, TRUE);
9132                                 } else {
9133                                         fill_label_bitfield64(fi, label_str, TRUE);
9134                                 }
9135                         } else {
9136                                 fill_label_number64(fi, label_str, TRUE);
9137                         }
9138                         break;
9139
9140                 case FT_FLOAT:
9141                 {
9142                         double d_value = fvalue_get_floating(&fi->value);
9143                         if (hfinfo->display & BASE_UNIT_STRING) {
9144                                 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9145                                            "%s: %." G_STRINGIFY(FLT_DIG) "g%s",
9146                                            hfinfo->name, d_value,
9147                                            unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
9148                         } else {
9149                                 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9150                                            "%s: %." G_STRINGIFY(FLT_DIG) "g",
9151                                            hfinfo->name, d_value);
9152                         }
9153                         break;
9154                 }
9155
9156                 case FT_DOUBLE:
9157                 {
9158                         double d_value = fvalue_get_floating(&fi->value);
9159                         if (hfinfo->display & BASE_UNIT_STRING) {
9160                                 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9161                                            "%s: %." G_STRINGIFY(DBL_DIG) "g%s",
9162                                            hfinfo->name, d_value,
9163                                            unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
9164                         } else {
9165                                 g_snprintf(label_str, ITEM_LABEL_LENGTH,
9166                                            "%s: %." G_STRINGIFY(DBL_DIG) "g",
9167                                            hfinfo->name, d_value);
9168                         }
9169                         break;
9170                 }
9171
9172                 case FT_ABSOLUTE_TIME:
9173                         tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
9174                         label_fill(label_str, 0, hfinfo, tmp);
9175                         wmem_free(NULL, tmp);
9176                         break;
9177
9178                 case FT_RELATIVE_TIME:
9179                         tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
9180                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
9181                                    "%s: %s seconds", hfinfo->name, tmp);
9182                         wmem_free(NULL, tmp);
9183                         break;
9184
9185                 case FT_IPXNET:
9186                         integer = fvalue_get_uinteger(&fi->value);
9187                         tmp = get_ipxnet_name(NULL, integer);
9188                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
9189                                    "%s: %s (0x%08X)", hfinfo->name,
9190                                    tmp, integer);
9191                         wmem_free(NULL, tmp);
9192                         break;
9193
9194                 case FT_AX25:
9195                         addr.type = AT_AX25;
9196                         addr.len  = AX25_ADDR_LEN;
9197                         addr.data = (guint8 *)fvalue_get(&fi->value);
9198
9199                         addr_str = (char*)address_to_str(NULL, &addr);
9200                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
9201                                    "%s: %s", hfinfo->name, addr_str);
9202                         wmem_free(NULL, addr_str);
9203                         break;
9204
9205                 case FT_VINES:
9206                         addr.type = AT_VINES;
9207                         addr.len  = VINES_ADDR_LEN;
9208                         addr.data = (guint8 *)fvalue_get(&fi->value);
9209
9210                         addr_str = (char*)address_to_str(NULL, &addr);
9211                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
9212                                    "%s: %s", hfinfo->name, addr_str);
9213                         wmem_free(NULL, addr_str);
9214                         break;
9215
9216                 case FT_ETHER:
9217                         bytes = (guint8 *)fvalue_get(&fi->value);
9218
9219                         addr.type = AT_ETHER;
9220                         addr.len  = 6;
9221                         addr.data = bytes;
9222
9223                         addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9224                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
9225                                    "%s: %s", hfinfo->name, addr_str);
9226                         wmem_free(NULL, addr_str);
9227                         break;
9228
9229                 case FT_IPv4:
9230                         ipv4 = fvalue_get_uinteger(&fi->value);
9231
9232                         addr.type = AT_IPv4;
9233                         addr.len  = 4;
9234                         addr.data = &ipv4;
9235
9236                         if (hfinfo->display == BASE_NETMASK) {
9237                                 addr_str = (char*)address_to_str(NULL, &addr);
9238                         } else {
9239                                 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9240                         }
9241                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
9242                                    "%s: %s", hfinfo->name, addr_str);
9243                         wmem_free(NULL, addr_str);
9244                         break;
9245
9246                 case FT_IPv6:
9247                         bytes = (guint8 *)fvalue_get(&fi->value);
9248
9249                         addr.type = AT_IPv6;
9250                         addr.len  = 16;
9251                         addr.data = bytes;
9252
9253                         addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9254                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
9255                                    "%s: %s", hfinfo->name, addr_str);
9256                         wmem_free(NULL, addr_str);
9257                         break;
9258
9259                 case FT_FCWWN:
9260                         addr.type = AT_FCWWN;
9261                         addr.len  = FCWWN_ADDR_LEN;
9262                         addr.data = (guint8 *)fvalue_get(&fi->value);
9263
9264                         addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9265                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
9266                                    "%s: %s", hfinfo->name, addr_str);
9267                         wmem_free(NULL, addr_str);
9268                         break;
9269
9270                 case FT_GUID:
9271                         guid = (e_guid_t *)fvalue_get(&fi->value);
9272                         tmp = guid_to_str(NULL, guid);
9273                         label_fill(label_str, 0, hfinfo, tmp);
9274                         wmem_free(NULL, tmp);
9275                         break;
9276
9277                 case FT_OID:
9278                         bytes = (guint8 *)fvalue_get(&fi->value);
9279                         name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
9280                         tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
9281                         if (name) {
9282                                 label_fill_descr(label_str, 0, hfinfo, tmp, name);
9283                                 wmem_free(NULL, name);
9284                         } else {
9285                                 label_fill(label_str, 0, hfinfo, tmp);
9286                         }
9287                         wmem_free(NULL, tmp);
9288                         break;
9289
9290                 case FT_REL_OID:
9291                         bytes = (guint8 *)fvalue_get(&fi->value);
9292                         name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
9293                         tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
9294                         if (name) {
9295                                 label_fill_descr(label_str, 0, hfinfo, tmp, name);
9296                                 wmem_free(NULL, name);
9297                         } else {
9298                                 label_fill(label_str, 0, hfinfo, tmp);
9299                         }
9300                         wmem_free(NULL, tmp);
9301                         break;
9302
9303                 case FT_SYSTEM_ID:
9304                         bytes = (guint8 *)fvalue_get(&fi->value);
9305                         tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
9306                         label_fill(label_str, 0, hfinfo, tmp);
9307                         wmem_free(NULL, tmp);
9308                         break;
9309
9310                 case FT_EUI64:
9311                         integer64 = fvalue_get_uinteger64(&fi->value);
9312                         addr_str = eui64_to_str(NULL, integer64);
9313                         tmp = (char*)eui64_to_display(NULL, integer64);
9314                         label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
9315                         wmem_free(NULL, tmp);
9316                         wmem_free(NULL, addr_str);
9317                         break;
9318                 case FT_STRING:
9319                 case FT_STRINGZ:
9320                 case FT_UINT_STRING:
9321                 case FT_STRINGZPAD:
9322                 case FT_STRINGZTRUNC:
9323                         bytes = (guint8 *)fvalue_get(&fi->value);
9324                         tmp = hfinfo_format_text(NULL, hfinfo, bytes);
9325                         label_fill(label_str, 0, hfinfo, tmp);
9326                         wmem_free(NULL, tmp);
9327                         break;
9328
9329                 case FT_IEEE_11073_SFLOAT:
9330                 case FT_IEEE_11073_FLOAT:
9331                         tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
9332                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
9333                                                 "%s: %s",
9334                                                 hfinfo->name, tmp);
9335                         wmem_free(NULL, tmp);
9336                         break;
9337
9338                 default:
9339                         REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_fill_label()",
9340                                              hfinfo->abbrev,
9341                                              hfinfo->type,
9342                                              ftype_name(hfinfo->type));
9343                         break;
9344         }
9345 }
9346
9347 static void
9348 fill_label_boolean(field_info *fi, gchar *label_str)
9349 {
9350         char    *p                    = label_str;
9351         int      bitfield_byte_length = 0, bitwidth;
9352         guint64  unshifted_value;
9353         guint64  value;
9354
9355         header_field_info       *hfinfo   = fi->hfinfo;
9356         const true_false_string *tfstring = &tfs_true_false;
9357
9358         if (hfinfo->strings) {
9359                 tfstring = (const struct true_false_string*) hfinfo->strings;
9360         }
9361
9362         value = fvalue_get_uinteger64(&fi->value);
9363         if (hfinfo->bitmask) {
9364                 /* Figure out the bit width */
9365                 bitwidth = hfinfo_container_bitwidth(hfinfo);
9366
9367                 /* Un-shift bits */
9368                 unshifted_value = value;
9369                 unshifted_value <<= hfinfo_bitshift(hfinfo);
9370
9371                 /* Create the bitfield first */
9372                 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9373                 bitfield_byte_length = (int) (p - label_str);
9374         }
9375
9376         /* Fill in the textual info */
9377         label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, tfstring));
9378 }
9379
9380 static const char *
9381 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
9382 {
9383         if (hfinfo->display & BASE_RANGE_STRING)
9384                 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
9385
9386         if (hfinfo->display & BASE_EXT_STRING) {
9387                 if (hfinfo->display & BASE_VAL64_STRING)
9388                         return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
9389                 else
9390                         return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
9391         }
9392
9393         if (hfinfo->display & BASE_VAL64_STRING)
9394                 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
9395
9396         if (hfinfo->display & BASE_UNIT_STRING)
9397                 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
9398
9399         return try_val_to_str(value, (const value_string *) hfinfo->strings);
9400 }
9401
9402 static const char *
9403 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
9404 {
9405         if (hfinfo->display & BASE_VAL64_STRING) {
9406                 if (hfinfo->display & BASE_EXT_STRING)
9407                         return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
9408                 else
9409                         return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
9410         }
9411
9412         if (hfinfo->display & BASE_RANGE_STRING)
9413                 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
9414
9415         if (hfinfo->display & BASE_UNIT_STRING)
9416                 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
9417
9418         /* If this is reached somebody registered a 64-bit field with a 32-bit
9419          * value-string, which isn't right. */
9420         REPORT_DISSECTOR_BUG("field %s is a 64-bit field with a 32-bit value_string",
9421             hfinfo->abbrev);
9422
9423         /* This is necessary to squelch MSVC errors; is there
9424            any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
9425            never returns? */
9426         return NULL;
9427 }
9428
9429 static const char *
9430 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
9431 {
9432         const char *str = hf_try_val_to_str(value, hfinfo);
9433
9434         return (str) ? str : unknown_str;
9435 }
9436
9437 static const char *
9438 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
9439 {
9440         const char *str = hf_try_val64_to_str(value, hfinfo);
9441
9442         return (str) ? str : unknown_str;
9443 }
9444
9445 /* Fills data for bitfield chars with val_strings */
9446 static void
9447 fill_label_bitfield_char(field_info *fi, gchar *label_str)
9448 {
9449         char       *p;
9450         int         bitfield_byte_length, bitwidth;
9451         guint32     unshifted_value;
9452         guint32     value;
9453
9454         char        buf[32];
9455         const char *out;
9456
9457         header_field_info *hfinfo = fi->hfinfo;
9458
9459         /* Figure out the bit width */
9460         bitwidth = hfinfo_container_bitwidth(hfinfo);
9461
9462         /* Un-shift bits */
9463         value = fvalue_get_uinteger(&fi->value);
9464
9465         unshifted_value = value;
9466         if (hfinfo->bitmask) {
9467                 unshifted_value <<= hfinfo_bitshift(hfinfo);
9468         }
9469
9470         /* Create the bitfield first */
9471         p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9472         bitfield_byte_length = (int) (p - label_str);
9473
9474         /* Fill in the textual info using stored (shifted) value */
9475         if (hfinfo->display == BASE_CUSTOM) {
9476                 gchar tmp[ITEM_LABEL_LENGTH];
9477                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9478
9479                 DISSECTOR_ASSERT(fmtfunc);
9480                 fmtfunc(tmp, value);
9481                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9482         }
9483         else if (hfinfo->strings) {
9484                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9485
9486                 out = hfinfo_char_vals_format(hfinfo, buf, value);
9487                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9488                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9489                 else
9490                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9491         }
9492         else {
9493                 out = hfinfo_char_value_format(hfinfo, buf, value);
9494
9495                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9496         }
9497 }
9498
9499 /* Fills data for bitfield ints with val_strings */
9500 static void
9501 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
9502 {
9503         char       *p;
9504         int         bitfield_byte_length, bitwidth;
9505         guint32     unshifted_value;
9506         guint32     value;
9507
9508         char        buf[32];
9509         const char *out;
9510
9511         header_field_info *hfinfo = fi->hfinfo;
9512
9513         /* Figure out the bit width */
9514         bitwidth = hfinfo_container_bitwidth(hfinfo);
9515
9516         /* Un-shift bits */
9517         if (is_signed)
9518                 value = fvalue_get_sinteger(&fi->value);
9519         else
9520                 value = fvalue_get_uinteger(&fi->value);
9521
9522         unshifted_value = value;
9523         if (hfinfo->bitmask) {
9524                 unshifted_value <<= hfinfo_bitshift(hfinfo);
9525         }
9526
9527         /* Create the bitfield first */
9528         p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9529         bitfield_byte_length = (int) (p - label_str);
9530
9531         /* Fill in the textual info using stored (shifted) value */
9532         if (hfinfo->display == BASE_CUSTOM) {
9533                 gchar tmp[ITEM_LABEL_LENGTH];
9534                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9535
9536                 DISSECTOR_ASSERT(fmtfunc);
9537                 fmtfunc(tmp, value);
9538                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9539         }
9540         else if (hfinfo->strings) {
9541                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9542
9543                 out = hfinfo_number_vals_format(hfinfo, buf, value);
9544                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9545                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9546                 else
9547                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9548         }
9549         else {
9550                 out = hfinfo_number_value_format(hfinfo, buf, value);
9551
9552                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9553         }
9554 }
9555
9556 static void
9557 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
9558 {
9559         char       *p;
9560         int         bitfield_byte_length, bitwidth;
9561         guint64     unshifted_value;
9562         guint64     value;
9563
9564         char        buf[48];
9565         const char *out;
9566
9567         header_field_info *hfinfo = fi->hfinfo;
9568
9569         /* Figure out the bit width */
9570         bitwidth = hfinfo_container_bitwidth(hfinfo);
9571
9572         /* Un-shift bits */
9573         if (is_signed)
9574                 value = fvalue_get_sinteger64(&fi->value);
9575         else
9576                 value = fvalue_get_uinteger64(&fi->value);
9577
9578         unshifted_value = value;
9579         if (hfinfo->bitmask) {
9580                 unshifted_value <<= hfinfo_bitshift(hfinfo);
9581         }
9582
9583         /* Create the bitfield first */
9584         p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9585         bitfield_byte_length = (int) (p - label_str);
9586
9587         /* Fill in the textual info using stored (shifted) value */
9588         if (hfinfo->display == BASE_CUSTOM) {
9589                 gchar tmp[ITEM_LABEL_LENGTH];
9590                 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9591
9592                 DISSECTOR_ASSERT(fmtfunc64);
9593                 fmtfunc64(tmp, value);
9594                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9595         }
9596         else if (hfinfo->strings) {
9597                 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
9598
9599                 out = hfinfo_number_vals_format64(hfinfo, buf, value);
9600                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9601                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9602                 else
9603                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9604         }
9605         else {
9606                 out = hfinfo_number_value_format64(hfinfo, buf, value);
9607
9608                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9609         }
9610 }
9611
9612 static void
9613 fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed)
9614 {
9615         char       *p;
9616         int         bitfield_byte_length;
9617         guint32     value, unshifted_value;
9618         char        buf[48];
9619         const char *out;
9620
9621         header_field_info *hfinfo = fi->hfinfo;
9622
9623         /* Un-shift bits */
9624         if (is_signed) {
9625                 value = fvalue_get_sinteger(&fi->value);
9626         } else {
9627                 value = fvalue_get_uinteger(&fi->value);
9628         }
9629         unshifted_value = value;
9630         if (hfinfo->bitmask) {
9631                 unshifted_value <<= hfinfo_bitshift(hfinfo);
9632         }
9633
9634         /* Create the bitfield first */
9635         p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
9636         bitfield_byte_length = (int) (p - label_str);
9637
9638         /* Fill in the textual info using stored (shifted) value */
9639         if (hfinfo->display == BASE_CUSTOM) {
9640                 gchar tmp[ITEM_LABEL_LENGTH];
9641                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9642
9643                 DISSECTOR_ASSERT(fmtfunc);
9644                 fmtfunc(tmp, value);
9645                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9646         }
9647         else if (hfinfo->strings) {
9648                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9649
9650                 out = hfinfo_number_vals_format(hfinfo, buf, value);
9651                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9652                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9653                 else
9654                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9655         }
9656         else {
9657                 out = hfinfo_number_value_format(hfinfo, buf, value);
9658
9659                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9660         }
9661 }
9662
9663 static void
9664 fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed)
9665 {
9666         char       *p;
9667         int         bitfield_byte_length;
9668         guint64     unshifted_value;
9669         guint64     value;
9670
9671         char        buf[48];
9672         const char *out;
9673
9674         header_field_info *hfinfo = fi->hfinfo;
9675
9676         /* Un-shift bits */
9677         if (is_signed) {
9678                 value = fvalue_get_sinteger64(&fi->value);
9679         } else {
9680                 value = fvalue_get_uinteger64(&fi->value);
9681         }
9682         unshifted_value = value;
9683         if (hfinfo->bitmask) {
9684                 unshifted_value <<= hfinfo_bitshift(hfinfo);
9685         }
9686
9687         /* Create the bitfield first */
9688         p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
9689         bitfield_byte_length = (int) (p - label_str);
9690
9691         /* Fill in the textual info using stored (shifted) value */
9692         if (hfinfo->display == BASE_CUSTOM) {
9693                 gchar tmp[ITEM_LABEL_LENGTH];
9694                 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9695
9696                 DISSECTOR_ASSERT(fmtfunc64);
9697                 fmtfunc64(tmp, value);
9698                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9699         }
9700         else if (hfinfo->strings) {
9701                 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
9702
9703                 out = hfinfo_number_vals_format64(hfinfo, buf, value);
9704                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9705                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9706                 else
9707                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9708         }
9709         else {
9710                 out = hfinfo_number_value_format64(hfinfo, buf, value);
9711
9712                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9713         }
9714 }
9715
9716 static void
9717 fill_label_char(field_info *fi, gchar *label_str)
9718 {
9719         header_field_info *hfinfo = fi->hfinfo;
9720         guint32            value;
9721
9722         char               buf[32];
9723         const char        *out;
9724
9725         value = fvalue_get_uinteger(&fi->value);
9726
9727         /* Fill in the textual info */
9728         if (hfinfo->display == BASE_CUSTOM) {
9729                 gchar tmp[ITEM_LABEL_LENGTH];
9730                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9731
9732                 DISSECTOR_ASSERT(fmtfunc);
9733                 fmtfunc(tmp, value);
9734                 label_fill(label_str, 0, hfinfo, tmp);
9735         }
9736         else if (hfinfo->strings) {
9737                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9738
9739                 out = hfinfo_char_vals_format(hfinfo, buf, value);
9740                 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9741         }
9742         else {
9743                 out = hfinfo_char_value_format(hfinfo, buf, value);
9744
9745                 label_fill(label_str, 0, hfinfo, out);
9746         }
9747 }
9748
9749 static void
9750 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
9751 {
9752         header_field_info *hfinfo = fi->hfinfo;
9753         guint32            value;
9754
9755         char               buf[32];
9756         const char        *out;
9757
9758         if (is_signed)
9759                 value = fvalue_get_sinteger(&fi->value);
9760         else
9761                 value = fvalue_get_uinteger(&fi->value);
9762
9763         /* Fill in the textual info */
9764         if (hfinfo->display == BASE_CUSTOM) {
9765                 gchar tmp[ITEM_LABEL_LENGTH];
9766                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9767
9768                 DISSECTOR_ASSERT(fmtfunc);
9769                 fmtfunc(tmp, value);
9770                 label_fill(label_str, 0, hfinfo, tmp);
9771         }
9772         else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
9773                 /*
9774                  * It makes no sense to have a value-string table for a
9775                  * frame-number field - they're just integers giving
9776                  * the ordinal frame number.
9777                  */
9778                 const char *val_str = hf_try_val_to_str(value, hfinfo);
9779
9780                 out = hfinfo_number_vals_format(hfinfo, buf, value);
9781                 if (hfinfo->display & BASE_SPECIAL_VALS) {
9782                         /*
9783                          * Unique values only display value_string string
9784                          * if there is a match. Otherwise it's just a number
9785                          */
9786                         if (val_str) {
9787                                 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9788                         } else {
9789                                 label_fill(label_str, 0, hfinfo, out);
9790                         }
9791                 } else {
9792                         if (val_str == NULL)
9793                                 val_str = "Unknown";
9794
9795                         if (out == NULL) /* BASE_NONE so don't put integer in descr */
9796                                 label_fill(label_str, 0, hfinfo, val_str);
9797                         else
9798                                 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9799                 }
9800         }
9801         else if (IS_BASE_PORT(hfinfo->display)) {
9802                 gchar tmp[ITEM_LABEL_LENGTH];
9803
9804                 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
9805                         display_to_port_type((field_display_e)hfinfo->display), value);
9806                 label_fill(label_str, 0, hfinfo, tmp);
9807         }
9808         else {
9809                 out = hfinfo_number_value_format(hfinfo, buf, value);
9810
9811                 label_fill(label_str, 0, hfinfo, out);
9812         }
9813 }
9814
9815 static void
9816 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
9817 {
9818         header_field_info *hfinfo = fi->hfinfo;
9819         guint64            value;
9820
9821         char               buf[48];
9822         const char        *out;
9823
9824         if (is_signed)
9825                 value = fvalue_get_sinteger64(&fi->value);
9826         else
9827                 value = fvalue_get_uinteger64(&fi->value);
9828
9829         /* Fill in the textual info */
9830         if (hfinfo->display == BASE_CUSTOM) {
9831                 gchar tmp[ITEM_LABEL_LENGTH];
9832                 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9833
9834                 DISSECTOR_ASSERT(fmtfunc64);
9835                 fmtfunc64(tmp, value);
9836                 label_fill(label_str, 0, hfinfo, tmp);
9837         }
9838         else if (hfinfo->strings) {
9839                 const char *val_str = hf_try_val64_to_str(value, hfinfo);
9840
9841                 out = hfinfo_number_vals_format64(hfinfo, buf, value);
9842                 if (hfinfo->display & BASE_SPECIAL_VALS) {
9843                         /*
9844                          * Unique values only display value_string string
9845                          * if there is a match. Otherwise it's just a number
9846                          */
9847                         if (val_str) {
9848                                 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9849                         } else {
9850                                 label_fill(label_str, 0, hfinfo, out);
9851                         }
9852                 } else {
9853                         if (val_str == NULL)
9854                                 val_str = "Unknown";
9855
9856                         if (out == NULL) /* BASE_NONE so don't put integer in descr */
9857                                 label_fill(label_str, 0, hfinfo, val_str);
9858                         else
9859                                 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9860                 }
9861         }
9862         else {
9863                 out = hfinfo_number_value_format64(hfinfo, buf, value);
9864
9865                 label_fill(label_str, 0, hfinfo, out);
9866         }
9867 }
9868
9869 int
9870 hfinfo_bitshift(const header_field_info *hfinfo)
9871 {
9872         return ws_ctz(hfinfo->bitmask);
9873 }
9874
9875
9876 static int
9877 hfinfo_bitoffset(const header_field_info *hfinfo)
9878 {
9879         if (!hfinfo->bitmask) {
9880                 return 0;
9881         }
9882
9883         /* ilog2 = first set bit, counting 0 as the last bit; we want 0
9884          * as the first bit */
9885         return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
9886 }
9887
9888 static int
9889 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
9890 {
9891         if (!hfinfo->bitmask) {
9892                 return 0;
9893         }
9894
9895         /* ilog2 = first set bit, ctz = last set bit */
9896         return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
9897 }
9898
9899 static int
9900 hfinfo_type_bitwidth(enum ftenum type)
9901 {
9902         int bitwidth = 0;
9903
9904         switch (type) {
9905                 case FT_CHAR:
9906                 case FT_UINT8:
9907                 case FT_INT8:
9908                         bitwidth = 8;
9909                         break;
9910                 case FT_UINT16:
9911                 case FT_INT16:
9912                         bitwidth = 16;
9913                         break;
9914                 case FT_UINT24:
9915                 case FT_INT24:
9916                         bitwidth = 24;
9917                         break;
9918                 case FT_UINT32:
9919                 case FT_INT32:
9920                         bitwidth = 32;
9921                         break;
9922                 case FT_UINT40:
9923                 case FT_INT40:
9924                         bitwidth = 40;
9925                         break;
9926                 case FT_UINT48:
9927                 case FT_INT48:
9928                         bitwidth = 48;
9929                         break;
9930                 case FT_UINT56:
9931                 case FT_INT56:
9932                         bitwidth = 56;
9933                         break;
9934                 case FT_UINT64:
9935                 case FT_INT64:
9936                         bitwidth = 64;
9937                         break;
9938                 default:
9939                         DISSECTOR_ASSERT_NOT_REACHED();
9940                         ;
9941         }
9942         return bitwidth;
9943 }
9944
9945
9946 static int
9947 hfinfo_container_bitwidth(const header_field_info *hfinfo)
9948 {
9949         if (!hfinfo->bitmask) {
9950                 return 0;
9951         }
9952
9953         if (hfinfo->type == FT_BOOLEAN) {
9954                 return hfinfo->display; /* hacky? :) */
9955         }
9956
9957         return hfinfo_type_bitwidth(hfinfo->type);
9958 }
9959
9960 static int
9961 hfinfo_hex_digits(const header_field_info *hfinfo)
9962 {
9963         int bitwidth;
9964
9965         /* If we have a bitmask, hfinfo->type is the width of the container, so not
9966          * appropriate to determine the number of hex digits for the field.
9967          * So instead, we compute it from the bitmask.
9968          */
9969         if (hfinfo->bitmask != 0) {
9970                 bitwidth = hfinfo_mask_bitwidth(hfinfo);
9971         } else {
9972                 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
9973         }
9974
9975         /* Divide by 4, rounding up, to get number of hex digits. */
9976         return (bitwidth + 3) / 4;
9977 }
9978
9979 static const char *
9980 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
9981 {
9982         char *ptr = &buf[6];
9983         static const gchar hex_digits[16] =
9984         { '0', '1', '2', '3', '4', '5', '6', '7',
9985           '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
9986
9987         *ptr = '\0';
9988         *(--ptr) = '\'';
9989         /* Properly format value */
9990         if (g_ascii_isprint(value)) {
9991                 /*
9992                  * Printable, so just show the character, and, if it needs
9993                  * to be escaped, escape it.
9994                  */
9995                 *(--ptr) = value;
9996                 if (value == '\\' || value == '\'')
9997                         *(--ptr) = '\\';
9998         } else {
9999                 /*
10000                  * Non-printable; show it as an escape sequence.
10001                  */
10002                 switch (value) {
10003
10004                 case '\0':
10005                         /*
10006                          * Show a NUL with only one digit.
10007                          */
10008                         *(--ptr) = '0';
10009                         break;
10010
10011                 case '\a':
10012                         *(--ptr) = 'a';
10013                         break;
10014
10015                 case '\b':
10016                         *(--ptr) = 'b';
10017                         break;
10018
10019                 case '\f':
10020                         *(--ptr) = 'f';
10021                         break;
10022
10023                 case '\n':
10024                         *(--ptr) = 'n';
10025                         break;
10026
10027                 case '\r':
10028                         *(--ptr) = 'r';
10029                         break;
10030
10031                 case '\t':
10032                         *(--ptr) = 't';
10033                         break;
10034
10035                 case '\v':
10036                         *(--ptr) = 'v';
10037                         break;
10038
10039                 default:
10040                         switch (FIELD_DISPLAY(display)) {
10041
10042                         case BASE_OCT:
10043                                 *(--ptr) = (value & 0x7) + '0';
10044                                 value >>= 3;
10045                                 *(--ptr) = (value & 0x7) + '0';
10046                                 value >>= 3;
10047                                 *(--ptr) = (value & 0x7) + '0';
10048                                 break;
10049
10050                         case BASE_HEX:
10051                                 *(--ptr) = hex_digits[value & 0x0F];
10052                                 value >>= 4;
10053                                 *(--ptr) = hex_digits[value & 0x0F];
10054                                 *(--ptr) = 'x';
10055                                 break;
10056
10057                         default:
10058                                 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
10059                         }
10060                 }
10061                 *(--ptr) = '\\';
10062         }
10063         *(--ptr) = '\'';
10064         return ptr;
10065 }
10066
10067 static const char *
10068 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
10069 {
10070         char *ptr = &buf[31];
10071         gboolean isint = IS_FT_INT(hfinfo->type);
10072
10073         *ptr = '\0';
10074         /* Properly format value */
10075         switch (FIELD_DISPLAY(display)) {
10076                 case BASE_DEC:
10077                         return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
10078
10079                 case BASE_DEC_HEX:
10080                         *(--ptr) = ')';
10081                         ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10082                         *(--ptr) = '(';
10083                         *(--ptr) = ' ';
10084                         ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
10085                         return ptr;
10086
10087                 case BASE_OCT:
10088                         return oct_to_str_back(ptr, value);
10089
10090                 case BASE_HEX:
10091                         return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10092
10093                 case BASE_HEX_DEC:
10094                         *(--ptr) = ')';
10095                         ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
10096                         *(--ptr) = '(';
10097                         *(--ptr) = ' ';
10098                         ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10099                         return ptr;
10100
10101                 case BASE_PT_UDP:
10102                 case BASE_PT_TCP:
10103                 case BASE_PT_DCCP:
10104                 case BASE_PT_SCTP:
10105                         port_with_resolution_to_str_buf(buf, 32,
10106                                         display_to_port_type((field_display_e)display), value);
10107                         return buf;
10108                 case BASE_OUI:
10109                         {
10110                         guint8 p_oui[3];
10111                         const gchar *manuf_name;
10112
10113                         p_oui[0] = value >> 16 & 0xFF;
10114                         p_oui[1] = value >> 8 & 0xFF;
10115                         p_oui[2] = value & 0xFF;
10116
10117                         /* Attempt an OUI lookup. */
10118                         manuf_name = uint_get_manuf_name_if_known(value);
10119                         if (manuf_name == NULL) {
10120                                 /* Could not find an OUI. */
10121                                 g_snprintf(buf, 32, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
10122                         }
10123                         else {
10124                                 /* Found an address string. */
10125                                 g_snprintf(buf, 32, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
10126                         }
10127                         return buf;
10128                         }
10129
10130                 default:
10131                         REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
10132         }
10133         return ptr;
10134 }
10135
10136 static const char *
10137 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
10138 {
10139         char *ptr = &buf[47];
10140         gboolean isint = IS_FT_INT(hfinfo->type);
10141
10142         *ptr = '\0';
10143         /* Properly format value */
10144         switch (FIELD_DISPLAY(display)) {
10145                 case BASE_DEC:
10146                         return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
10147
10148                 case BASE_DEC_HEX:
10149                         *(--ptr) = ')';
10150                         ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10151                         *(--ptr) = '(';
10152                         *(--ptr) = ' ';
10153                         ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
10154                         return ptr;
10155
10156                 case BASE_OCT:
10157                         return oct64_to_str_back(ptr, value);
10158
10159                 case BASE_HEX:
10160                         return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10161
10162                 case BASE_HEX_DEC:
10163                         *(--ptr) = ')';
10164                         ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
10165                         *(--ptr) = '(';
10166                         *(--ptr) = ' ';
10167                         ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
10168                         return ptr;
10169
10170                 default:
10171                         REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
10172         }
10173
10174         return ptr;
10175 }
10176
10177 static const char *
10178 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10179 {
10180         int display = hfinfo->display;
10181
10182         if (hfinfo->type == FT_FRAMENUM) {
10183                 /*
10184                  * Frame numbers are always displayed in decimal.
10185                  */
10186                 display = BASE_DEC;
10187         }
10188
10189         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
10190 }
10191
10192 static const char *
10193 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value)
10194 {
10195         int display = hfinfo->display;
10196
10197         if (hfinfo->type == FT_FRAMENUM) {
10198                 /*
10199                  * Frame numbers are always displayed in decimal.
10200                  */
10201                 display = BASE_DEC;
10202         }
10203
10204         return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
10205 }
10206
10207 static const char *
10208 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10209 {
10210         /* Get the underlying BASE_ value */
10211         int display = FIELD_DISPLAY(hfinfo->display);
10212
10213         return hfinfo_char_value_format_display(display, buf, value);
10214 }
10215
10216 static const char *
10217 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10218 {
10219         /* Get the underlying BASE_ value */
10220         int display = FIELD_DISPLAY(hfinfo->display);
10221
10222         if (hfinfo->type == FT_FRAMENUM) {
10223                 /*
10224                  * Frame numbers are always displayed in decimal.
10225                  */
10226                 display = BASE_DEC;
10227         }
10228
10229         if (IS_BASE_PORT(display)) {
10230                 display = BASE_DEC;
10231         } else if (display == BASE_OUI) {
10232                 display = BASE_HEX;
10233         }
10234
10235         switch (display) {
10236                 case BASE_NONE:
10237                 /* case BASE_DEC: */
10238                 case BASE_DEC_HEX:
10239                 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
10240                 case BASE_CUSTOM:
10241                         display = BASE_DEC;
10242                         break;
10243
10244                 /* case BASE_HEX: */
10245                 case BASE_HEX_DEC:
10246                         display = BASE_HEX;
10247                         break;
10248         }
10249
10250         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
10251 }
10252
10253 static const char *
10254 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value)
10255 {
10256         /* Get the underlying BASE_ value */
10257         int display = FIELD_DISPLAY(hfinfo->display);
10258
10259         if (hfinfo->type == FT_FRAMENUM) {
10260                 /*
10261                  * Frame numbers are always displayed in decimal.
10262                  */
10263                 display = BASE_DEC;
10264         }
10265
10266         switch (display) {
10267                 case BASE_NONE:
10268                 /* case BASE_DEC: */
10269                 case BASE_DEC_HEX:
10270                 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
10271                 case BASE_CUSTOM:
10272                         display = BASE_DEC;
10273                         break;
10274
10275                 /* case BASE_HEX: */
10276                 case BASE_HEX_DEC:
10277                         display = BASE_HEX;
10278                         break;
10279         }
10280
10281         return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
10282 }
10283
10284 static const char *
10285 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10286 {
10287         /* Get the underlying BASE_ value */
10288         int display = FIELD_DISPLAY(hfinfo->display);
10289
10290         return hfinfo_char_value_format_display(display, buf, value);
10291 }
10292
10293 static const char *
10294 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10295 {
10296         /* Get the underlying BASE_ value */
10297         int display = FIELD_DISPLAY(hfinfo->display);
10298
10299         if (display == BASE_NONE)
10300                 return NULL;
10301
10302         if (display == BASE_DEC_HEX)
10303                 display = BASE_DEC;
10304         if (display == BASE_HEX_DEC)
10305                 display = BASE_HEX;
10306
10307         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
10308 }
10309
10310 static const char *
10311 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value)
10312 {
10313         /* Get the underlying BASE_ value */
10314         int display = FIELD_DISPLAY(hfinfo->display);
10315
10316         if (display == BASE_NONE)
10317                 return NULL;
10318
10319         if (display == BASE_DEC_HEX)
10320                 display = BASE_DEC;
10321         if (display == BASE_HEX_DEC)
10322                 display = BASE_HEX;
10323
10324         return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
10325 }
10326
10327 const char *
10328 proto_registrar_get_name(const int n)
10329 {
10330         header_field_info *hfinfo;
10331
10332         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10333         return hfinfo->name;
10334 }
10335
10336 const char *
10337 proto_registrar_get_abbrev(const int n)
10338 {
10339         header_field_info *hfinfo;
10340
10341         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10342         return hfinfo->abbrev;
10343 }
10344
10345 enum ftenum
10346 proto_registrar_get_ftype(const int n)
10347 {
10348         header_field_info *hfinfo;
10349
10350         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10351         return hfinfo->type;
10352 }
10353
10354 int
10355 proto_registrar_get_parent(const int n)
10356 {
10357         header_field_info *hfinfo;
10358
10359         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10360         return hfinfo->parent;
10361 }
10362
10363 gboolean
10364 proto_registrar_is_protocol(const int n)
10365 {
10366         header_field_info *hfinfo;
10367
10368         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10369         return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
10370 }
10371
10372 /* Returns length of field in packet (not necessarily the length
10373  * in our internal representation, as in the case of IPv4).
10374  * 0 means undeterminable at time of registration
10375  * -1 means the field is not registered. */
10376 gint
10377 proto_registrar_get_length(const int n)
10378 {
10379         header_field_info *hfinfo;
10380
10381         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10382         return ftype_length(hfinfo->type);
10383 }
10384
10385 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
10386  * it exists anywhere, or FALSE if it exists nowhere. */
10387 gboolean
10388 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
10389 {
10390         GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
10391
10392         if (g_ptr_array_len(ptrs) > 0) {
10393                 return TRUE;
10394         }
10395         else {
10396                 return FALSE;
10397         }
10398 }
10399
10400 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
10401  * This only works if the hfindex was "primed" before the dissection
10402  * took place, as we just pass back the already-created GPtrArray*.
10403  * The caller should *not* free the GPtrArray*; proto_tree_free_node()
10404  * handles that. */
10405 GPtrArray *
10406 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
10407 {
10408         if (!tree)
10409                 return NULL;
10410
10411         if (PTREE_DATA(tree)->interesting_hfids != NULL)
10412                 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
10413                                            GINT_TO_POINTER(id));
10414         else
10415                 return NULL;
10416 }
10417
10418 gboolean
10419 proto_tracking_interesting_fields(const proto_tree *tree)
10420 {
10421         GHashTable *interesting_hfids;
10422
10423         if (!tree)
10424                 return FALSE;
10425
10426         interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
10427
10428         return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
10429 }
10430
10431 /* Helper struct for proto_find_info() and      proto_all_finfos() */
10432 typedef struct {
10433         GPtrArray *array;
10434         int        id;
10435 } ffdata_t;
10436
10437 /* Helper function for proto_find_info() */
10438 static gboolean
10439 find_finfo(proto_node *node, gpointer data)
10440 {
10441         field_info *fi = PNODE_FINFO(node);
10442         if (fi && fi->hfinfo) {
10443                 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
10444                         g_ptr_array_add(((ffdata_t*)data)->array, fi);
10445                 }
10446         }
10447
10448         /* Don't stop traversing. */
10449         return FALSE;
10450 }
10451
10452 /* Helper function for proto_find_first_info() */
10453 static gboolean
10454 find_first_finfo(proto_node *node, gpointer data)
10455 {
10456         field_info *fi = PNODE_FINFO(node);
10457         if (fi && fi->hfinfo) {
10458                 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
10459                         g_ptr_array_add(((ffdata_t*)data)->array, fi);
10460
10461                         /* Stop traversing. */
10462                         return TRUE;
10463                 }
10464         }
10465
10466         /* Continue traversing. */
10467         return FALSE;
10468 }
10469
10470 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
10471 * This works on any proto_tree, primed or unprimed, but actually searches
10472 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
10473 * The caller does need to free the returned GPtrArray with
10474 * g_ptr_array_free(<array>, TRUE).
10475 */
10476 GPtrArray *
10477 proto_find_finfo(proto_tree *tree, const int id)
10478 {
10479         ffdata_t ffdata;
10480
10481         ffdata.array = g_ptr_array_new();
10482         ffdata.id = id;
10483
10484         proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
10485
10486         return ffdata.array;
10487 }
10488
10489 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
10490 * This works on any proto_tree, primed or unprimed, but actually searches
10491 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
10492 * The caller does need to free the returned GPtrArray with
10493 * g_ptr_array_free(<array>, TRUE).
10494 */
10495 GPtrArray *
10496 proto_find_first_finfo(proto_tree *tree, const int id)
10497 {
10498         ffdata_t ffdata;
10499
10500         ffdata.array = g_ptr_array_new();
10501         ffdata.id = id;
10502
10503         proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
10504
10505         return ffdata.array;
10506 }
10507
10508 /* Helper function for proto_all_finfos() */
10509 static gboolean
10510 every_finfo(proto_node *node, gpointer data)
10511 {
10512         field_info *fi = PNODE_FINFO(node);
10513         if (fi && fi->hfinfo) {
10514                 g_ptr_array_add(((ffdata_t*)data)->array, fi);
10515         }
10516
10517         /* Don't stop traversing. */
10518         return FALSE;
10519 }
10520
10521 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
10522 GPtrArray *
10523 proto_all_finfos(proto_tree *tree)
10524 {
10525         ffdata_t ffdata;
10526
10527         /* Pre allocate enough space to hold all fields in most cases */
10528         ffdata.array = g_ptr_array_sized_new(512);
10529         ffdata.id = 0;
10530
10531         proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
10532
10533         return ffdata.array;
10534 }
10535
10536
10537 typedef struct {
10538         guint       offset;
10539         field_info *finfo;
10540         tvbuff_t   *tvb;
10541 } offset_search_t;
10542
10543 static gboolean
10544 check_for_offset(proto_node *node, gpointer data)
10545 {
10546         field_info      *fi        = PNODE_FINFO(node);
10547         offset_search_t *offsearch = (offset_search_t *)data;
10548
10549         /* !fi == the top most container node which holds nothing */
10550         if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
10551                 if (offsearch->offset >= (guint) fi->start &&
10552                                 offsearch->offset < (guint) (fi->start + fi->length)) {
10553
10554                         offsearch->finfo = fi;
10555                         return FALSE; /* keep traversing */
10556                 }
10557         }
10558         return FALSE; /* keep traversing */
10559 }
10560
10561 /* Search a proto_tree backwards (from leaves to root) looking for the field
10562  * whose start/length occupies 'offset' */
10563 /* XXX - I couldn't find an easy way to search backwards, so I search
10564  * forwards, w/o stopping. Therefore, the last finfo I find will the be
10565  * the one I want to return to the user. This algorithm is inefficient
10566  * and could be re-done, but I'd have to handle all the children and
10567  * siblings of each node myself. When I have more time I'll do that.
10568  * (yeah right) */
10569 field_info *
10570 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
10571 {
10572         offset_search_t offsearch;
10573
10574         offsearch.offset = offset;
10575         offsearch.finfo  = NULL;
10576         offsearch.tvb    = tvb;
10577
10578         proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
10579
10580         return offsearch.finfo;
10581 }
10582
10583 typedef struct {
10584         gint length;
10585         gchar *buf;
10586 } decoded_data_t;
10587
10588 static gboolean
10589 check_for_undecoded(proto_node *node, gpointer data)
10590 {
10591         field_info *fi = PNODE_FINFO(node);
10592         decoded_data_t* decoded = (decoded_data_t*)data;
10593         gint i;
10594         guint byte;
10595         guint bit;
10596
10597         if (fi && fi->hfinfo->type != FT_PROTOCOL) {
10598                 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
10599                         byte = i / 8;
10600                         bit = i % 8;
10601                         decoded->buf[byte] |= (1 << bit);
10602                 }
10603         }
10604
10605         return FALSE;
10606 }
10607
10608 gchar*
10609 proto_find_undecoded_data(proto_tree *tree, guint length)
10610 {
10611         decoded_data_t decoded;
10612         decoded.length = length;
10613         decoded.buf = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
10614
10615         proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
10616         return decoded.buf;
10617 }
10618
10619 /* Dumps the protocols in the registration database to stdout.  An independent
10620  * program can take this output and format it into nice tables or HTML or
10621  * whatever.
10622  *
10623  * There is one record per line. The fields are tab-delimited.
10624  *
10625  * Field 1 = protocol name
10626  * Field 2 = protocol short name
10627  * Field 3 = protocol filter name
10628  */
10629 void
10630 proto_registrar_dump_protocols(void)
10631 {
10632         protocol_t *protocol;
10633         int         i;
10634         void       *cookie = NULL;
10635
10636
10637         i = proto_get_first_protocol(&cookie);
10638         while (i != -1) {
10639                 protocol = find_protocol_by_id(i);
10640                 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
10641                         protocol->filter_name);
10642                 i = proto_get_next_protocol(&cookie);
10643         }
10644 }
10645
10646 /* Dumps the value_strings, extended value string headers, range_strings
10647  * or true/false strings for fields that have them.
10648  * There is one record per line. Fields are tab-delimited.
10649  * There are four types of records: Value String, Extended Value String Header,
10650  * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
10651  * the type of record.
10652  *
10653  * Note that a record will be generated only if the value_string,... is referenced
10654  * in a registered hfinfo entry.
10655  *
10656  *
10657  * Value Strings
10658  * -------------
10659  * Field 1 = 'V'
10660  * Field 2 = Field abbreviation to which this value string corresponds
10661  * Field 3 = Integer value
10662  * Field 4 = String
10663  *
10664  * Extended Value String Headers
10665  * -----------------------------
10666  * Field 1 = 'E'
10667  * Field 2 = Field abbreviation to which this extended value string header corresponds
10668  * Field 3 = Extended Value String "Name"
10669  * Field 4 = Number of entries in the associated value_string array
10670  * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
10671  *
10672  * Range Strings
10673  * -------------
10674  * Field 1 = 'R'
10675  * Field 2 = Field abbreviation to which this range string corresponds
10676  * Field 3 = Integer value: lower bound
10677  * Field 4 = Integer value: upper bound
10678  * Field 5 = String
10679  *
10680  * True/False Strings
10681  * ------------------
10682  * Field 1 = 'T'
10683  * Field 2 = Field abbreviation to which this true/false string corresponds
10684  * Field 3 = True String
10685  * Field 4 = False String
10686  */
10687 void
10688 proto_registrar_dump_values(void)
10689 {
10690         header_field_info       *hfinfo;
10691         int                     i, len, vi;
10692         const value_string      *vals;
10693         const val64_string      *vals64;
10694         const range_string      *range;
10695         const true_false_string *tfs;
10696         const unit_name_string  *units;
10697
10698         len = gpa_hfinfo.len;
10699         for (i = 0; i < len ; i++) {
10700                 if (gpa_hfinfo.hfi[i] == NULL)
10701                         continue; /* This is a deregistered protocol or field */
10702
10703                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10704
10705                 if (hfinfo->id == hf_text_only) {
10706                         continue;
10707                 }
10708
10709                 /* ignore protocols */
10710                 if (proto_registrar_is_protocol(i)) {
10711                         continue;
10712                 }
10713                 /* process header fields */
10714 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
10715                 /*
10716                  * If this field isn't at the head of the list of
10717                  * fields with this name, skip this field - all
10718                  * fields with the same name are really just versions
10719                  * of the same field stored in different bits, and
10720                  * should have the same type/radix/value list, and
10721                  * just differ in their bit masks.      (If a field isn't
10722                  * a bitfield, but can be, say, 1 or 2 bytes long,
10723                  * it can just be made FT_UINT16, meaning the
10724                  * *maximum* length is 2 bytes, and be used
10725                  * for all lengths.)
10726                  */
10727                 if (hfinfo->same_name_prev_id != -1)
10728                         continue;
10729 #endif
10730                 vals   = NULL;
10731                 vals64 = NULL;
10732                 range  = NULL;
10733                 tfs    = NULL;
10734                 units  = NULL;
10735
10736                 if (hfinfo->strings != NULL) {
10737                         if (FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM &&
10738                             (hfinfo->type == FT_CHAR  ||
10739                              hfinfo->type == FT_UINT8  ||
10740                              hfinfo->type == FT_UINT16 ||
10741                              hfinfo->type == FT_UINT24 ||
10742                              hfinfo->type == FT_UINT32 ||
10743                              hfinfo->type == FT_UINT40 ||
10744                              hfinfo->type == FT_UINT48 ||
10745                              hfinfo->type == FT_UINT56 ||
10746                              hfinfo->type == FT_UINT64 ||
10747                              hfinfo->type == FT_INT8   ||
10748                              hfinfo->type == FT_INT16  ||
10749                              hfinfo->type == FT_INT24  ||
10750                              hfinfo->type == FT_INT32  ||
10751                              hfinfo->type == FT_INT40  ||
10752                              hfinfo->type == FT_INT48  ||
10753                              hfinfo->type == FT_INT56  ||
10754                              hfinfo->type == FT_INT64  ||
10755                              hfinfo->type == FT_FLOAT  ||
10756                              hfinfo->type == FT_DOUBLE)) {
10757
10758                                 if (hfinfo->display & BASE_RANGE_STRING) {
10759                                         range = (const range_string *)hfinfo->strings;
10760                                 } else if (hfinfo->display & BASE_EXT_STRING) {
10761                                         if (hfinfo->display & BASE_VAL64_STRING) {
10762                                                 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings);
10763                                         } else {
10764                                                 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
10765                                         }
10766                                 } else if (hfinfo->display & BASE_VAL64_STRING) {
10767                                         vals64 = (const val64_string *)hfinfo->strings;
10768                                 } else if (hfinfo->display & BASE_UNIT_STRING) {
10769                                         units = (const unit_name_string *)hfinfo->strings;
10770                                 } else {
10771                                         vals = (const value_string *)hfinfo->strings;
10772                                 }
10773                         }
10774                         else if (hfinfo->type == FT_BOOLEAN) {
10775                                 tfs = (const struct true_false_string *)hfinfo->strings;
10776                         }
10777                 }
10778
10779                 /* Print value strings? */
10780                 if (vals) {
10781                         if (hfinfo->display & BASE_EXT_STRING) {
10782                                 if (hfinfo->display & BASE_VAL64_STRING) {
10783                                         val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
10784                                         if (!val64_string_ext_validate(vse_p)) {
10785                                                 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev);
10786                                                 continue;
10787                                         }
10788                                         try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
10789                                         printf("E\t%s\t%u\t%s\t%s\n",
10790                                                hfinfo->abbrev,
10791                                                VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p),
10792                                                VAL64_STRING_EXT_VS_NAME(vse_p),
10793                                                val64_string_ext_match_type_str(vse_p));
10794                                 } else {
10795                                         value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
10796                                         if (!value_string_ext_validate(vse_p)) {
10797                                                 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
10798                                                 continue;
10799                                         }
10800                                         try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
10801                                         printf("E\t%s\t%u\t%s\t%s\n",
10802                                                hfinfo->abbrev,
10803                                                VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
10804                                                VALUE_STRING_EXT_VS_NAME(vse_p),
10805                                                value_string_ext_match_type_str(vse_p));
10806                                 }
10807                         }
10808                         vi = 0;
10809                         while (vals[vi].strptr) {
10810                                 /* Print in the proper base */
10811                                 if (hfinfo->type == FT_CHAR) {
10812                                         if (g_ascii_isprint(vals[vi].value)) {
10813                                                 printf("V\t%s\t'%c'\t%s\n",
10814                                                        hfinfo->abbrev,
10815                                                        vals[vi].value,
10816                                                        vals[vi].strptr);
10817                                         } else {
10818                                                 if (hfinfo->display == BASE_HEX) {
10819                                                         printf("V\t%s\t'\\x%02x'\t%s\n",
10820                                                                hfinfo->abbrev,
10821                                                                vals[vi].value,
10822                                                                vals[vi].strptr);
10823                                                 }
10824                                                 else {
10825                                                         printf("V\t%s\t'\\%03o'\t%s\n",
10826                                                                hfinfo->abbrev,
10827                                                                vals[vi].value,
10828                                                                vals[vi].strptr);
10829                                                 }
10830                                         }
10831                                 } else {
10832                                         if (hfinfo->display == BASE_HEX) {
10833                                                 printf("V\t%s\t0x%x\t%s\n",
10834                                                        hfinfo->abbrev,
10835                                                        vals[vi].value,
10836                                                        vals[vi].strptr);
10837                                         }
10838                                         else {
10839                                                 printf("V\t%s\t%u\t%s\n",
10840                                                        hfinfo->abbrev,
10841                                                        vals[vi].value,
10842                                                        vals[vi].strptr);
10843                                         }
10844                                 }
10845                                 vi++;
10846                         }
10847                 }
10848                 else if (vals64) {
10849                         vi = 0;
10850                         while (vals64[vi].strptr) {
10851                                 printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
10852                                        hfinfo->abbrev,
10853                                        vals64[vi].value,
10854                                        vals64[vi].strptr);
10855                                 vi++;
10856                         }
10857                 }
10858
10859                 /* print range strings? */
10860                 else if (range) {
10861                         vi = 0;
10862                         while (range[vi].strptr) {
10863                                 /* Print in the proper base */
10864                                 if (FIELD_DISPLAY(hfinfo->display) == BASE_HEX) {
10865                                         printf("R\t%s\t0x%x\t0x%x\t%s\n",
10866                                                hfinfo->abbrev,
10867                                                range[vi].value_min,
10868                                                range[vi].value_max,
10869                                                range[vi].strptr);
10870                                 }
10871                                 else {
10872                                         printf("R\t%s\t%u\t%u\t%s\n",
10873                                                hfinfo->abbrev,
10874                                                range[vi].value_min,
10875                                                range[vi].value_max,
10876                                                range[vi].strptr);
10877                                 }
10878                                 vi++;
10879                         }
10880                 }
10881
10882                 /* Print true/false strings? */
10883                 else if (tfs) {
10884                         printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
10885                                tfs->true_string, tfs->false_string);
10886                 }
10887                 /* Print unit strings? */
10888                 else if (units) {
10889                         printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
10890                                units->singular, units->plural ? units->plural : "(no plural)");
10891                 }
10892         }
10893 }
10894
10895 /* Prints the number of registered fields.
10896  * Useful for determining an appropriate value for
10897  * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
10898  *
10899  * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
10900  * the number of fields, TRUE otherwise.
10901  */
10902 gboolean
10903 proto_registrar_dump_fieldcount(void)
10904 {
10905         guint32                 i;
10906         header_field_info       *hfinfo;
10907         guint32                 deregistered_count = 0;
10908         guint32                 same_name_count = 0;
10909         guint32                 protocol_count = 0;
10910
10911         for (i = 0; i < gpa_hfinfo.len; i++) {
10912                 if (gpa_hfinfo.hfi[i] == NULL) {
10913                         deregistered_count++;
10914                         continue; /* This is a deregistered protocol or header field */
10915                 }
10916
10917                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10918
10919                 if (proto_registrar_is_protocol(i))
10920                         protocol_count++;
10921
10922                 if (hfinfo->same_name_prev_id != -1)
10923                         same_name_count++;
10924         }
10925
10926         printf("There are %u header fields registered, of which:\n"
10927                 "\t%u are deregistered\n"
10928                 "\t%u are protocols\n"
10929                 "\t%u have the same name as another field\n\n",
10930                 gpa_hfinfo.len, deregistered_count, protocol_count,
10931                 same_name_count);
10932
10933         printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
10934                 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
10935                     "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
10936                     "\n");
10937
10938         printf("The header field table consumes %u KiB of memory.\n",
10939                 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
10940         printf("The fields themselves consume %u KiB of memory.\n",
10941                 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
10942
10943         return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
10944 }
10945
10946 static void
10947 elastic_add_base_mapping(json_dumper *dumper)
10948 {
10949         json_dumper_set_member_name(dumper, "index_patterns");
10950         json_dumper_value_string(dumper, "packets-*");
10951
10952         json_dumper_set_member_name(dumper, "settings");
10953         json_dumper_begin_object(dumper);
10954         json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
10955         json_dumper_value_anyf(dumper, "%d", 1000000);
10956         json_dumper_end_object(dumper);
10957 }
10958
10959 static gchar*
10960 ws_type_to_elastic(guint type _U_)
10961 {
10962         switch(type) {
10963                 case FT_UINT16:
10964                 case FT_INT16:
10965                 case FT_INT32:
10966                 case FT_UINT24:
10967                 case FT_INT24:
10968                         return "integer";
10969                 case FT_INT8:
10970                 case FT_UINT8:
10971                         return "short";
10972                 case FT_FRAMENUM:
10973                 case FT_UINT32:
10974                 case FT_UINT40:
10975                 case FT_UINT48:
10976                 case FT_UINT56:
10977                 case FT_UINT64: // Actually it's not handled by 'long' elastic type.
10978                 case FT_INT48:
10979                 case FT_INT64:
10980                         return "long";
10981                 case FT_FLOAT:
10982                 case FT_DOUBLE:
10983                         return "float";
10984                 case FT_IPv6:
10985                 case FT_IPv4:
10986                         return "ip";
10987                 case FT_ABSOLUTE_TIME:
10988                 case FT_RELATIVE_TIME:
10989                         return "date";
10990                 case FT_BYTES:
10991                 case FT_UINT_BYTES:
10992                         return "byte";
10993                 case FT_BOOLEAN:
10994                         return "boolean";
10995                 default:
10996                         return NULL;
10997         }
10998 }
10999
11000 static gchar*
11001 dot_to_underscore(gchar* str)
11002 {
11003         unsigned i;
11004         for (i = 0; i < strlen(str); i++) {
11005                 if (str[i] == '.')
11006                         str[i] = '_';
11007         }
11008         return str;
11009 }
11010
11011 /* Dumps a mapping file for ElasticSearch
11012  */
11013 void
11014 proto_registrar_dump_elastic(const gchar* filter)
11015 {
11016         header_field_info *hfinfo;
11017         header_field_info *parent_hfinfo;
11018         guint i;
11019         gboolean open_object = TRUE;
11020         const char* prev_proto = NULL;
11021         gchar* str;
11022         gchar** protos = NULL;
11023         gchar* proto;
11024         gboolean found;
11025         guint j;
11026         gchar* type;
11027
11028         /* We have filtering protocols. Extract them. */
11029         if (filter) {
11030                 protos = g_strsplit(filter, ",", -1);
11031         }
11032
11033         /*
11034          * To help tracking down the json tree, objects have been appended with a comment:
11035          * n.label -> where n is the indentation level and label the name of the object
11036          */
11037
11038         json_dumper dumper = {
11039                 .output_file = stdout,
11040                 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT,
11041         };
11042         json_dumper_begin_object(&dumper); // 1.root
11043         elastic_add_base_mapping(&dumper);
11044
11045         json_dumper_set_member_name(&dumper, "mappings");
11046         json_dumper_begin_object(&dumper); // 2.mappings
11047         json_dumper_set_member_name(&dumper, "doc");
11048
11049         json_dumper_begin_object(&dumper); // 3.doc
11050         json_dumper_set_member_name(&dumper, "dynamic");
11051         json_dumper_value_anyf(&dumper, "false");
11052
11053         json_dumper_set_member_name(&dumper, "properties");
11054         json_dumper_begin_object(&dumper); // 4.properties
11055         json_dumper_set_member_name(&dumper, "timestamp");
11056         json_dumper_begin_object(&dumper); // 5.timestamp
11057         json_dumper_set_member_name(&dumper, "type");
11058         json_dumper_value_string(&dumper, "date");
11059         json_dumper_end_object(&dumper); // 5.timestamp
11060
11061         json_dumper_set_member_name(&dumper, "layers");
11062         json_dumper_begin_object(&dumper); // 5.layers
11063         json_dumper_set_member_name(&dumper, "properties");
11064         json_dumper_begin_object(&dumper); // 6.properties
11065
11066         for (i = 0; i < gpa_hfinfo.len; i++) {
11067                 if (gpa_hfinfo.hfi[i] == NULL)
11068                         continue; /* This is a deregistered protocol or header field */
11069
11070                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
11071
11072                 /*
11073                  * Skip the pseudo-field for "proto_tree_add_text()" since
11074                  * we don't want it in the list of filterable protocols.
11075                  */
11076                 if (hfinfo->id == hf_text_only)
11077                         continue;
11078
11079                 if (!proto_registrar_is_protocol(i)) {
11080                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
11081
11082                         /*
11083                          * Skip the field if filter protocols have been set and this one's
11084                          * parent is not listed.
11085                          */
11086                         if (protos) {
11087                                 found = FALSE;
11088                                 j = 0;
11089                                 proto = protos[0];
11090                                 while(proto) {
11091                                         if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
11092                                                 found = TRUE;
11093                                                 break;
11094                                         }
11095                                         j++;
11096                                         proto = protos[j];
11097                                 }
11098                                 if (!found)
11099                                         continue;
11100                         }
11101
11102                         if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
11103                                 json_dumper_end_object(&dumper); // 8.properties
11104                                 json_dumper_end_object(&dumper); // 7.parent_hfinfo->abbrev
11105                                 open_object = TRUE;
11106                         }
11107
11108                         prev_proto = parent_hfinfo->abbrev;
11109
11110                         if (open_object) {
11111                                 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
11112                                 json_dumper_begin_object(&dumper); // 7.parent_hfinfo->abbrev
11113                                 json_dumper_set_member_name(&dumper, "properties");
11114                                 json_dumper_begin_object(&dumper); // 8.properties
11115                                 open_object = FALSE;
11116                         }
11117                         /* Skip the fields that would map into string. This is the default in elasticsearch. */
11118                         type = ws_type_to_elastic(hfinfo->type);
11119                         if (type) {
11120                                 str = g_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev);
11121                                 json_dumper_set_member_name(&dumper, dot_to_underscore(str));
11122                                 g_free(str);
11123                                 json_dumper_begin_object(&dumper); // 9.hfinfo->abbrev
11124                                 json_dumper_set_member_name(&dumper, "type");
11125                                 json_dumper_value_string(&dumper, type);
11126                                 json_dumper_end_object(&dumper); // 9.hfinfo->abbrev
11127                         }
11128                 }
11129         }
11130
11131         if (prev_proto) {
11132                 json_dumper_end_object(&dumper); // 8.properties
11133                 json_dumper_end_object(&dumper); // 7.parent_hfinfo->abbrev
11134         }
11135
11136         json_dumper_end_object(&dumper); // 6.properties
11137         json_dumper_end_object(&dumper); // 5.layers
11138         json_dumper_end_object(&dumper); // 4.properties
11139         json_dumper_end_object(&dumper); // 3.doc
11140         json_dumper_end_object(&dumper); // 2.mappings
11141         json_dumper_end_object(&dumper); // 1.root
11142         gboolean ret = json_dumper_finish(&dumper);
11143         DISSECTOR_ASSERT(ret);
11144
11145         g_strfreev(protos);
11146 }
11147
11148 /* Dumps the contents of the registration database to stdout. An independent
11149  * program can take this output and format it into nice tables or HTML or
11150  * whatever.
11151  *
11152  * There is one record per line. Each record is either a protocol or a header
11153  * field, differentiated by the first field. The fields are tab-delimited.
11154  *
11155  * Protocols
11156  * ---------
11157  * Field 1 = 'P'
11158  * Field 2 = descriptive protocol name
11159  * Field 3 = protocol abbreviation
11160  *
11161  * Header Fields
11162  * -------------
11163  * Field 1 = 'F'
11164  * Field 2 = descriptive field name
11165  * Field 3 = field abbreviation
11166  * Field 4 = type ( textual representation of the the ftenum type )
11167  * Field 5 = parent protocol abbreviation
11168  * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
11169  * Field 7 = bitmask: format: hex: 0x....
11170  * Field 8 = blurb describing field
11171  */
11172 void
11173 proto_registrar_dump_fields(void)
11174 {
11175         header_field_info *hfinfo, *parent_hfinfo;
11176         int                i, len;
11177         const char        *enum_name;
11178         const char        *base_name;
11179         const char        *blurb;
11180         char               width[5];
11181
11182         len = gpa_hfinfo.len;
11183         for (i = 0; i < len ; i++) {
11184                 if (gpa_hfinfo.hfi[i] == NULL)
11185                         continue; /* This is a deregistered protocol or header field */
11186
11187                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
11188
11189                 /*
11190                  * Skip the pseudo-field for "proto_tree_add_text()" since
11191                  * we don't want it in the list of filterable fields.
11192                  */
11193                 if (hfinfo->id == hf_text_only)
11194                         continue;
11195
11196                 /* format for protocols */
11197                 if (proto_registrar_is_protocol(i)) {
11198                         printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
11199                 }
11200                 /* format for header fields */
11201                 else {
11202                         /*
11203                          * If this field isn't at the head of the list of
11204                          * fields with this name, skip this field - all
11205                          * fields with the same name are really just versions
11206                          * of the same field stored in different bits, and
11207                          * should have the same type/radix/value list, and
11208                          * just differ in their bit masks.      (If a field isn't
11209                          * a bitfield, but can be, say, 1 or 2 bytes long,
11210                          * it can just be made FT_UINT16, meaning the
11211                          * *maximum* length is 2 bytes, and be used
11212                          * for all lengths.)
11213                          */
11214                         if (hfinfo->same_name_prev_id != -1)
11215                                 continue;
11216
11217                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
11218
11219                         enum_name = ftype_name(hfinfo->type);
11220                         base_name = "";
11221
11222                         if (hfinfo->type == FT_CHAR  ||
11223                             hfinfo->type == FT_UINT8  ||
11224                             hfinfo->type == FT_UINT16 ||
11225                             hfinfo->type == FT_UINT24 ||
11226                             hfinfo->type == FT_UINT32 ||
11227                             hfinfo->type == FT_UINT40 ||
11228                             hfinfo->type == FT_UINT48 ||
11229                             hfinfo->type == FT_UINT56 ||
11230                             hfinfo->type == FT_UINT64 ||
11231                             hfinfo->type == FT_INT8   ||
11232                             hfinfo->type == FT_INT16  ||
11233                             hfinfo->type == FT_INT24  ||
11234                             hfinfo->type == FT_INT32  ||
11235                             hfinfo->type == FT_INT40 ||
11236                             hfinfo->type == FT_INT48 ||
11237                             hfinfo->type == FT_INT56 ||
11238                             hfinfo->type == FT_INT64) {
11239
11240                                 switch (FIELD_DISPLAY(hfinfo->display)) {
11241                                         case BASE_NONE:
11242                                         case BASE_DEC:
11243                                         case BASE_HEX:
11244                                         case BASE_OCT:
11245                                         case BASE_DEC_HEX:
11246                                         case BASE_HEX_DEC:
11247                                         case BASE_CUSTOM:
11248                                         case BASE_PT_UDP:
11249                                         case BASE_PT_TCP:
11250                                         case BASE_PT_DCCP:
11251                                         case BASE_PT_SCTP:
11252                                         case BASE_OUI:
11253                                                 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
11254                                                 break;
11255                                         default:
11256                                                 base_name = "????";
11257                                                 break;
11258                                 }
11259                         } else if (hfinfo->type == FT_BOOLEAN) {
11260                                 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
11261                                 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
11262                                 base_name = width;
11263                         }
11264
11265                         blurb = hfinfo->blurb;
11266                         if (blurb == NULL)
11267                                 blurb = "";
11268                         else if (strlen(blurb) == 0)
11269                                 blurb = "\"\"";
11270
11271                         printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
11272                                 hfinfo->name, hfinfo->abbrev, enum_name,
11273                                 parent_hfinfo->abbrev, base_name,
11274                                 hfinfo->bitmask, blurb);
11275                 }
11276         }
11277 }
11278
11279 /* Dumps field types and descriptive names to stdout. An independent
11280  * program can take this output and format it into nice tables or HTML or
11281  * whatever.
11282  *
11283  * There is one record per line. The fields are tab-delimited.
11284  *
11285  * Field 1 = field type name, e.g. FT_UINT8
11286  * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
11287  */
11288 void
11289 proto_registrar_dump_ftypes(void)
11290 {
11291         int fte;
11292
11293         for (fte = 0; fte < FT_NUM_TYPES; fte++) {
11294                 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
11295         }
11296 }
11297
11298 /* This function indicates whether it's possible to construct a
11299  * "match selected" display filter string for the specified field,
11300  * returns an indication of whether it's possible, and, if it's
11301  * possible and "filter" is non-null, constructs the filter and
11302  * sets "*filter" to point to it.
11303  * You do not need to [g_]free() this string since it will be automatically
11304  * freed once the next packet is dissected.
11305  */
11306 static gboolean
11307 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
11308                                 char **filter)
11309 {
11310         header_field_info *hfinfo;
11311         int                abbrev_len;
11312         char              *ptr;
11313         int                buf_len;
11314         int                dfilter_len, i;
11315         gint               start, length, length_remaining;
11316         guint8             c;
11317         gchar              is_signed_num = FALSE;
11318
11319         if (!finfo)
11320                 return FALSE;
11321
11322         hfinfo     = finfo->hfinfo;
11323         DISSECTOR_ASSERT(hfinfo);
11324         abbrev_len = (int) strlen(hfinfo->abbrev);
11325
11326         if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
11327                 const gchar *str = NULL;
11328
11329                 switch (hfinfo->type) {
11330
11331                 case FT_INT8:
11332                 case FT_INT16:
11333                 case FT_INT24:
11334                 case FT_INT32:
11335                         str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
11336                         break;
11337
11338                 case FT_CHAR:
11339                 case FT_UINT8:
11340                 case FT_UINT16:
11341                 case FT_UINT24:
11342                 case FT_UINT32:
11343                         str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
11344                         break;
11345
11346                 default:
11347                         break;
11348                 }
11349
11350                 if (str != NULL && filter != NULL) {
11351                         *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
11352                         return TRUE;
11353                 }
11354         }
11355
11356         /*
11357          * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
11358          * functions for FT_UINT and FT_INT types, as we choose the base in
11359          * the string expression based on the display base of the field.
11360          *
11361          * Note that the base does matter, as this is also used for
11362          * the protocolinfo tap.
11363          *
11364          * It might be nice to use them in "proto_item_fill_label()"
11365          * as well, although, there, you'd have to deal with the base
11366          * *and* with resolved values for addresses.
11367          *
11368          * Perhaps we need two different val_to_string routines, one
11369          * to generate items for display filters and one to generate
11370          * strings for display, and pass to both of them the
11371          * "display" and "strings" values in the header_field_info
11372          * structure for the field, so they can get the base and,
11373          * if the field is Boolean or an enumerated integer type,
11374          * the tables used to generate human-readable values.
11375          */
11376         switch (hfinfo->type) {
11377
11378                 case FT_CHAR:
11379                         if (filter != NULL) {
11380                                 guint32 number;
11381
11382                                 char buf [48];
11383                                 const char *out;
11384
11385                                 number = fvalue_get_uinteger(&finfo->value);
11386
11387                                 out = hfinfo_char_value_format(hfinfo, buf, number);
11388
11389                                 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
11390                         }
11391                         break;
11392
11393                 case FT_INT8:
11394                 case FT_INT16:
11395                 case FT_INT24:
11396                 case FT_INT32:
11397                         is_signed_num = TRUE;
11398                         /* FALLTHRU */
11399                 case FT_UINT8:
11400                 case FT_UINT16:
11401                 case FT_UINT24:
11402                 case FT_UINT32:
11403                 case FT_FRAMENUM:
11404                         if (filter != NULL) {
11405                                 guint32 number;
11406
11407                                 char buf[32];
11408                                 const char *out;
11409
11410                                 if (is_signed_num)
11411                                         number = fvalue_get_sinteger(&finfo->value);
11412                                 else
11413                                         number = fvalue_get_uinteger(&finfo->value);
11414
11415                                 out = hfinfo_numeric_value_format(hfinfo, buf, number);
11416
11417                                 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
11418                         }
11419                         break;
11420
11421                 case FT_INT40:
11422                 case FT_INT48:
11423                 case FT_INT56:
11424                 case FT_INT64:
11425                         is_signed_num = TRUE;
11426                         /* FALLTHRU */
11427                 case FT_UINT40:
11428                 case FT_UINT48:
11429                 case FT_UINT56:
11430                 case FT_UINT64:
11431                         if (filter != NULL) {
11432                                 guint64 number;
11433
11434                                 char buf [48];
11435                                 const char *out;
11436
11437                                 if (is_signed_num)
11438                                         number = fvalue_get_sinteger64(&finfo->value);
11439                                 else
11440                                         number = fvalue_get_uinteger64(&finfo->value);
11441
11442                                 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
11443
11444                                 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
11445                         }
11446                         break;
11447
11448                 case FT_PROTOCOL:
11449                         if (filter != NULL)
11450                                 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
11451                         break;
11452
11453                 case FT_NONE:
11454                         /*
11455                          * If the length is 0, just match the name of the
11456                          * field.
11457                          *
11458                          * (Also check for negative values, just in case,
11459                          * as we'll cast it to an unsigned value later.)
11460                          */
11461                         length = finfo->length;
11462                         if (length == 0) {
11463                                 if (filter != NULL)
11464                                         *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
11465                                 break;
11466                         }
11467                         if (length < 0)
11468                                 return FALSE;
11469
11470                         /*
11471                          * This doesn't have a value, so we'd match
11472                          * on the raw bytes at this address.
11473                          *
11474                          * Should we be allowed to access to the raw bytes?
11475                          * If "edt" is NULL, the answer is "no".
11476                          */
11477                         if (edt == NULL)
11478                                 return FALSE;
11479
11480                         /*
11481                          * Is this field part of the raw frame tvbuff?
11482                          * If not, we can't use "frame[N:M]" to match
11483                          * it.
11484                          *
11485                          * XXX - should this be frame-relative, or
11486                          * protocol-relative?
11487                          *
11488                          * XXX - does this fallback for non-registered
11489                          * fields even make sense?
11490                          */
11491                         if (finfo->ds_tvb != edt->tvb)
11492                                 return FALSE;   /* you lose */
11493
11494                         /*
11495                          * Don't go past the end of that tvbuff.
11496                          */
11497                         length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
11498                         if (length > length_remaining)
11499                                 length = length_remaining;
11500                         if (length <= 0)
11501                                 return FALSE;
11502
11503                         if (filter != NULL) {
11504                                 start = finfo->start;
11505                                 buf_len = 32 + length * 3;
11506                                 *filter = (char *)wmem_alloc0(NULL, buf_len);
11507                                 ptr = *filter;
11508
11509                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
11510                                         "frame[%d:%d] == ", finfo->start, length);
11511                                 for (i=0; i<length; i++) {
11512                                         c = tvb_get_guint8(finfo->ds_tvb, start);
11513                                         start++;
11514                                         if (i == 0 ) {
11515                                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
11516                                         }
11517                                         else {
11518                                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
11519                                         }
11520                                 }
11521                         }
11522                         break;
11523
11524                 /* By default, use the fvalue's "to_string_repr" method. */
11525                 default:
11526                         /* Figure out the string length needed.
11527                          *      The ft_repr length.
11528                          *      4 bytes for " == ".
11529                          *      1 byte for trailing NUL.
11530                          */
11531                         if (filter != NULL) {
11532                                 char* str;
11533                                 dfilter_len = fvalue_string_repr_len(&finfo->value,
11534                                                 FTREPR_DFILTER, finfo->hfinfo->display);
11535                                 dfilter_len += abbrev_len + 4 + 1;
11536                                 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
11537
11538                                 /* Create the string */
11539                                 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
11540                                 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
11541                                 wmem_free(NULL, str);
11542                         }
11543                         break;
11544         }
11545
11546         return TRUE;
11547 }
11548
11549 /*
11550  * Returns TRUE if we can do a "match selected" on the field, FALSE
11551  * otherwise.
11552  */
11553 gboolean
11554 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
11555 {
11556         return construct_match_selected_string(finfo, edt, NULL);
11557 }
11558
11559 /* This function attempts to construct a "match selected" display filter
11560  * string for the specified field; if it can do so, it returns a pointer
11561  * to the string, otherwise it returns NULL.
11562  *
11563  * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
11564  */
11565 char *
11566 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
11567 {
11568         char *filter = NULL;
11569
11570         if (!construct_match_selected_string(finfo, edt, &filter))
11571         {
11572                 wmem_free(NULL, filter);
11573                 return NULL;
11574         }
11575         return filter;
11576 }
11577
11578 /* This function is common code for all proto_tree_add_bitmask... functions.
11579  */
11580
11581 static gboolean
11582 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
11583                             const int len, const gint ett, int * const *fields,
11584                             const int flags, gboolean first,
11585                             gboolean use_parent_tree,
11586                             proto_tree* tree, guint64 value)
11587 {
11588         guint64            available_bits = G_MAXUINT64;
11589         guint64            bitmask = 0;
11590         guint64            tmpval;
11591         header_field_info *hf;
11592         guint32            integer32;
11593         gint               bit_offset;
11594         gint               no_of_bits;
11595
11596         if (!*fields)
11597                 REPORT_DISSECTOR_BUG("Illegal call of proto_item_add_bitmask_tree without fields");
11598
11599         if (len < 0 || len > 8)
11600                 REPORT_DISSECTOR_BUG("Invalid len: %d", len);
11601         /**
11602          * packet-frame.c uses len=0 since the value is taken from the packet
11603          * metadata, not the packet bytes. In that case, assume that all bits
11604          * in the provided value are valid.
11605          */
11606         if (len > 0) {
11607                 available_bits >>= (8 - (guint)len)*8;
11608         }
11609
11610         if (use_parent_tree == FALSE)
11611                 tree = proto_item_add_subtree(item, ett);
11612
11613         while (*fields) {
11614                 guint64 present_bits;
11615                 PROTO_REGISTRAR_GET_NTH(**fields,hf);
11616                 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
11617
11618                 bitmask |= hf->bitmask;
11619
11620                 /* Skip fields that aren't fully present */
11621                 present_bits = available_bits & hf->bitmask;
11622                 if (present_bits != hf->bitmask) {
11623                         fields++;
11624                         continue;
11625                 }
11626
11627                 switch (hf->type) {
11628                 case FT_CHAR:
11629                 case FT_UINT8:
11630                 case FT_UINT16:
11631                 case FT_UINT24:
11632                 case FT_UINT32:
11633                         proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
11634                         break;
11635
11636                 case FT_INT8:
11637                 case FT_INT16:
11638                 case FT_INT24:
11639                 case FT_INT32:
11640                         proto_tree_add_int(tree, **fields, tvb, offset, len, (gint32)value);
11641                         break;
11642
11643                 case FT_UINT40:
11644                 case FT_UINT48:
11645                 case FT_UINT56:
11646                 case FT_UINT64:
11647                         proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
11648                         break;
11649
11650                 case FT_INT40:
11651                 case FT_INT48:
11652                 case FT_INT56:
11653                 case FT_INT64:
11654                         proto_tree_add_int64(tree, **fields, tvb, offset, len, (gint64)value);
11655                         break;
11656
11657                 case FT_BOOLEAN:
11658                         proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
11659                         break;
11660
11661                 default:
11662                         REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
11663                                              hf->abbrev,
11664                                              hf->type,
11665                                              ftype_name(hf->type));
11666                         break;
11667                 }
11668                 if (flags & BMT_NO_APPEND) {
11669                         fields++;
11670                         continue;
11671                 }
11672                 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
11673
11674                 switch (hf->type) {
11675                 case FT_CHAR:
11676                         if (hf->display == BASE_CUSTOM) {
11677                                 gchar lbl[ITEM_LABEL_LENGTH];
11678                                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11679
11680                                 DISSECTOR_ASSERT(fmtfunc);
11681                                 fmtfunc(lbl, (guint32) tmpval);
11682                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11683                                                 hf->name, lbl);
11684                                 first = FALSE;
11685                         }
11686                         else if (hf->strings) {
11687                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11688                                                        hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
11689                                 first = FALSE;
11690                         }
11691                         else if (!(flags & BMT_NO_INT)) {
11692                                 char buf[32];
11693                                 const char *out;
11694
11695                                 if (!first) {
11696                                         proto_item_append_text(item, ", ");
11697                                 }
11698
11699                                 out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
11700                                 proto_item_append_text(item, "%s: %s", hf->name, out);
11701                                 first = FALSE;
11702                         }
11703
11704                         break;
11705
11706                 case FT_UINT8:
11707                 case FT_UINT16:
11708                 case FT_UINT24:
11709                 case FT_UINT32:
11710                         if (hf->display == BASE_CUSTOM) {
11711                                 gchar lbl[ITEM_LABEL_LENGTH];
11712                                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11713
11714                                 DISSECTOR_ASSERT(fmtfunc);
11715                                 fmtfunc(lbl, (guint32) tmpval);
11716                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11717                                                 hf->name, lbl);
11718                                 first = FALSE;
11719                         }
11720                         else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11721                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11722                                                                                 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
11723                                 first = FALSE;
11724                         }
11725                         else if (!(flags & BMT_NO_INT)) {
11726                                 char buf[32];
11727                                 const char *out;
11728
11729                                 if (!first) {
11730                                         proto_item_append_text(item, ", ");
11731                                 }
11732
11733                                 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
11734                                 if (hf->display & BASE_UNIT_STRING) {
11735                                         proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
11736                                 } else {
11737                                         proto_item_append_text(item, "%s: %s", hf->name, out);
11738                                 }
11739                                 first = FALSE;
11740                         }
11741
11742                         break;
11743
11744                 case FT_INT8:
11745                 case FT_INT16:
11746                 case FT_INT24:
11747                 case FT_INT32:
11748                         integer32 = (guint32) tmpval;
11749                         if (hf->bitmask) {
11750                                 no_of_bits = ws_count_ones(hf->bitmask);
11751                                 integer32 = ws_sign_ext32(integer32, no_of_bits);
11752                         }
11753                         if (hf->display == BASE_CUSTOM) {
11754                                 gchar lbl[ITEM_LABEL_LENGTH];
11755                                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11756
11757                                 DISSECTOR_ASSERT(fmtfunc);
11758                                 fmtfunc(lbl, (gint32) integer32);
11759                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11760                                                 hf->name, lbl);
11761                                 first = FALSE;
11762                         }
11763                         else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11764                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11765                                                 hf->name, hf_try_val_to_str_const((gint32) integer32, hf, "Unknown"));
11766                                 first = FALSE;
11767                         }
11768                         else if (!(flags & BMT_NO_INT)) {
11769                                 char buf[32];
11770                                 const char *out;
11771
11772                                 if (!first) {
11773                                         proto_item_append_text(item, ", ");
11774                                 }
11775
11776                                 out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
11777                                 if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11778                                         proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
11779                                 } else {
11780                                         proto_item_append_text(item, "%s: %s", hf->name, out);
11781                                 }
11782                                 first = FALSE;
11783                         }
11784
11785                         break;
11786
11787                 case FT_UINT40:
11788                 case FT_UINT48:
11789                 case FT_UINT56:
11790                 case FT_UINT64:
11791                         if (hf->display == BASE_CUSTOM) {
11792                                 gchar lbl[ITEM_LABEL_LENGTH];
11793                                 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
11794
11795                                 DISSECTOR_ASSERT(fmtfunc);
11796                                 fmtfunc(lbl, tmpval);
11797                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11798                                                 hf->name, lbl);
11799                                 first = FALSE;
11800                         }
11801                         else if (hf->strings) {
11802                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11803                                                 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
11804                                 first = FALSE;
11805                         }
11806                         else if (!(flags & BMT_NO_INT)) {
11807                                 char buf[48];
11808                                 const char *out;
11809
11810                                 if (!first) {
11811                                         proto_item_append_text(item, ", ");
11812                                 }
11813
11814                                 out = hfinfo_number_value_format64(hf, buf, tmpval);
11815                                 proto_item_append_text(item, "%s: %s", hf->name, out);
11816                                 first = FALSE;
11817                         }
11818
11819                         break;
11820
11821                 case FT_INT40:
11822                 case FT_INT48:
11823                 case FT_INT56:
11824                 case FT_INT64:
11825                         if (hf->bitmask) {
11826                                 no_of_bits = ws_count_ones(hf->bitmask);
11827                                 tmpval = ws_sign_ext64(tmpval, no_of_bits);
11828                         }
11829                         if (hf->display == BASE_CUSTOM) {
11830                                 gchar lbl[ITEM_LABEL_LENGTH];
11831                                 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
11832
11833                                 DISSECTOR_ASSERT(fmtfunc);
11834                                 fmtfunc(lbl, (gint64) tmpval);
11835                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11836                                                 hf->name, lbl);
11837                                 first = FALSE;
11838                         }
11839                         else if (hf->strings) {
11840                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11841                                                 hf->name, hf_try_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
11842                                 first = FALSE;
11843                         }
11844                         else if (!(flags & BMT_NO_INT)) {
11845                                 char buf[48];
11846                                 const char *out;
11847
11848                                 if (!first) {
11849                                         proto_item_append_text(item, ", ");
11850                                 }
11851
11852                                 out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
11853                                 proto_item_append_text(item, "%s: %s", hf->name, out);
11854                                 first = FALSE;
11855                         }
11856
11857                         break;
11858
11859                 case FT_BOOLEAN:
11860                         if (hf->strings && !(flags & BMT_NO_TFS)) {
11861                                 /* If we have true/false strings, emit full - otherwise messages
11862                                    might look weird */
11863                                 const struct true_false_string *tfs =
11864                                         (const struct true_false_string *)hf->strings;
11865
11866                                 if (tmpval) {
11867                                         proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11868                                                         hf->name, tfs->true_string);
11869                                         first = FALSE;
11870                                 } else if (!(flags & BMT_NO_FALSE)) {
11871                                         proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11872                                                         hf->name, tfs->false_string);
11873                                         first = FALSE;
11874                                 }
11875                         } else if (hf->bitmask & value) {
11876                                 /* If the flag is set, show the name */
11877                                 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
11878                                 first = FALSE;
11879                         }
11880                         break;
11881                 default:
11882                         REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
11883                                              hf->abbrev,
11884                                              hf->type,
11885                                              ftype_name(hf->type));
11886                         break;
11887                 }
11888
11889                 fields++;
11890         }
11891
11892         /* XXX: We don't pass the hfi into this function. Perhaps we should,
11893          * but then again most dissectors don't set the bitmask field for
11894          * the higher level bitmask hfi, so calculate the bitmask from the
11895          * fields present. */
11896         if (item) {
11897                 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
11898                 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
11899                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
11900                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
11901         }
11902         return first;
11903 }
11904
11905 /* This function will dissect a sequence of bytes that describe a
11906  * bitmask and supply the value of that sequence through a pointer.
11907  * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
11908  * to be dissected.
11909  * This field will form an expansion under which the individual fields of the
11910  * bitmask is dissected and displayed.
11911  * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
11912  *
11913  * fields is an array of pointers to int that lists all the fields of the
11914  * bitmask. These fields can be either of the type FT_BOOLEAN for flags
11915  * or another integer of the same type/size as hf_hdr with a mask specified.
11916  * This array is terminated by a NULL entry.
11917  *
11918  * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
11919  * FT_integer fields that have a value_string attached will have the
11920  * matched string displayed on the expansion line.
11921  */
11922 proto_item *
11923 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
11924                        const guint offset, const int hf_hdr,
11925                        const gint ett, int * const *fields,
11926                        const guint encoding, guint64 *retval)
11927 {
11928         return proto_tree_add_bitmask_with_flags_ret_uint64(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, retval);
11929 }
11930
11931 /* This function will dissect a sequence of bytes that describe a
11932  * bitmask.
11933  * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
11934  * to be dissected.
11935  * This field will form an expansion under which the individual fields of the
11936  * bitmask is dissected and displayed.
11937  * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
11938  *
11939  * fields is an array of pointers to int that lists all the fields of the
11940  * bitmask. These fields can be either of the type FT_BOOLEAN for flags
11941  * or another integer of the same type/size as hf_hdr with a mask specified.
11942  * This array is terminated by a NULL entry.
11943  *
11944  * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
11945  * FT_integer fields that have a value_string attached will have the
11946  * matched string displayed on the expansion line.
11947  */
11948 proto_item *
11949 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
11950                        const guint offset, const int hf_hdr,
11951                        const gint ett, int * const *fields,
11952                        const guint encoding)
11953 {
11954         return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
11955 }
11956
11957 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
11958  * what data is appended to the header.
11959  */
11960 proto_item *
11961 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11962                 const int hf_hdr, const gint ett, int * const *fields, const guint encoding, const int flags,
11963                 guint64 *retval)
11964 {
11965         proto_item        *item = NULL;
11966         header_field_info *hf;
11967         int                len;
11968         guint64            value;
11969
11970         PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
11971         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
11972         len = ftype_length(hf->type);
11973         value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
11974
11975         if (parent_tree) {
11976                 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
11977                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
11978                     flags, FALSE, FALSE, NULL, value);
11979         }
11980
11981         *retval = value;
11982         if (hf->bitmask) {
11983                 /* Mask out irrelevant portions */
11984                 *retval &= hf->bitmask;
11985                 /* Shift bits */
11986                 *retval >>= hfinfo_bitshift(hf);
11987         }
11988
11989         return item;
11990 }
11991
11992 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
11993  * what data is appended to the header.
11994  */
11995 proto_item *
11996 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11997                 const int hf_hdr, const gint ett, int * const *fields, const guint encoding, const int flags)
11998 {
11999         proto_item        *item = NULL;
12000         header_field_info *hf;
12001         int                len;
12002         guint64            value;
12003
12004         PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
12005         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
12006
12007         if (parent_tree) {
12008                 len = ftype_length(hf->type);
12009                 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12010                 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12011                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12012                     flags, FALSE, FALSE, NULL, value);
12013         }
12014
12015         return item;
12016 }
12017
12018 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
12019    can't be retrieved directly from tvb) */
12020 proto_item *
12021 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
12022                 const int hf_hdr, const gint ett, int * const *fields, const guint64 value)
12023 {
12024         return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
12025                                                 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
12026 }
12027
12028 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
12029 WS_DLL_PUBLIC proto_item *
12030 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
12031                 const int hf_hdr, const gint ett, int * const *fields, const guint64 value, const int flags)
12032 {
12033         proto_item        *item = NULL;
12034         header_field_info *hf;
12035         int                len;
12036
12037         PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
12038         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
12039         /* the proto_tree_add_uint/_uint64() calls below
12040            will fail if tvb==NULL and len!=0 */
12041         len = tvb ? ftype_length(hf->type) : 0;
12042
12043         if (parent_tree) {
12044                 if (len <= 4)
12045                         item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
12046                 else
12047                         item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
12048
12049                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12050                     flags, FALSE, FALSE, NULL, value);
12051         }
12052
12053         return item;
12054 }
12055
12056 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
12057 void
12058 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
12059                                                                 const int len, int * const *fields, const guint encoding)
12060 {
12061         guint64 value;
12062
12063         if (tree) {
12064                 value = get_uint64_value(tree, tvb, offset, len, encoding);
12065                 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
12066                     BMT_NO_APPEND, FALSE, TRUE, tree, value);
12067         }
12068 }
12069
12070 WS_DLL_PUBLIC void
12071 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
12072                                                                 const int len, int * const *fields, const guint64 value)
12073 {
12074         if (tree) {
12075                 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
12076                     BMT_NO_APPEND, FALSE, TRUE, tree, value);
12077         }
12078 }
12079
12080
12081 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
12082  * This is intended to support bitmask fields whose lengths can vary, perhaps
12083  * as the underlying standard evolves over time.
12084  * With this API there is the possibility of being called to display more or
12085  * less data than the dissector was coded to support.
12086  * In such cases, it is assumed that bitmasks are extended on the MSb end.
12087  * Thus when presented with "too much" or "too little" data, MSbits will be
12088  * ignored or MSfields sacrificed.
12089  *
12090  * Only fields for which all defined bits are available are displayed.
12091  */
12092 proto_item *
12093 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
12094                        const guint offset,  const guint len, const int hf_hdr,
12095                        const gint ett, int * const *fields, struct expert_field* exp,
12096                        const guint encoding)
12097 {
12098         proto_item        *item = NULL;
12099         header_field_info *hf;
12100         guint   decodable_len;
12101         guint   decodable_offset;
12102         guint32 decodable_value;
12103         guint64 value;
12104
12105         PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
12106         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
12107
12108         decodable_offset = offset;
12109         decodable_len = MIN(len, (guint) ftype_length(hf->type));
12110
12111         /* If we are ftype_length-limited,
12112          * make sure we decode as many LSBs as possible.
12113          */
12114         if (encoding == ENC_BIG_ENDIAN) {
12115                 decodable_offset += (len - decodable_len);
12116         }
12117
12118         if (parent_tree) {
12119                 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
12120                                                  decodable_len, encoding);
12121
12122                 /* The root item covers all the bytes even if we can't decode them all */
12123                 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
12124                                            decodable_value);
12125         }
12126
12127         if (decodable_len < len) {
12128                 /* Dissector likely requires updating for new protocol revision */
12129                 expert_add_info_format(NULL, item, exp,
12130                                        "Only least-significant %d of %d bytes decoded",
12131                                        decodable_len, len);
12132         }
12133
12134         if (item) {
12135                 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
12136                 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
12137                     ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
12138         }
12139
12140         return item;
12141 }
12142
12143 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
12144 proto_item *
12145 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
12146                             const guint offset, const guint len,
12147                             const char *name, const char *fallback,
12148                             const gint ett, int * const *fields,
12149                             const guint encoding, const int flags)
12150 {
12151         proto_item *item = NULL;
12152         guint64     value;
12153
12154         if (parent_tree) {
12155                 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
12156                 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12157                 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12158                     flags, TRUE, FALSE, NULL, value) && fallback) {
12159                         /* Still at first item - append 'fallback' text if any */
12160                         proto_item_append_text(item, "%s", fallback);
12161                 }
12162         }
12163
12164         return item;
12165 }
12166
12167 proto_item *
12168 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12169                          const guint bit_offset, const gint no_of_bits,
12170                          const guint encoding)
12171 {
12172         header_field_info *hfinfo;
12173         gint               octet_length;
12174         gint               octet_offset;
12175
12176         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
12177
12178         octet_length = (no_of_bits + 7) >> 3;
12179         octet_offset = bit_offset >> 3;
12180         test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
12181
12182         /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
12183          * but only after doing a bunch more work (which we can, in the common
12184          * case, shortcut here).
12185          */
12186         CHECK_FOR_NULL_TREE(tree);
12187         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12188
12189         return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
12190 }
12191
12192 /*
12193  * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
12194  * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
12195  * Offset should be given in bits from the start of the tvb.
12196  */
12197
12198 static proto_item *
12199 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12200                             const guint bit_offset, const gint no_of_bits,
12201                             guint64 *return_value, const guint encoding)
12202 {
12203         gint     offset;
12204         guint    length;
12205         guint8   tot_no_bits;
12206         char    *bf_str;
12207         char     lbl_str[ITEM_LABEL_LENGTH];
12208         guint64  value = 0;
12209         guint8  *bytes = NULL;
12210         size_t bytes_length = 0;
12211
12212         proto_item        *pi;
12213         header_field_info *hf_field;
12214
12215         const true_false_string *tfstring;
12216
12217         /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
12218         PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
12219
12220         if (hf_field->bitmask != 0) {
12221                 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_ret_val"
12222                                      " with field '%s' (%s) with bitmask != 0",
12223                                      hf_field->abbrev, hf_field->name);
12224         }
12225
12226         if (no_of_bits == 0) {
12227                 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0",
12228                                      hf_field->abbrev);
12229         }
12230
12231         /* Byte align offset */
12232         offset = bit_offset>>3;
12233
12234         /*
12235          * Calculate the number of octets used to hold the bits
12236          */
12237         tot_no_bits = ((bit_offset&0x7) + no_of_bits);
12238         length = (tot_no_bits + 7) >> 3;
12239
12240         if (no_of_bits < 65) {
12241                 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
12242         } else if (hf_field->type != FT_BYTES) {
12243                 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 65",
12244                                      hf_field->abbrev, no_of_bits);
12245                 return NULL;
12246         }
12247
12248         /* Sign extend for signed types */
12249         switch (hf_field->type) {
12250                 case FT_INT8:
12251                 case FT_INT16:
12252                 case FT_INT24:
12253                 case FT_INT32:
12254                 case FT_INT40:
12255                 case FT_INT48:
12256                 case FT_INT56:
12257                 case FT_INT64:
12258                         value = ws_sign_ext64(value, no_of_bits);
12259                         break;
12260
12261                 default:
12262                         break;
12263         }
12264
12265         if (return_value) {
12266                 *return_value = value;
12267         }
12268
12269         /* Coast clear. Try and fake it */
12270         CHECK_FOR_NULL_TREE(tree);
12271         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12272
12273         bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
12274
12275         switch (hf_field->type) {
12276         case FT_BOOLEAN:
12277                 /* Boolean field */
12278                 tfstring = &tfs_true_false;
12279                 if (hf_field->strings)
12280                         tfstring = (const true_false_string *)hf_field->strings;
12281                 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
12282                         "%s = %s: %s",
12283                         bf_str, hf_field->name, tfs_get_string(!!value, tfstring));
12284                 break;
12285
12286         case FT_CHAR:
12287                 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
12288                 fill_label_char(PITEM_FINFO(pi), lbl_str);
12289                 break;
12290
12291         case FT_UINT8:
12292         case FT_UINT16:
12293         case FT_UINT24:
12294         case FT_UINT32:
12295                 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
12296                 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
12297                 break;
12298
12299         case FT_INT8:
12300         case FT_INT16:
12301         case FT_INT24:
12302         case FT_INT32:
12303                 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
12304                 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
12305                 break;
12306
12307         case FT_UINT40:
12308         case FT_UINT48:
12309         case FT_UINT56:
12310         case FT_UINT64:
12311                 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
12312                 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
12313                 break;
12314
12315         case FT_INT40:
12316         case FT_INT48:
12317         case FT_INT56:
12318         case FT_INT64:
12319                 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
12320                 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
12321                 break;
12322
12323         case FT_BYTES:
12324                 bytes = tvb_get_bits_array(wmem_packet_scope(), tvb, bit_offset, no_of_bits, &bytes_length);
12325                 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (gint) bytes_length);
12326                 proto_item_fill_label(PITEM_FINFO(pi), lbl_str);
12327                 proto_item_set_text(pi, "%s", lbl_str);
12328                 return pi;
12329                 break;
12330
12331         default:
12332                 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()",
12333                                      hf_field->abbrev,
12334                                      hf_field->type,
12335                                      ftype_name(hf_field->type));
12336                 return NULL;
12337                 break;
12338         }
12339
12340         proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
12341         return pi;
12342 }
12343
12344 proto_item *
12345 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12346                                        const guint bit_offset, const crumb_spec_t *crumb_spec,
12347                                        guint64 *return_value)
12348 {
12349         proto_item *pi;
12350         gint        no_of_bits;
12351         gint        octet_offset;
12352         guint       mask_initial_bit_offset;
12353         guint       mask_greatest_bit_offset;
12354         guint       octet_length;
12355         guint8      i;
12356         char        bf_str[256];
12357         char        lbl_str[ITEM_LABEL_LENGTH];
12358         guint64     value;
12359         guint64     composite_bitmask;
12360         guint64     composite_bitmap;
12361
12362         header_field_info       *hf_field;
12363         const true_false_string *tfstring;
12364
12365         /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
12366         PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
12367
12368         if (hf_field->bitmask != 0) {
12369                 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_split_bits_item_ret_val"
12370                                      " with field '%s' (%s) with bitmask != 0",
12371                                      hf_field->abbrev, hf_field->name);
12372         }
12373
12374         mask_initial_bit_offset = bit_offset % 8;
12375
12376         no_of_bits = 0;
12377         value      = 0;
12378         i          = 0;
12379         mask_greatest_bit_offset = 0;
12380         composite_bitmask        = 0;
12381         composite_bitmap         = 0;
12382
12383         while (crumb_spec[i].crumb_bit_length != 0) {
12384                 guint64 crumb_mask, crumb_value;
12385                 guint8  crumb_end_bit_offset;
12386
12387                 crumb_value = tvb_get_bits64(tvb,
12388                                              bit_offset + crumb_spec[i].crumb_bit_offset,
12389                                              crumb_spec[i].crumb_bit_length,
12390                                              ENC_BIG_ENDIAN);
12391                 value      += crumb_value;
12392                 no_of_bits += crumb_spec[i].crumb_bit_length;
12393                 DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "a value larger than 64 bits cannot be represented");
12394
12395                 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
12396                    octet containing the initial offset.
12397                    If the mask is beyond 32 bits, then give up on bit map display.
12398                    This could be improved in future, probably showing a table
12399                    of 32 or 64 bits per row */
12400                 if (mask_greatest_bit_offset < 32) {
12401                         crumb_end_bit_offset = mask_initial_bit_offset
12402                                 + crumb_spec[i].crumb_bit_offset
12403                                 + crumb_spec[i].crumb_bit_length;
12404                         crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
12405
12406                         if (crumb_end_bit_offset > mask_greatest_bit_offset) {
12407                                 mask_greatest_bit_offset = crumb_end_bit_offset;
12408                         }
12409                         /* Currently the bitmap of the crumbs are only shown if
12410                          * smaller than 32 bits. Do not bother calculating the
12411                          * mask if it is larger than that. */
12412                         if (crumb_end_bit_offset <= 32) {
12413                                 composite_bitmask |= (crumb_mask  << (64 - crumb_end_bit_offset));
12414                                 composite_bitmap  |= (crumb_value << (64 - crumb_end_bit_offset));
12415                         }
12416                 }
12417                 /* Shift left for the next segment */
12418                 value <<= crumb_spec[++i].crumb_bit_length;
12419         }
12420
12421         /* Sign extend for signed types */
12422         switch (hf_field->type) {
12423                 case FT_INT8:
12424                 case FT_INT16:
12425                 case FT_INT24:
12426                 case FT_INT32:
12427                 case FT_INT40:
12428                 case FT_INT48:
12429                 case FT_INT56:
12430                 case FT_INT64:
12431                         value = ws_sign_ext64(value, no_of_bits);
12432                         break;
12433                 default:
12434                         break;
12435         }
12436
12437         if (return_value) {
12438                 *return_value = value;
12439         }
12440
12441         /* Coast clear. Try and fake it */
12442         CHECK_FOR_NULL_TREE(tree);
12443         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12444
12445         /* initialise the format string */
12446         bf_str[0] = '\0';
12447
12448         octet_offset = bit_offset >> 3;
12449
12450         /* Round up mask length to nearest octet */
12451         octet_length = ((mask_greatest_bit_offset + 7) >> 3);
12452         mask_greatest_bit_offset = octet_length << 3;
12453
12454         /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
12455            It would be a useful enhancement to eliminate this restriction. */
12456         if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
12457                 other_decode_bitfield_value(bf_str,
12458                                             (guint32)(composite_bitmap  >> (64 - mask_greatest_bit_offset)),
12459                                             (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
12460                                             mask_greatest_bit_offset);
12461         } else {
12462                 /* If the bitmask is too large, try to describe its contents. */
12463                 g_snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
12464         }
12465
12466         switch (hf_field->type) {
12467         case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
12468                 /* Boolean field */
12469                 tfstring = &tfs_true_false;
12470                 if (hf_field->strings)
12471                         tfstring = (const true_false_string *) hf_field->strings;
12472                 return proto_tree_add_boolean_format(tree, hfindex,
12473                                                      tvb, octet_offset, octet_length, (guint32)value,
12474                                                      "%s = %s: %s",
12475                                                      bf_str, hf_field->name, tfs_get_string(!!value, tfstring));
12476                 break;
12477
12478         case FT_CHAR:
12479                 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
12480                 fill_label_char(PITEM_FINFO(pi), lbl_str);
12481                 break;
12482
12483         case FT_UINT8:
12484         case FT_UINT16:
12485         case FT_UINT24:
12486         case FT_UINT32:
12487                 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
12488                 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
12489                 break;
12490
12491         case FT_INT8:
12492         case FT_INT16:
12493         case FT_INT24:
12494         case FT_INT32:
12495                 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
12496                 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
12497                 break;
12498
12499         case FT_UINT40:
12500         case FT_UINT48:
12501         case FT_UINT56:
12502         case FT_UINT64:
12503                 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
12504                 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
12505                 break;
12506
12507         case FT_INT40:
12508         case FT_INT48:
12509         case FT_INT56:
12510         case FT_INT64:
12511                 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
12512                 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
12513                 break;
12514
12515         default:
12516                 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()",
12517                                      hf_field->abbrev,
12518                                      hf_field->type,
12519                                      ftype_name(hf_field->type));
12520                 return NULL;
12521                 break;
12522         }
12523         proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
12524         return pi;
12525 }
12526
12527 void
12528 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
12529                                 const crumb_spec_t *crumb_spec, guint16 crumb_index)
12530 {
12531         header_field_info *hfinfo;
12532
12533         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
12534         proto_tree_add_text_internal(tree, tvb,
12535                             bit_offset >> 3,
12536                             ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
12537                             "%s crumb %d of %s (decoded above)",
12538                             decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
12539                                                  tvb_get_bits(tvb,
12540                                                               bit_offset,
12541                                                               crumb_spec[crumb_index].crumb_bit_length,
12542                                                               ENC_BIG_ENDIAN)),
12543                             crumb_index,
12544                             hfinfo->name);
12545 }
12546
12547 proto_item *
12548 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12549                             const guint bit_offset, const gint no_of_bits,
12550                             guint64 *return_value, const guint encoding)
12551 {
12552         proto_item *item;
12553
12554         if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
12555                                                  bit_offset, no_of_bits,
12556                                                  return_value, encoding))) {
12557                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
12558                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
12559         }
12560         return item;
12561 }
12562
12563 static proto_item *
12564 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
12565                                  tvbuff_t *tvb, const guint bit_offset,
12566                                  const gint no_of_bits, void *value_ptr,
12567                                  gchar *value_str)
12568 {
12569         gint     offset;
12570         guint    length;
12571         guint8   tot_no_bits;
12572         char    *str;
12573         guint64  value = 0;
12574         header_field_info *hf_field;
12575
12576         /* We do not have to return a value, try to fake it as soon as possible */
12577         CHECK_FOR_NULL_TREE(tree);
12578         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12579
12580         if (hf_field->bitmask != 0) {
12581                 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_format_value"
12582                                      " with field '%s' (%s) with bitmask != 0",
12583                                      hf_field->abbrev, hf_field->name);
12584         }
12585
12586         if (no_of_bits == 0) {
12587                 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0",
12588                                      hf_field->abbrev);
12589         }
12590
12591         /* Byte align offset */
12592         offset = bit_offset>>3;
12593
12594         /*
12595          * Calculate the number of octets used to hold the bits
12596          */
12597         tot_no_bits = ((bit_offset&0x7) + no_of_bits);
12598         length      = tot_no_bits>>3;
12599         /* If we are using part of the next octet, increase length by 1 */
12600         if (tot_no_bits & 0x07)
12601                 length++;
12602
12603         if (no_of_bits < 65) {
12604                 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
12605         } else {
12606                 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65",
12607                                      hf_field->abbrev, no_of_bits);
12608                 return NULL;
12609         }
12610
12611         str = decode_bits_in_field(bit_offset, no_of_bits, value);
12612
12613         (void) g_strlcat(str, " = ", 256+64);
12614         (void) g_strlcat(str, hf_field->name, 256+64);
12615
12616         /*
12617          * This function does not receive an actual value but a dimensionless pointer to that value.
12618          * For this reason, the type of the header field is examined in order to determine
12619          * what kind of value we should read from this address.
12620          * The caller of this function must make sure that for the specific header field type the address of
12621          * a compatible value is provided.
12622          */
12623         switch (hf_field->type) {
12624         case FT_BOOLEAN:
12625                 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
12626                                                      "%s: %s", str, value_str);
12627                 break;
12628
12629         case FT_CHAR:
12630         case FT_UINT8:
12631         case FT_UINT16:
12632         case FT_UINT24:
12633         case FT_UINT32:
12634                 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
12635                                                   "%s: %s", str, value_str);
12636                 break;
12637
12638         case FT_UINT40:
12639         case FT_UINT48:
12640         case FT_UINT56:
12641         case FT_UINT64:
12642                 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
12643                                                     "%s: %s", str, value_str);
12644                 break;
12645
12646         case FT_INT8:
12647         case FT_INT16:
12648         case FT_INT24:
12649         case FT_INT32:
12650                 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
12651                                                  "%s: %s", str, value_str);
12652                 break;
12653
12654         case FT_INT40:
12655         case FT_INT48:
12656         case FT_INT56:
12657         case FT_INT64:
12658                 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
12659                                                    "%s: %s", str, value_str);
12660                 break;
12661
12662         case FT_FLOAT:
12663                 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
12664                                                    "%s: %s", str, value_str);
12665                 break;
12666
12667         default:
12668                 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()",
12669                                      hf_field->abbrev,
12670                                      hf_field->type,
12671                                      ftype_name(hf_field->type));
12672                 return NULL;
12673                 break;
12674         }
12675 }
12676
12677 static proto_item *
12678 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
12679                                  tvbuff_t *tvb, const guint bit_offset,
12680                                  const gint no_of_bits, void *value_ptr,
12681                                  gchar *value_str)
12682 {
12683         proto_item *item;
12684
12685         if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
12686                                                       tvb, bit_offset, no_of_bits,
12687                                                       value_ptr, value_str))) {
12688                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
12689                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
12690         }
12691         return item;
12692 }
12693
12694 #define CREATE_VALUE_STRING(dst,format,ap) \
12695         va_start(ap, format); \
12696         dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
12697         va_end(ap);
12698
12699 proto_item *
12700 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
12701                                       tvbuff_t *tvb, const guint bit_offset,
12702                                       const gint no_of_bits, guint32 value,
12703                                       const char *format, ...)
12704 {
12705         va_list ap;
12706         gchar  *dst;
12707         header_field_info *hf_field;
12708
12709         CHECK_FOR_NULL_TREE(tree);
12710
12711         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12712
12713         switch (hf_field->type) {
12714                 case FT_UINT8:
12715                 case FT_UINT16:
12716                 case FT_UINT24:
12717                 case FT_UINT32:
12718                         break;
12719
12720                 default:
12721                         REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
12722                             hf_field->abbrev);
12723                         return NULL;
12724                         break;
12725         }
12726
12727         CREATE_VALUE_STRING(dst, format, ap);
12728
12729         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12730 }
12731
12732 proto_item *
12733 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
12734                                       tvbuff_t *tvb, const guint bit_offset,
12735                                       const gint no_of_bits, guint64 value,
12736                                       const char *format, ...)
12737 {
12738         va_list ap;
12739         gchar  *dst;
12740         header_field_info *hf_field;
12741
12742         CHECK_FOR_NULL_TREE(tree);
12743
12744         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12745
12746         switch (hf_field->type) {
12747                 case FT_UINT40:
12748                 case FT_UINT48:
12749                 case FT_UINT56:
12750                 case FT_UINT64:
12751                         break;
12752
12753                 default:
12754                         REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
12755                             hf_field->abbrev);
12756                         return NULL;
12757                         break;
12758         }
12759
12760         CREATE_VALUE_STRING(dst, format, ap);
12761
12762         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12763 }
12764
12765 proto_item *
12766 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
12767                                        tvbuff_t *tvb, const guint bit_offset,
12768                                        const gint no_of_bits, float value,
12769                                        const char *format, ...)
12770 {
12771         va_list ap;
12772         gchar  *dst;
12773         header_field_info *hf_field;
12774
12775         CHECK_FOR_NULL_TREE(tree);
12776
12777         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12778
12779         DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
12780
12781         CREATE_VALUE_STRING(dst, format, ap);
12782
12783         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12784 }
12785
12786 proto_item *
12787 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
12788                                      tvbuff_t *tvb, const guint bit_offset,
12789                                      const gint no_of_bits, gint32 value,
12790                                      const char *format, ...)
12791 {
12792         va_list ap;
12793         gchar  *dst;
12794         header_field_info *hf_field;
12795
12796         CHECK_FOR_NULL_TREE(tree);
12797
12798         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12799
12800         switch (hf_field->type) {
12801                 case FT_INT8:
12802                 case FT_INT16:
12803                 case FT_INT24:
12804                 case FT_INT32:
12805                         break;
12806
12807                 default:
12808                         REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
12809                             hf_field->abbrev);
12810                         return NULL;
12811                         break;
12812         }
12813
12814         CREATE_VALUE_STRING(dst, format, ap);
12815
12816         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12817 }
12818
12819 proto_item *
12820 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
12821                                      tvbuff_t *tvb, const guint bit_offset,
12822                                      const gint no_of_bits, gint64 value,
12823                                      const char *format, ...)
12824 {
12825         va_list ap;
12826         gchar  *dst;
12827         header_field_info *hf_field;
12828
12829         CHECK_FOR_NULL_TREE(tree);
12830
12831         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12832
12833         switch (hf_field->type) {
12834                 case FT_INT40:
12835                 case FT_INT48:
12836                 case FT_INT56:
12837                 case FT_INT64:
12838                         break;
12839
12840                 default:
12841                         REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
12842                             hf_field->abbrev);
12843                         return NULL;
12844                         break;
12845         }
12846
12847         CREATE_VALUE_STRING(dst, format, ap);
12848
12849         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12850 }
12851
12852 proto_item *
12853 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
12854                                          tvbuff_t *tvb, const guint bit_offset,
12855                                          const gint no_of_bits, guint32 value,
12856                                          const char *format, ...)
12857 {
12858         va_list ap;
12859         gchar  *dst;
12860         header_field_info *hf_field;
12861
12862         CHECK_FOR_NULL_TREE(tree);
12863
12864         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12865
12866         DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
12867
12868         CREATE_VALUE_STRING(dst, format, ap);
12869
12870         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12871 }
12872
12873 proto_item *
12874 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
12875                                          tvbuff_t *tvb, const guint bit_offset,
12876                                          const gint no_of_bits, guint64 value,
12877                                          const char *format, ...)
12878 {
12879         va_list ap;
12880         gchar  *dst;
12881         header_field_info *hf_field;
12882
12883         CHECK_FOR_NULL_TREE(tree);
12884
12885         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12886
12887         DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
12888
12889         CREATE_VALUE_STRING(dst, format, ap);
12890
12891         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12892 }
12893
12894 proto_item *
12895 proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12896         const guint bit_offset, const gint no_of_chars)
12897 {
12898         proto_item        *pi;
12899         header_field_info *hfinfo;
12900         gint               byte_length;
12901         gint               byte_offset;
12902         gchar             *string;
12903
12904         CHECK_FOR_NULL_TREE(tree);
12905
12906         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12907
12908         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
12909
12910         byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
12911         byte_offset = bit_offset >> 3;
12912
12913         string = tvb_get_ts_23_038_7bits_string_packed(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
12914
12915         if (hfinfo->display == STR_UNICODE) {
12916                 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
12917         }
12918
12919         pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
12920         DISSECTOR_ASSERT(byte_length >= 0);
12921         proto_tree_set_string(PNODE_FINFO(pi), string);
12922
12923         return pi;
12924 }
12925
12926 proto_item *
12927 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12928         const guint bit_offset, const gint no_of_chars)
12929 {
12930         proto_item        *pi;
12931         header_field_info *hfinfo;
12932         gint               byte_length;
12933         gint               byte_offset;
12934         gchar             *string;
12935
12936         CHECK_FOR_NULL_TREE(tree);
12937
12938         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12939
12940         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
12941
12942         byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
12943         byte_offset = bit_offset >> 3;
12944
12945         string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
12946
12947         if (hfinfo->display == STR_UNICODE) {
12948                 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
12949         }
12950
12951         pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
12952         DISSECTOR_ASSERT(byte_length >= 0);
12953         proto_tree_set_string(PNODE_FINFO(pi), string);
12954
12955         return pi;
12956 }
12957
12958 const value_string proto_checksum_vals[] = {
12959         { PROTO_CHECKSUM_E_BAD,        "Bad"  },
12960         { PROTO_CHECKSUM_E_GOOD,       "Good" },
12961         { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
12962         { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
12963         { PROTO_CHECKSUM_E_ILLEGAL,    "Illegal" },
12964
12965         { 0,        NULL }
12966 };
12967
12968 proto_item *
12969 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
12970                 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
12971                 packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
12972 {
12973         header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
12974         guint32 checksum;
12975         guint32 len;
12976         proto_item* ti = NULL;
12977         proto_item* ti2;
12978         gboolean incorrect_checksum = TRUE;
12979
12980         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
12981
12982         switch (hfinfo->type) {
12983         case FT_UINT8:
12984                 len = 1;
12985                 break;
12986         case FT_UINT16:
12987                 len = 2;
12988                 break;
12989         case FT_UINT24:
12990                 len = 3;
12991                 break;
12992         case FT_UINT32:
12993                 len = 4;
12994                 break;
12995         default:
12996                 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
12997                     hfinfo->abbrev);
12998         }
12999
13000         if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
13001                 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
13002                 proto_item_set_generated(ti);
13003                 if (hf_checksum_status != -1) {
13004                         ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
13005                         proto_item_set_generated(ti2);
13006                 }
13007                 return ti;
13008         }
13009
13010         if (flags & PROTO_CHECKSUM_GENERATED) {
13011                 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
13012                 proto_item_set_generated(ti);
13013         } else {
13014                 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
13015                 if (flags & PROTO_CHECKSUM_VERIFY) {
13016                         if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
13017                                 if (computed_checksum == 0) {
13018                                         proto_item_append_text(ti, " [correct]");
13019                                         if (hf_checksum_status != -1) {
13020                                                 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13021                                                 proto_item_set_generated(ti2);
13022                                         }
13023                                         incorrect_checksum = FALSE;
13024                                 } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
13025                                         computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
13026                                 }
13027                         } else {
13028                                 if (checksum == computed_checksum) {
13029                                         proto_item_append_text(ti, " [correct]");
13030                                         if (hf_checksum_status != -1) {
13031                                                 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13032                                                 proto_item_set_generated(ti2);
13033                                         }
13034                                         incorrect_checksum = FALSE;
13035                                 }
13036                         }
13037
13038                         if (incorrect_checksum) {
13039                                 if (hf_checksum_status != -1) {
13040                                         ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
13041                                         proto_item_set_generated(ti2);
13042                                 }
13043                                 if (flags & PROTO_CHECKSUM_ZERO) {
13044                                         proto_item_append_text(ti, " [incorrect]");
13045                                         if (bad_checksum_expert != NULL)
13046                                                 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
13047                                 } else {
13048                                         proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
13049                                         if (bad_checksum_expert != NULL)
13050                                                 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%0*x]", expert_get_summary(bad_checksum_expert), len * 2, computed_checksum);
13051                                 }
13052                         }
13053                 } else {
13054                         if (hf_checksum_status != -1) {
13055                                 proto_item_append_text(ti, " [unverified]");
13056                                 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
13057                                 proto_item_set_generated(ti2);
13058                         }
13059                 }
13060         }
13061
13062         return ti;
13063 }
13064
13065 guchar
13066 proto_check_field_name(const gchar *field_name)
13067 {
13068         const char *p = field_name;
13069         guchar c = '.', lastc;
13070
13071         do {
13072                 lastc = c;
13073                 c = *(p++);
13074                 /* Leading '.' or substring ".." are disallowed. */
13075                 if (c == '.' && lastc == '.') {
13076                         break;
13077                 }
13078         } while (fld_abbrev_chars[c]);
13079
13080         /* Trailing '.' is disallowed. */
13081         if (lastc == '.') {
13082                 return '.';
13083         }
13084         return c;
13085 }
13086
13087 gboolean
13088 tree_expanded(int tree_type)
13089 {
13090         if (tree_type == -1) {
13091                 return FALSE;
13092         }
13093         g_assert(tree_type >= 0 && tree_type < num_tree_types);
13094         return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
13095 }
13096
13097 void
13098 tree_expanded_set(int tree_type, gboolean value)
13099 {
13100         g_assert(tree_type >= 0 && tree_type < num_tree_types);
13101
13102         if (value)
13103                 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
13104         else
13105                 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
13106 }
13107
13108 /*
13109  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
13110  *
13111  * Local variables:
13112  * c-basic-offset: 8
13113  * tab-width: 8
13114  * indent-tabs-mode: t
13115  * End:
13116  *
13117  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
13118  * :indentSize=8:tabSize=8:noTabs=false:
13119  */