c31f3d095eabddbdd4b6251fb814566f73a28af3
[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
13 #include <stdio.h>
14 #include <string.h>
15 #include <glib.h>
16 #include <float.h>
17 #include <errno.h>
18
19 #include <wsutil/bits_ctz.h>
20 #include <wsutil/bits_count_ones.h>
21 #include <wsutil/sign_ext.h>
22 #include <wsutil/utf8_entities.h>
23
24 #include <ftypes/ftypes-int.h>
25
26 #include "packet.h"
27 #include "exceptions.h"
28 #include "ptvcursor.h"
29 #include "strutil.h"
30 #include "addr_resolv.h"
31 #include "address_types.h"
32 #include "oids.h"
33 #include "proto.h"
34 #include "epan_dissect.h"
35 #include "tvbuff.h"
36 #include "wmem/wmem.h"
37 #include "charsets.h"
38 #include "column-utils.h"
39 #include "to_str-int.h"
40 #include "to_str.h"
41 #include "osi-utils.h"
42 #include "expert.h"
43 #include "show_exception.h"
44 #include "in_cksum.h"
45 #include "register-int.h"
46
47 #include <wsutil/ws_printf.h> /* ws_debug_printf */
48 #include <wsutil/crash_info.h>
49
50 #ifdef HAVE_JSONGLIB
51 #include <json-glib/json-glib.h>
52 #endif
53
54 /* Ptvcursor limits */
55 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
56 #define SUBTREE_MAX_LEVELS 256
57
58 /* Throw an exception if our tree exceeds these. */
59 /* XXX - These should probably be preferences */
60 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
61 #define MAX_TREE_LEVELS (5 * 100)
62
63 typedef struct __subtree_lvl {
64         gint        cursor_offset;
65         proto_item *it;
66         proto_tree *tree;
67 } subtree_lvl;
68
69 struct ptvcursor {
70         subtree_lvl *pushed_tree;
71         guint8       pushed_tree_index;
72         guint8       pushed_tree_max;
73         proto_tree  *tree;
74         tvbuff_t    *tvb;
75         gint         offset;
76 };
77
78 #define cVALS(x) (const value_string*)(x)
79
80 /** See inlined comments.
81  @param tree the tree to append this item to
82  @param free_block a code block to call to free resources if this returns
83  @return NULL if 'tree' is null */
84 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)                  \
85         if (!tree) {                                                    \
86                 free_block;                                             \
87                 return NULL;                                            \
88         }
89
90 /** See inlined comments.
91  @param tree the tree to append this item to
92  @param free_block a code block to call to free resources if this returns
93  @return NULL if 'tree' is null */
94 #define CHECK_FOR_NULL_TREE(tree) \
95         CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
96
97 /** See inlined comments.
98  @param tree the tree to append this item to
99  @param hfindex field index
100  @param hfinfo header_field
101  @param free_block a code block to call to free resources if this returns
102  @return the header field matching 'hfinfo' */
103 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
104         /* If this item is not referenced we don't have to do much work \
105            at all but we should still return a node so that field items \
106            below this node (think proto_item_add_subtree()) will still  \
107            have somewhere to attach to or else filtering will not work  \
108            (they would be ignored since tree would be NULL).            \
109            DON'T try to fake a node where PTREE_FINFO(tree) is NULL     \
110            since dissectors that want to do proto_item_set_len() or     \
111            other operations that dereference this would crash.          \
112            We fake FT_PROTOCOL unless some clients have requested us    \
113            not to do so.                                                \
114         */                                                              \
115         PTREE_DATA(tree)->count++;                                      \
116         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);                       \
117         if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) {                 \
118                 free_block;                                             \
119                 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
120                         g_error("Adding %s would put more than %d items in the tree -- possible infinite loop", \
121                             hfinfo->abbrev, MAX_TREE_ITEMS);            \
122                 /* Let the exception handler add items to the tree */   \
123                 PTREE_DATA(tree)->count = 0;                            \
124                 THROW_MESSAGE(DissectorError,                           \
125                         wmem_strdup_printf(wmem_packet_scope(),         \
126                             "Adding %s would put more than %d items in the tree -- possible infinite loop", \
127                             hfinfo->abbrev, MAX_TREE_ITEMS));           \
128         }                                                               \
129         if (!(PTREE_DATA(tree)->visible)) {                             \
130                 if (PTREE_FINFO(tree)) {                                \
131                         if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT)    \
132                             && (hfinfo->type != FT_PROTOCOL ||          \
133                                 PTREE_DATA(tree)->fake_protocols)) {    \
134                                 free_block;                             \
135                                 /* just return tree back to the caller */\
136                                 return tree;                            \
137                         }                                               \
138                 }                                                       \
139         }
140
141 /** See inlined comments.
142  @param tree the tree to append this item to
143  @param hfindex field index
144  @param hfinfo header_field
145  @return the header field matching 'hfinfo' */
146 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
147         TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
148
149
150 /** See inlined comments.
151  @param pi the created protocol item we're about to return */
152 #define TRY_TO_FAKE_THIS_REPR(pi)       \
153         g_assert(pi);                   \
154         if (!(PTREE_DATA(pi)->visible)) { \
155                 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
156                  * items string representation */ \
157                 return pi; \
158         }
159 /* Same as above but returning void */
160 #define TRY_TO_FAKE_THIS_REPR_VOID(pi)  \
161         if (!pi)                        \
162                 return;                 \
163         if (!(PTREE_DATA(pi)->visible)) { \
164                 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
165                  * items string representation */ \
166                 return; \
167         }
168 /* Similar to above, but allows a NULL tree */
169 #define TRY_TO_FAKE_THIS_REPR_NESTED(pi)        \
170         if ((pi == NULL) || (!(PTREE_DATA(pi)->visible))) { \
171                 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
172                  * items string representation */ \
173                 return pi; \
174         }
175
176 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
177 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
178 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
179
180 static void label_mark_truncated(char *label_str, gsize name_pos);
181 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
182
183 static void fill_label_boolean(field_info *fi, gchar *label_str);
184 static void fill_label_bitfield_char(field_info *fi, gchar *label_str);
185 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
186 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
187 static void fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed);
188 static void fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed);
189 static void fill_label_char(field_info *fi, gchar *label_str);
190 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
191 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
192
193 static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value);
194 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
195 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
196 static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
197 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
198 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
199 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
200 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
201 static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
202 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
203 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
204
205 static void proto_cleanup_base(void);
206
207 static proto_item *
208 proto_tree_add_node(proto_tree *tree, field_info *fi);
209
210 static void
211 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
212                 gint *item_length, const guint encoding);
213
214 static gint
215 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
216                 gint length, guint item_length, const gint encoding);
217
218 static field_info *
219 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
220                const gint start, const gint item_length);
221
222 static proto_item *
223 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
224                   gint start, gint *length);
225
226 static void
227 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
228 static void
229 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
230
231 static void
232 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
233 static void
234 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
235 static void
236 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
237 static void
238 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
239 static void
240 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
241 static void
242 proto_tree_set_string(field_info *fi, const char* value);
243 static void
244 proto_tree_set_ax25(field_info *fi, const guint8* value);
245 static void
246 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
247 static void
248 proto_tree_set_vines(field_info *fi, const guint8* value);
249 static void
250 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
251 static void
252 proto_tree_set_ether(field_info *fi, const guint8* value);
253 static void
254 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
255 static void
256 proto_tree_set_ipxnet(field_info *fi, guint32 value);
257 static void
258 proto_tree_set_ipv4(field_info *fi, guint32 value);
259 static void
260 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
261 static void
262 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
263 static void
264 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
265 static void
266 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
267 static void
268 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
269 static void
270 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
271 static void
272 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
273 static void
274 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
275 static void
276 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
277 static void
278 proto_tree_set_boolean(field_info *fi, guint64 value);
279 static void
280 proto_tree_set_float(field_info *fi, float value);
281 static void
282 proto_tree_set_double(field_info *fi, double value);
283 static void
284 proto_tree_set_uint(field_info *fi, guint32 value);
285 static void
286 proto_tree_set_int(field_info *fi, gint32 value);
287 static void
288 proto_tree_set_uint64(field_info *fi, guint64 value);
289 static void
290 proto_tree_set_int64(field_info *fi, gint64 value);
291 static void
292 proto_tree_set_eui64(field_info *fi, const guint64 value);
293 static void
294 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
295
296 /* Handle type length mismatch (now filterable) expert info */
297 static int proto_type_length_mismatch = -1;
298 static expert_field ei_type_length_mismatch_error = EI_INIT;
299 static expert_field ei_type_length_mismatch_warn = EI_INIT;
300 static void register_type_length_mismatch(void);
301
302 /* Handle number string decoding errors with expert info */
303 static int proto_number_string_decoding_error = -1;
304 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
305 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
306 static void register_number_string_decoding_error(void);
307
308 /* Handle string errors expert info */
309 static int proto_string_errors = -1;
310 static expert_field ei_string_trailing_characters = EI_INIT;
311 static void register_string_errors(void);
312
313 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
314
315 /* special-case header field used within proto.c */
316 static header_field_info hfi_text_only =
317         { "Text item",  "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
318 int hf_text_only = -1;
319
320 /* Structure for information about a protocol */
321 struct _protocol {
322         const char *name;               /* long description */
323         const char *short_name;         /* short description */
324         const char *filter_name;        /* name of this protocol in filters */
325         GPtrArray  *fields;             /* fields for this protocol */
326         int         proto_id;           /* field ID for this protocol */
327         gboolean    is_enabled;         /* TRUE if protocol is enabled */
328         gboolean    enabled_by_default; /* TRUE if protocol is enabled by default */
329         gboolean    can_toggle;         /* TRUE if is_enabled can be changed */
330         int         parent_proto_id;    /* Used to identify "pino"s (Protocol In Name Only).
331                                        For dissectors that need a protocol name so they
332                                        can be added to a dissector table, but use the
333                                        parent_proto_id for things like enable/disable */
334         GList      *heur_list;          /* Heuristic dissectors associated with this protocol */
335 };
336
337 /* List of all protocols */
338 static GList *protocols = NULL;
339 static GList *pino_protocols = NULL;
340
341 /* Deregistered fields */
342 static GPtrArray *deregistered_fields = NULL;
343 static GPtrArray *deregistered_data = NULL;
344
345 /* indexed by prefix, contains initializers */
346 static GHashTable* prefixes = NULL;
347
348 /* Contains information about a field when a dissector calls
349  * proto_tree_add_item.  */
350 #define FIELD_INFO_NEW(pool, fi)  fi = wmem_new(pool, field_info)
351 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
352
353 /* Contains the space for proto_nodes. */
354 #define PROTO_NODE_INIT(node)                   \
355         node->first_child = NULL;               \
356         node->last_child = NULL;                \
357         node->next = NULL;
358
359 #define PROTO_NODE_FREE(pool, node)                     \
360         wmem_free(pool, node)
361
362 /* String space for protocol and field items for the GUI */
363 #define ITEM_LABEL_NEW(pool, il)                        \
364         il = wmem_new(pool, item_label_t);
365 #define ITEM_LABEL_FREE(pool, il)                       \
366         wmem_free(pool, il);
367
368 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)                                                \
369         if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG"))      \
370                 g_error("Unregistered hf! index=%d", hfindex);                                  \
371         DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!");     \
372         DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!");     \
373         hfinfo = gpa_hfinfo.hfi[hfindex];
374
375 /* List which stores protocols and fields that have been registered */
376 typedef struct _gpa_hfinfo_t {
377         guint32             len;
378         guint32             allocated_len;
379         header_field_info **hfi;
380 } gpa_hfinfo_t;
381
382 static gpa_hfinfo_t gpa_hfinfo;
383
384 /* Hash table of abbreviations and IDs */
385 static GHashTable *gpa_name_map = NULL;
386 static header_field_info *same_name_hfinfo;
387
388 /* Hash table protocol aliases. const char * -> const char * */
389 static GHashTable *gpa_protocol_aliases = NULL;
390
391 /*
392  * We're called repeatedly with the same field name when sorting a column.
393  * Cache our last gpa_name_map hit for faster lookups.
394  */
395 static char *last_field_name = NULL;
396 static header_field_info *last_hfinfo;
397
398 static void save_same_name_hfinfo(gpointer data)
399 {
400         same_name_hfinfo = (header_field_info*)data;
401 }
402
403 /* Points to the first element of an array of bits, indexed by
404    a subtree item type; that array element is TRUE if subtrees of
405    an item of that type are to be expanded. */
406 static guint32 *tree_is_expanded;
407
408 /* Number of elements in that array. */
409 int             num_tree_types;
410
411 /* Name hashtables for fast detection of duplicate names */
412 static GHashTable* proto_names        = NULL;
413 static GHashTable* proto_short_names  = NULL;
414 static GHashTable* proto_filter_names = NULL;
415
416 static gint
417 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
418 {
419         const protocol_t *p1 = (const protocol_t *)p1_arg;
420         const protocol_t *p2 = (const protocol_t *)p2_arg;
421
422         return g_ascii_strcasecmp(p1->short_name, p2->short_name);
423 }
424
425 #ifdef HAVE_PLUGINS
426 static GSList *dissector_plugins = NULL;
427
428 void
429 proto_register_plugin(const proto_plugin *plug)
430 {
431         if (!plug) {
432                 /* XXX print useful warning */
433                 return;
434         }
435         dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
436 }
437
438 static void
439 call_plugin_register_protoinfo(gpointer data, gpointer user_data _U_)
440 {
441         proto_plugin *plug = (proto_plugin *)data;
442
443         if (plug->register_protoinfo) {
444                 plug->register_protoinfo();
445         }
446 }
447
448 static void
449 call_plugin_register_handoff(gpointer data, gpointer user_data _U_)
450 {
451         proto_plugin *plug = (proto_plugin *)data;
452
453         if (plug->register_handoff) {
454                 plug->register_handoff();
455         }
456 }
457 #endif /* HAVE_PLUGINS */
458
459 /* initialize data structures and register protocols and fields */
460 void
461 proto_init(GSList *register_all_plugin_protocols_list,
462            GSList *register_all_plugin_handoffs_list,
463            register_cb cb,
464            gpointer client_data)
465 {
466         proto_cleanup_base();
467
468         proto_names        = g_hash_table_new(g_str_hash, g_str_equal);
469         proto_short_names  = g_hash_table_new(g_str_hash, g_str_equal);
470         proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
471
472         gpa_hfinfo.len           = 0;
473         gpa_hfinfo.allocated_len = 0;
474         gpa_hfinfo.hfi           = NULL;
475         gpa_name_map             = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
476         gpa_protocol_aliases     = g_hash_table_new(g_str_hash, g_str_equal);
477         deregistered_fields      = g_ptr_array_new();
478         deregistered_data        = g_ptr_array_new();
479
480         /* Initialize the ftype subsystem */
481         ftypes_initialize();
482
483         /* Initialize the addres type subsystem */
484         address_types_initialize();
485
486         /* Register one special-case FT_TEXT_ONLY field for use when
487            converting wireshark to new-style proto_tree. These fields
488            are merely strings on the GUI tree; they are not filterable */
489         hf_text_only = proto_register_field_init(&hfi_text_only, -1);
490
491         /* Register the pseudo-protocols used for exceptions. */
492         register_show_exception();
493         register_type_length_mismatch();
494         register_number_string_decoding_error();
495         register_string_errors();
496
497         /* Have each built-in dissector register its protocols, fields,
498            dissector tables, and dissectors to be called through a
499            handle, and do whatever one-time initialization it needs to
500            do. */
501         register_all_protocols(cb, client_data);
502
503         /* Now call the registration routines for all epan plugins. */
504         for (GSList *l = register_all_plugin_protocols_list; l != NULL; l = l->next) {
505                 ((void (*)(register_cb, gpointer))l->data)(cb, client_data);
506         }
507
508 #ifdef HAVE_PLUGINS
509         /* Now call the registration routines for all dissector plugins. */
510         if (cb)
511                 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
512         g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL);
513 #endif
514
515         /* Now call the "handoff registration" routines of all built-in
516            dissectors; those routines register the dissector in other
517            dissectors' handoff tables, and fetch any dissector handles
518            they need. */
519         register_all_protocol_handoffs(cb, client_data);
520
521         /* Now do the same with epan plugins. */
522         for (GSList *l = register_all_plugin_handoffs_list; l != NULL; l = l->next) {
523                 ((void (*)(register_cb, gpointer))l->data)(cb, client_data);
524         }
525
526 #ifdef HAVE_PLUGINS
527         /* Now do the same with dissector plugins. */
528         if (cb)
529                 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
530         g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL);
531 #endif
532
533         /* sort the protocols by protocol name */
534         protocols = g_list_sort(protocols, proto_compare_name);
535
536         /* We've assigned all the subtree type values; allocate the array
537            for them, and zero it out. */
538         tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
539 }
540
541 static void
542 proto_cleanup_base(void)
543 {
544         protocol_t *protocol;
545         header_field_info *hfinfo;
546
547         /* Free the abbrev/ID hash table */
548         if (gpa_name_map) {
549                 g_hash_table_destroy(gpa_name_map);
550                 gpa_name_map = NULL;
551         }
552         if (gpa_protocol_aliases) {
553                 g_hash_table_destroy(gpa_protocol_aliases);
554                 gpa_protocol_aliases = NULL;
555         }
556         g_free(last_field_name);
557         last_field_name = NULL;
558
559         while (protocols) {
560                 protocol = (protocol_t *)protocols->data;
561                 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
562                 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
563
564                 g_slice_free(header_field_info, hfinfo);
565                 if (protocol->fields) {
566                         g_ptr_array_free(protocol->fields, TRUE);
567                 }
568                 g_list_free(protocol->heur_list);
569                 protocols = g_list_remove(protocols, protocol);
570                 g_free(protocol);
571         }
572
573         while (pino_protocols) {
574                 protocol = (protocol_t *)pino_protocols->data;
575                 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
576                 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
577                 DISSECTOR_ASSERT(protocol->fields == NULL); //helpers should not have any registered fields
578                 g_slice_free(header_field_info, hfinfo);
579                 DISSECTOR_ASSERT(protocol->heur_list == NULL); //helpers should not have a heuristic list
580                 pino_protocols = g_list_remove(pino_protocols, protocol);
581                 g_free(protocol);
582         }
583
584         if (proto_names) {
585                 g_hash_table_destroy(proto_names);
586                 proto_names = NULL;
587         }
588
589         if (proto_short_names) {
590                 g_hash_table_destroy(proto_short_names);
591                 proto_short_names = NULL;
592         }
593
594         if (proto_filter_names) {
595                 g_hash_table_destroy(proto_filter_names);
596                 proto_filter_names = NULL;
597         }
598
599         if (gpa_hfinfo.allocated_len) {
600                 gpa_hfinfo.len           = 0;
601                 gpa_hfinfo.allocated_len = 0;
602                 g_free(gpa_hfinfo.hfi);
603                 gpa_hfinfo.hfi           = NULL;
604         }
605
606         if (deregistered_fields) {
607                 g_ptr_array_free(deregistered_fields, TRUE);
608                 deregistered_fields = NULL;
609         }
610
611         if (deregistered_data) {
612                 g_ptr_array_free(deregistered_data, TRUE);
613                 deregistered_data = NULL;
614         }
615
616         g_free(tree_is_expanded);
617         tree_is_expanded = NULL;
618
619         if (prefixes)
620                 g_hash_table_destroy(prefixes);
621 }
622
623 void
624 proto_cleanup(void)
625 {
626         proto_free_deregistered_fields();
627         proto_cleanup_base();
628
629 #ifdef HAVE_PLUGINS
630         g_slist_free(dissector_plugins);
631         dissector_plugins = NULL;
632 #endif
633 }
634
635 static gboolean
636 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
637                               gpointer data)
638 {
639         proto_node *pnode = tree;
640         proto_node *child;
641         proto_node *current;
642
643         if (func(pnode, data))
644                 return TRUE;
645
646         child = pnode->first_child;
647         while (child != NULL) {
648                 /*
649                  * The routine we call might modify the child, e.g. by
650                  * freeing it, so we get the child's successor before
651                  * calling that routine.
652                  */
653                 current = child;
654                 child   = current->next;
655                 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
656                         return TRUE;
657         }
658
659         return FALSE;
660 }
661
662 gboolean
663 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
664                                gpointer data)
665 {
666         proto_node *pnode = tree;
667         proto_node *child;
668         proto_node *current;
669
670         child = pnode->first_child;
671         while (child != NULL) {
672                 /*
673                  * The routine we call might modify the child, e.g. by
674                  * freeing it, so we get the child's successor before
675                  * calling that routine.
676                  */
677                 current = child;
678                 child   = current->next;
679                 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
680                         return TRUE;
681         }
682         if (func(pnode, data))
683                 return TRUE;
684
685         return FALSE;
686 }
687
688 void
689 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
690                             gpointer data)
691 {
692         proto_node *node = tree;
693         proto_node *current;
694
695         if (!node)
696                 return;
697
698         node = node->first_child;
699         while (node != NULL) {
700                 current = node;
701                 node    = current->next;
702                 func((proto_tree *)current, data);
703         }
704 }
705
706 static void
707 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
708 {
709         GPtrArray         *ptrs = (GPtrArray *)value;
710         gint               hfid = GPOINTER_TO_UINT(key);
711         header_field_info *hfinfo;
712
713         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
714         if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
715                 /* when a field is referenced by a filter this also
716                    affects the refcount for the parent protocol so we need
717                    to adjust the refcount for the parent as well
718                 */
719                 if (hfinfo->parent != -1) {
720                         header_field_info *parent_hfinfo;
721                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
722                         parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
723                 }
724                 hfinfo->ref_type = HF_REF_TYPE_NONE;
725         }
726
727         g_ptr_array_free(ptrs, TRUE);
728 }
729
730 static void
731 proto_tree_free_node(proto_node *node, gpointer data _U_)
732 {
733         field_info *finfo  = PNODE_FINFO(node);
734
735         proto_tree_children_foreach(node, proto_tree_free_node, NULL);
736
737         FVALUE_CLEANUP(&finfo->value);
738 }
739
740 void
741 proto_tree_reset(proto_tree *tree)
742 {
743         tree_data_t *tree_data = PTREE_DATA(tree);
744
745         proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
746
747         /* free tree data */
748         if (tree_data->interesting_hfids) {
749                 /* Free all the GPtrArray's in the interesting_hfids hash. */
750                 g_hash_table_foreach(tree_data->interesting_hfids,
751                         free_GPtrArray_value, NULL);
752
753                 /* And then remove all values. */
754                 g_hash_table_remove_all(tree_data->interesting_hfids);
755         }
756
757         /* Reset track of the number of children */
758         tree_data->count = 0;
759
760         PROTO_NODE_INIT(tree);
761 }
762
763 /* frees the resources that the dissection a proto_tree uses */
764 void
765 proto_tree_free(proto_tree *tree)
766 {
767         tree_data_t *tree_data = PTREE_DATA(tree);
768
769         proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
770
771         /* free tree data */
772         if (tree_data->interesting_hfids) {
773                 /* Free all the GPtrArray's in the interesting_hfids hash. */
774                 g_hash_table_foreach(tree_data->interesting_hfids,
775                         free_GPtrArray_value, NULL);
776
777                 /* And then destroy the hash. */
778                 g_hash_table_destroy(tree_data->interesting_hfids);
779         }
780
781         g_slice_free(tree_data_t, tree_data);
782
783         g_slice_free(proto_tree, tree);
784 }
785
786 /* Is the parsing being done for a visible proto_tree or an invisible one?
787  * By setting this correctly, the proto_tree creation is sped up by not
788  * having to call g_vsnprintf and copy strings around.
789  */
790 gboolean
791 proto_tree_set_visible(proto_tree *tree, gboolean visible)
792 {
793         gboolean old_visible = PTREE_DATA(tree)->visible;
794
795         PTREE_DATA(tree)->visible = visible;
796
797         return old_visible;
798 }
799
800 void
801 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
802 {
803         PTREE_DATA(tree)->fake_protocols = fake_protocols;
804 }
805
806 /* Assume dissector set only its protocol fields.
807    This function is called by dissectors and allows the speeding up of filtering
808    in wireshark; if this function returns FALSE it is safe to reset tree to NULL
809    and thus skip calling most of the expensive proto_tree_add_...()
810    functions.
811    If the tree is visible we implicitly assume the field is referenced.
812 */
813 gboolean
814 proto_field_is_referenced(proto_tree *tree, int proto_id)
815 {
816         register header_field_info *hfinfo;
817
818
819         if (!tree)
820                 return FALSE;
821
822         if (PTREE_DATA(tree)->visible)
823                 return TRUE;
824
825         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
826         if (hfinfo->ref_type != HF_REF_TYPE_NONE)
827                 return TRUE;
828
829         if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
830                 return TRUE;
831
832         return FALSE;
833 }
834
835
836 /* Finds a record in the hfinfo array by id. */
837 header_field_info *
838 proto_registrar_get_nth(guint hfindex)
839 {
840         register header_field_info *hfinfo;
841
842         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
843         return hfinfo;
844 }
845
846
847 /*      Prefix initialization
848  *        this allows for a dissector to register a display filter name prefix
849  *        so that it can delay the initialization of the hf array as long as
850  *        possible.
851  */
852
853 /* compute a hash for the part before the dot of a display filter */
854 static guint
855 prefix_hash (gconstpointer key) {
856         /* end the string at the dot and compute its hash */
857         gchar* copy = g_strdup((const gchar *)key);
858         gchar* c    = copy;
859         guint tmp;
860
861         for (; *c; c++) {
862                 if (*c == '.') {
863                         *c = 0;
864                         break;
865                 }
866         }
867
868         tmp = g_str_hash(copy);
869         g_free(copy);
870         return tmp;
871 }
872
873 /* are both strings equal up to the end or the dot? */
874 static gboolean
875 prefix_equal (gconstpointer ap, gconstpointer bp) {
876         const gchar* a = (const gchar *)ap;
877         const gchar* b = (const gchar *)bp;
878
879         do {
880                 gchar ac = *a++;
881                 gchar bc = *b++;
882
883                 if ( (ac == '.' || ac == '\0') &&   (bc == '.' || bc == '\0') ) return TRUE;
884
885                 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
886                 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
887
888                 if (ac != bc) return FALSE;
889         } while (1);
890
891         return FALSE;
892 }
893
894 /* Register a new prefix for "delayed" initialization of field arrays */
895 void
896 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
897         if (! prefixes ) {
898                 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
899         }
900
901         g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
902 }
903
904 /* helper to call all prefix initializers */
905 static gboolean
906 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
907         ((prefix_initializer_t)v)((const char *)k);
908         return TRUE;
909 }
910
911 /** Initialize every remaining uninitialized prefix. */
912 void
913 proto_initialize_all_prefixes(void) {
914         g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
915 }
916
917 /* Finds a record in the hfinfo array by name.
918  * If it fails to find it in the already registered fields,
919  * it tries to find and call an initializer in the prefixes
920  * table and if so it looks again.
921  */
922
923 header_field_info *
924 proto_registrar_get_byname(const char *field_name)
925 {
926         header_field_info    *hfinfo;
927         prefix_initializer_t  pi;
928
929         if (!field_name)
930                 return NULL;
931
932         if (g_strcmp0(field_name, last_field_name) == 0) {
933                 return last_hfinfo;
934         }
935
936         hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
937
938         if (hfinfo) {
939                 g_free(last_field_name);
940                 last_field_name = g_strdup(field_name);
941                 last_hfinfo = hfinfo;
942                 return hfinfo;
943         }
944
945         if (!prefixes)
946                 return NULL;
947
948         if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
949                 pi(field_name);
950                 g_hash_table_remove(prefixes, field_name);
951         } else {
952                 return NULL;
953         }
954
955         hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
956
957         if (hfinfo) {
958                 g_free(last_field_name);
959                 last_field_name = g_strdup(field_name);
960                 last_hfinfo = hfinfo;
961         }
962         return hfinfo;
963 }
964
965 header_field_info*
966 proto_registrar_get_byalias(const char *alias_name)
967 {
968         if (!alias_name) {
969                 return NULL;
970         }
971
972         /* Find our aliased protocol. */
973         char *an_copy = g_strdup(alias_name);
974         char *dot = strchr(an_copy, '.');
975         if (dot) {
976                 *dot = '\0';
977         }
978         const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
979         if (!proto_pfx) {
980                 g_free(an_copy);
981                 return NULL;
982         }
983
984         /* Construct our aliased field and look it up. */
985         GString *filter_name = g_string_new(proto_pfx);
986         if (dot) {
987                 g_string_append_printf(filter_name, ".%s", dot+1);
988         }
989         header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
990         g_free(an_copy);
991         g_string_free(filter_name, TRUE);
992
993         return hfinfo;
994 }
995
996 int
997 proto_registrar_get_id_byname(const char *field_name)
998 {
999         header_field_info *hfinfo;
1000
1001         hfinfo = proto_registrar_get_byname(field_name);
1002
1003         if (!hfinfo)
1004                 return -1;
1005
1006         return hfinfo->id;
1007 }
1008
1009
1010 static void
1011 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1012 {
1013         subtree_lvl *pushed_tree;
1014
1015         DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
1016         ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
1017
1018         pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1019         DISSECTOR_ASSERT(pushed_tree != NULL);
1020         if (ptvc->pushed_tree)
1021                 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
1022         ptvc->pushed_tree = pushed_tree;
1023 }
1024
1025 static void
1026 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1027 {
1028         ptvc->pushed_tree       = NULL;
1029         ptvc->pushed_tree_max   = 0;
1030         DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1031         ptvc->pushed_tree_index = 0;
1032 }
1033
1034 /* Allocates an initializes a ptvcursor_t with 3 variables:
1035  *      proto_tree, tvbuff, and offset. */
1036 ptvcursor_t *
1037 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
1038 {
1039         ptvcursor_t *ptvc;
1040
1041         ptvc                    = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
1042         ptvc->tree              = tree;
1043         ptvc->tvb               = tvb;
1044         ptvc->offset            = offset;
1045         ptvc->pushed_tree       = NULL;
1046         ptvc->pushed_tree_max   = 0;
1047         ptvc->pushed_tree_index = 0;
1048         return ptvc;
1049 }
1050
1051
1052 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1053 void
1054 ptvcursor_free(ptvcursor_t *ptvc)
1055 {
1056         ptvcursor_free_subtree_levels(ptvc);
1057         /*g_free(ptvc);*/
1058 }
1059
1060 /* Returns tvbuff. */
1061 tvbuff_t *
1062 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1063 {
1064         return ptvc->tvb;
1065 }
1066
1067 /* Returns current offset. */
1068 gint
1069 ptvcursor_current_offset(ptvcursor_t *ptvc)
1070 {
1071         return ptvc->offset;
1072 }
1073
1074 proto_tree *
1075 ptvcursor_tree(ptvcursor_t *ptvc)
1076 {
1077         if (!ptvc)
1078                 return NULL;
1079
1080         return ptvc->tree;
1081 }
1082
1083 void
1084 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1085 {
1086         ptvc->tree = tree;
1087 }
1088
1089 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1090 proto_tree *
1091 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1092 {
1093         subtree_lvl *subtree;
1094         if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1095                 ptvcursor_new_subtree_levels(ptvc);
1096
1097         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1098         subtree->tree = ptvc->tree;
1099         subtree->it= NULL;
1100         ptvc->pushed_tree_index++;
1101         return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1102 }
1103
1104 /* pops a subtree */
1105 void
1106 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1107 {
1108         subtree_lvl *subtree;
1109
1110         if (ptvc->pushed_tree_index <= 0)
1111                 return;
1112
1113         ptvc->pushed_tree_index--;
1114         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1115         if (subtree->it != NULL)
1116                 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1117
1118         ptvc->tree = subtree->tree;
1119 }
1120
1121 /* saves the current tvb offset and the item in the current subtree level */
1122 static void
1123 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1124 {
1125         subtree_lvl *subtree;
1126
1127         DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1128
1129         subtree                = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1130         subtree->it            = it;
1131         subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1132 }
1133
1134 /* Creates a subtree and adds it to the cursor as the working tree but does not
1135  * save the old working tree */
1136 proto_tree *
1137 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1138 {
1139         ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1140         return ptvc->tree;
1141 }
1142
1143 static proto_tree *
1144 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1145 {
1146         ptvcursor_push_subtree(ptvc, it, ett_subtree);
1147         if (length == SUBTREE_UNDEFINED_LENGTH)
1148                 ptvcursor_subtree_set_item(ptvc, it);
1149         return ptvcursor_tree(ptvc);
1150 }
1151
1152 /* Add an item to the tree and create a subtree
1153  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1154  * In this case, when the subtree will be closed, the parent item length will
1155  * be equal to the advancement of the cursor since the creation of the subtree.
1156  */
1157 proto_tree *
1158 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1159                            const guint encoding, gint ett_subtree)
1160 {
1161         proto_item *it;
1162
1163         it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1164         return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1165 }
1166
1167 static proto_item *
1168 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1169
1170 /* Add a text node to the tree and create a subtree
1171  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1172  * In this case, when the subtree will be closed, the item length will be equal
1173  * to the advancement of the cursor since the creation of the subtree.
1174  */
1175 proto_tree *
1176 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1177                                 gint ett_subtree, const char *format, ...)
1178 {
1179         proto_item        *pi;
1180         va_list            ap;
1181         header_field_info *hfinfo;
1182         proto_tree        *tree;
1183
1184         tree = ptvcursor_tree(ptvc);
1185
1186         CHECK_FOR_NULL_TREE(tree);
1187
1188         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1189
1190         pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1191                                       ptvcursor_current_offset(ptvc), length);
1192
1193         TRY_TO_FAKE_THIS_REPR(pi);
1194
1195         va_start(ap, format);
1196         proto_tree_set_representation(pi, format, ap);
1197         va_end(ap);
1198
1199         return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1200 }
1201
1202 /* Add a text-only node, leaving it to our caller to fill the text in */
1203 static proto_item *
1204 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1205 {
1206         proto_item *pi;
1207
1208         if (tree == NULL)
1209                 return NULL;
1210
1211         pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1212
1213         return pi;
1214 }
1215
1216 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1217 proto_item *
1218 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1219                     const char *format, ...)
1220 {
1221         proto_item        *pi;
1222         va_list            ap;
1223         header_field_info *hfinfo;
1224
1225         if (length == -1) {
1226                 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1227         } else {
1228                 tvb_ensure_bytes_exist(tvb, start, length);
1229         }
1230
1231         CHECK_FOR_NULL_TREE(tree);
1232
1233         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1234
1235         pi = proto_tree_add_text_node(tree, tvb, start, length);
1236
1237         TRY_TO_FAKE_THIS_REPR(pi);
1238
1239         va_start(ap, format);
1240         proto_tree_set_representation(pi, format, ap);
1241         va_end(ap);
1242
1243         return pi;
1244 }
1245
1246 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1247 proto_item *
1248 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1249                            gint length, const char *format, va_list ap)
1250 {
1251         proto_item        *pi;
1252         header_field_info *hfinfo;
1253
1254         if (length == -1) {
1255                 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1256         } else {
1257                 tvb_ensure_bytes_exist(tvb, start, length);
1258         }
1259
1260         CHECK_FOR_NULL_TREE(tree);
1261
1262         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1263
1264         pi = proto_tree_add_text_node(tree, tvb, start, length);
1265
1266         TRY_TO_FAKE_THIS_REPR(pi);
1267
1268         proto_tree_set_representation(pi, format, ap);
1269
1270         return pi;
1271 }
1272
1273 /* Add a text-only node that creates a subtree underneath.
1274  */
1275 proto_tree *
1276 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1277 {
1278         return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1279 }
1280
1281 /* Add a text-only node that creates a subtree underneath.
1282  */
1283 proto_tree *
1284 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1285 {
1286         proto_tree *pt;
1287         proto_item *pi;
1288         va_list     ap;
1289
1290         va_start(ap, format);
1291         pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1292         va_end(ap);
1293
1294         if (tree_item != NULL)
1295                 *tree_item = pi;
1296
1297         pt = proto_item_add_subtree(pi, idx);
1298
1299         return pt;
1300 }
1301
1302 /* Add a text-only node for debugging purposes. The caller doesn't need
1303  * to worry about tvbuff, start, or length. Debug message gets sent to
1304  * STDOUT, too */
1305 proto_item *
1306 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1307 {
1308         proto_item *pi;
1309         va_list     ap;
1310
1311         pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1312
1313         if (pi) {
1314                 va_start(ap, format);
1315                 proto_tree_set_representation(pi, format, ap);
1316                 va_end(ap);
1317         }
1318         va_start(ap, format);
1319         vprintf(format, ap);
1320         va_end(ap);
1321         ws_debug_printf("\n");
1322
1323         return pi;
1324 }
1325
1326 proto_item *
1327 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1328 {
1329         proto_item        *pi;
1330         header_field_info *hfinfo;
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         proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1341
1342         return pi;
1343 }
1344
1345 proto_item *
1346 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1347 {
1348         proto_item        *pi;
1349         header_field_info *hfinfo;
1350         gchar             *str;
1351
1352         CHECK_FOR_NULL_TREE(tree);
1353
1354         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1355
1356         pi = proto_tree_add_text_node(tree, tvb, start, length);
1357
1358         TRY_TO_FAKE_THIS_REPR(pi);
1359
1360         str = tvb_format_text_wsp(NULL, tvb, start, length);
1361         proto_item_set_text(pi, "%s", str);
1362         wmem_free(NULL, str);
1363
1364         return pi;
1365 }
1366
1367 void proto_report_dissector_bug(const char *format, ...)
1368 {
1369         va_list args;
1370
1371         if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL) {
1372                 /*
1373                  * Try to have the error message show up in the crash
1374                  * information.
1375                  */
1376                 va_start(args, format);
1377                 ws_vadd_crash_info(format, args);
1378                 va_end(args);
1379
1380                 /*
1381                  * Print the error message.
1382                  */
1383                 va_start(args, format);
1384                 vfprintf(stderr, format, args);
1385                 va_end(args);
1386                 putc('\n', stderr);
1387
1388                 /*
1389                  * And crash.
1390                  */
1391                 abort();
1392         } else {
1393                 va_start(args, format);
1394                 VTHROW_FORMATTED(DissectorError, format, args);
1395                 va_end(args);
1396         }
1397 }
1398
1399 /* We could probably get away with changing is_error to a minimum length value. */
1400 static void
1401 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1402
1403         if (is_error) {
1404                 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1405         } else {
1406                 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1407         }
1408
1409         if (is_error) {
1410                 THROW(ReportedBoundsError);
1411         }
1412 }
1413
1414 static guint32
1415 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1416 {
1417         guint32 value;
1418         gboolean length_error;
1419
1420         switch (length) {
1421
1422         case 1:
1423                 value = tvb_get_guint8(tvb, offset);
1424                 if (encoding & ENC_ZIGBEE) {
1425                         if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1426                                 value = 0;
1427                         }
1428                 }
1429                 break;
1430
1431         case 2:
1432                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1433                                                        : tvb_get_ntohs(tvb, offset);
1434                 if (encoding & ENC_ZIGBEE) {
1435                         if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1436                                 value = 0;
1437                         }
1438                 }
1439                 break;
1440
1441         case 3:
1442                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1443                                                        : tvb_get_ntoh24(tvb, offset);
1444                 break;
1445
1446         case 4:
1447                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1448                                                        : tvb_get_ntohl(tvb, offset);
1449                 break;
1450
1451         default:
1452                 if (length < 1) {
1453                         length_error = TRUE;
1454                         value = 0;
1455                 } else {
1456                         length_error = FALSE;
1457                         value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1458                                                                : tvb_get_ntohl(tvb, offset);
1459                 }
1460                 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1461                 break;
1462         }
1463         return value;
1464 }
1465
1466 static inline guint64
1467 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1468 {
1469         guint64 value;
1470         gboolean length_error;
1471
1472         switch (length) {
1473
1474         case 1:
1475                 value = tvb_get_guint8(tvb, offset);
1476                 break;
1477
1478         case 2:
1479                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1480                                                        : tvb_get_ntohs(tvb, offset);
1481                 break;
1482
1483         case 3:
1484                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1485                                                        : tvb_get_ntoh24(tvb, offset);
1486                 break;
1487
1488         case 4:
1489                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1490                                                        : tvb_get_ntohl(tvb, offset);
1491                 break;
1492
1493         case 5:
1494                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1495                                                        : tvb_get_ntoh40(tvb, offset);
1496                 break;
1497
1498         case 6:
1499                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1500                                                        : tvb_get_ntoh48(tvb, offset);
1501                 break;
1502
1503         case 7:
1504                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1505                                                        : tvb_get_ntoh56(tvb, offset);
1506                 break;
1507
1508         case 8:
1509                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1510                                                        : tvb_get_ntoh64(tvb, offset);
1511                 break;
1512
1513         default:
1514                 if (length < 1) {
1515                         length_error = TRUE;
1516                         value = 0;
1517                 } else {
1518                         length_error = FALSE;
1519                         value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1520                                                                : tvb_get_ntoh64(tvb, offset);
1521                 }
1522                 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1523                 break;
1524         }
1525         return value;
1526 }
1527
1528 static gint32
1529 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1530 {
1531         gint32 value;
1532         gboolean length_error;
1533
1534         switch (length) {
1535
1536         case 1:
1537                 value = tvb_get_gint8(tvb, offset);
1538                 break;
1539
1540         case 2:
1541                 value = encoding ? tvb_get_letohis(tvb, offset)
1542                                  : tvb_get_ntohis(tvb, offset);
1543                 break;
1544
1545         case 3:
1546                 value = encoding ? tvb_get_letohi24(tvb, offset)
1547                                  : tvb_get_ntohi24(tvb, offset);
1548                 break;
1549
1550         case 4:
1551                 value = encoding ? tvb_get_letohil(tvb, offset)
1552                                  : tvb_get_ntohil(tvb, offset);
1553                 break;
1554
1555         default:
1556                 if (length < 1) {
1557                         length_error = TRUE;
1558                         value = 0;
1559                 } else {
1560                         length_error = FALSE;
1561                         value = encoding ? tvb_get_letohil(tvb, offset)
1562                                          : tvb_get_ntohil(tvb, offset);
1563                 }
1564                 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1565                 break;
1566         }
1567         return value;
1568 }
1569
1570 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1571  * be cast-able as a gint64. This is weird, but what the code has always done.
1572  */
1573 static inline guint64
1574 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1575 {
1576         guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1577
1578         switch (length) {
1579                 case 7:
1580                         value = ws_sign_ext64(value, 56);
1581                         break;
1582                 case 6:
1583                         value = ws_sign_ext64(value, 48);
1584                         break;
1585                 case 5:
1586                         value = ws_sign_ext64(value, 40);
1587                         break;
1588                 case 4:
1589                         value = ws_sign_ext64(value, 32);
1590                         break;
1591                 case 3:
1592                         value = ws_sign_ext64(value, 24);
1593                         break;
1594                 case 2:
1595                         value = ws_sign_ext64(value, 16);
1596                         break;
1597                 case 1:
1598                         value = ws_sign_ext64(value, 8);
1599                         break;
1600         }
1601
1602         return value;
1603 }
1604
1605 /* For FT_STRING */
1606 static inline const guint8 *
1607 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1608     gint length, gint *ret_length, const guint encoding)
1609 {
1610         if (length == -1) {
1611                 length = tvb_ensure_captured_length_remaining(tvb, start);
1612         }
1613         *ret_length = length;
1614         return tvb_get_string_enc(scope, tvb, start, length, encoding);
1615 }
1616
1617 /* For FT_STRINGZ */
1618 static inline const guint8 *
1619 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1620     gint start, gint length, gint *ret_length, const guint encoding)
1621 {
1622         const guint8 *value;
1623
1624         if (length < -1) {
1625                 report_type_length_mismatch(tree, "a string", length, TRUE);
1626         }
1627         if (length == -1) {
1628                 /* This can throw an exception */
1629                 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1630         } else if (length == 0) {
1631                 value = "[Empty]";
1632         } else {
1633                 /* In this case, length signifies the length of the string.
1634                  *
1635                  * This could either be a null-padded string, which doesn't
1636                  * necessarily have a '\0' at the end, or a null-terminated
1637                  * string, with a trailing '\0'.  (Yes, there are cases
1638                  * where you have a string that's both counted and null-
1639                  * terminated.)
1640                  *
1641                  * In the first case, we must allocate a buffer of length
1642                  * "length+1", to make room for a trailing '\0'.
1643                  *
1644                  * In the second case, we don't assume that there is a
1645                  * trailing '\0' there, as the packet might be malformed.
1646                  * (XXX - should we throw an exception if there's no
1647                  * trailing '\0'?)  Therefore, we allocate a buffer of
1648                  * length "length+1", and put in a trailing '\0', just to
1649                  * be safe.
1650                  *
1651                  * (XXX - this would change if we made string values counted
1652                  * rather than null-terminated.)
1653                  */
1654                 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1655         }
1656         *ret_length = length;
1657         return value;
1658 }
1659
1660 /* For FT_UINT_STRING */
1661 static inline const guint8 *
1662 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1663     tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1664     const guint encoding)
1665 {
1666         guint32 n;
1667         const guint8 *value;
1668
1669         /* I believe it's ok if this is called with a NULL tree */
1670         if (encoding & ENC_ZIGBEE) {
1671                 n = get_uint_value(tree, tvb, start, length, encoding);
1672         } else {
1673                 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1674         }
1675         value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1676         length += n;
1677         *ret_length = length;
1678         return value;
1679 }
1680
1681 /* For FT_STRINGZPAD */
1682 static inline const guint8 *
1683 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1684     gint length, gint *ret_length, const guint encoding)
1685 {
1686         /*
1687          * XXX - currently, string values are null-
1688          * terminated, so a "zero-padded" string
1689          * isn't special.  If we represent string
1690          * values as something that includes a counted
1691          * array of bytes, we'll need to strip
1692          * trailing NULs.
1693          */
1694         if (length == -1) {
1695                 length = tvb_ensure_captured_length_remaining(tvb, start);
1696         }
1697         *ret_length = length;
1698         return tvb_get_string_enc(scope, tvb, start, length, encoding);
1699 }
1700
1701 /*
1702  * Epochs for various non-UN*X time stamp formats.
1703  */
1704 #define NTP_TIMEDIFF1900TO1970SEC G_GINT64_CONSTANT(2208988800) /* NTP Time Diff 1900 to 1970 in sec */
1705 #define NTP_TIMEDIFF1970TO2036SEC G_GINT64_CONSTANT(2085978496) /* NTP Time Diff 1970 to 2036 in sec */
1706 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800)     /* System/3x0 and z/Architecture TOD clock */
1707
1708 /* this can be called when there is no tree, so tree may be null */
1709 static void
1710 get_time_value(proto_tree *tree, tvbuff_t *tvb, const gint start,
1711                const gint length, const guint encoding, nstime_t *time_stamp,
1712                const gboolean is_relative)
1713 {
1714         guint32     tmpsecs;
1715         guint64     todsecs;
1716
1717         switch (encoding) {
1718
1719                 case ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN:
1720                         /*
1721                          * If the length is 16, 8-byte seconds, followed
1722                          * by 8-byte fractional time in nanoseconds,
1723                          * both big-endian.
1724                          *
1725                          * If the length is 12, 8-byte seconds, followed
1726                          * by 4-byte fractional time in nanoseconds,
1727                          * both big-endian.
1728                          *
1729                          * If the length is 8, 4-byte seconds, followed
1730                          * by 4-byte fractional time in nanoseconds,
1731                          * both big-endian.
1732                          *
1733                          * For absolute times, the seconds are seconds
1734                          * since the UN*X epoch.
1735                          */
1736                         if (length == 16) {
1737                                 time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
1738                                 time_stamp->nsecs = (guint32)tvb_get_ntoh64(tvb, start+8);
1739                         } else if (length == 12) {
1740                                 time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
1741                                 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1742                         } else if (length == 8) {
1743                                 time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
1744                                 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1745                         } else if (length == 4) {
1746                                 /*
1747                                  * Backwards compatibility.
1748                                  * ENC_TIME_SECS_NSECS is 0; using
1749                                  * ENC_BIG_ENDIAN by itself with a 4-byte
1750                                  * time-in-seconds value was done in the
1751                                  * past.
1752                                  */
1753                                 time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
1754                                 time_stamp->nsecs = 0;
1755                         } else {
1756                                 time_stamp->secs  = 0;
1757                                 time_stamp->nsecs = 0;
1758                                 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1759                         }
1760                         break;
1761
1762                 case ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN:
1763                         /*
1764                          * If the length is 16, 8-byte seconds, followed
1765                          * by 8-byte fractional time in nanoseconds,
1766                          * both little-endian.
1767                          *
1768                          * If the length is 12, 8-byte seconds, followed
1769                          * by 4-byte fractional time in nanoseconds,
1770                          * both little-endian.
1771                          *
1772                          * If the length is 8, 4-byte seconds, followed
1773                          * by 4-byte fractional time in nanoseconds,
1774                          * both little-endian.
1775                          *
1776                          * For absolute times, the seconds are seconds
1777                          * since the UN*X epoch.
1778                          */
1779                         if (length == 16) {
1780                                 time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
1781                                 time_stamp->nsecs = (guint32)tvb_get_letoh64(tvb, start+8);
1782                         } else if (length == 12) {
1783                                 time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
1784                                 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1785                         } else if (length == 8) {
1786                                 time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
1787                                 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1788                         } else if (length == 4) {
1789                                 /*
1790                                  * Backwards compatibility.
1791                                  * ENC_TIME_SECS_NSECS is 0; using
1792                                  * ENC_LITTLE_ENDIAN by itself with a 4-byte
1793                                  * time-in-seconds value was done in the
1794                                  * past.
1795                                  */
1796                                 time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
1797                                 time_stamp->nsecs = 0;
1798                         } else {
1799                                 time_stamp->secs  = 0;
1800                                 time_stamp->nsecs = 0;
1801                                 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1802                         }
1803                         break;
1804
1805                 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1806                         /*
1807                          * NTP time stamp, big-endian.
1808                          * Only supported for absolute times.
1809                          */
1810                         DISSECTOR_ASSERT(!is_relative);
1811
1812                         /* We need a temporary variable here so the unsigned math
1813                          * works correctly (for years > 2036 according to RFC 2030
1814                          * chapter 3).
1815                          *
1816                          * If bit 0 is set, the UTC time is in the range 1968-2036 and
1817                          * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
1818                          * If bit 0 is not set, the time is in the range 2036-2104 and
1819                          * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
1820                          */
1821                         tmpsecs  = tvb_get_ntohl(tvb, start);
1822                         if ((tmpsecs & 0x80000000) != 0)
1823                                 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
1824                         else
1825                                 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
1826
1827                         if (length == 8) {
1828                                 /*
1829                                  * Convert 1/2^32s of a second to nanoseconds.
1830                                  */
1831                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1832                         } else if (length == 4) {
1833                                 /*
1834                                  * Backwards compatibility.
1835                                  */
1836                                 time_stamp->nsecs = 0;
1837                         } else {
1838                                 time_stamp->secs  = 0;
1839                                 time_stamp->nsecs = 0;
1840                                 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
1841                         }
1842                         break;
1843
1844                 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1845                         /*
1846                          * NTP time stamp, little-endian.
1847                          * Only supported for absolute times.
1848                          */
1849                         DISSECTOR_ASSERT(!is_relative);
1850
1851                         /* We need a temporary variable here so the unsigned math
1852                          * works correctly (for years > 2036 according to RFC 2030
1853                          * chapter 3).
1854                          *
1855                          * If bit 0 is set, the UTC time is in the range 1968-2036 and
1856                          * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
1857                          * If bit 0 is not set, the time is in the range 2036-2104 and
1858                          * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
1859                          */
1860                         tmpsecs  = tvb_get_letohl(tvb, start);
1861                         if ((tmpsecs & 0x80000000) != 0)
1862                                 time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
1863                         else
1864                                 time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
1865
1866                         if (length == 8) {
1867                                 /*
1868                                  * Convert 1/2^32s of a second to nanoseconds.
1869                                  */
1870                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1871                         } else if (length == 4) {
1872                                 /*
1873                                  * Backwards compatibility.
1874                                  */
1875                                 time_stamp->nsecs = 0;
1876                         } else {
1877                                 time_stamp->secs  = 0;
1878                                 time_stamp->nsecs = 0;
1879                                 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
1880                         }
1881                         break;
1882
1883                 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1884                         /*
1885                          * S/3x0 and z/Architecture TOD clock time stamp,
1886                          * big-endian.
1887                          * Only supported for absolute times.
1888                          */
1889                         DISSECTOR_ASSERT(!is_relative);
1890                         DISSECTOR_ASSERT(length == 8);
1891
1892                         if (length == 8) {
1893                                 todsecs  = tvb_get_ntoh64(tvb, start) >> 12;
1894                                 time_stamp->secs = (time_t)((todsecs  / 1000000) - TOD_BASETIME);
1895                                 time_stamp->nsecs = (int)((todsecs  % 1000000) * 1000);
1896                         } else {
1897                                 time_stamp->secs  = 0;
1898                                 time_stamp->nsecs = 0;
1899                                 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
1900                         }
1901                         break;
1902
1903                 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1904                         /*
1905                          * S/3x0 and z/Architecture TOD clock time stamp,
1906                          * little-endian.
1907                          * Only supported for absolute times.
1908                          */
1909                         DISSECTOR_ASSERT(!is_relative);
1910
1911                         if (length == 8) {
1912                                 todsecs  = tvb_get_letoh64(tvb, start) >> 12 ;
1913                                 time_stamp->secs = (time_t)((todsecs  / 1000000) - TOD_BASETIME);
1914                                 time_stamp->nsecs = (int)((todsecs  % 1000000) * 1000);
1915                         } else {
1916                                 time_stamp->secs  = 0;
1917                                 time_stamp->nsecs = 0;
1918                                 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
1919                         }
1920                         break;
1921
1922                 case ENC_TIME_RTPS|ENC_BIG_ENDIAN:
1923                         /*
1924                          * Time stamp using the same seconds/fraction format
1925                          * as NTP, but with the origin of the time stamp being
1926                          * the UNIX epoch rather than the NTP epoch; big-
1927                          * endian.
1928                          *
1929                          * Only supported for absolute times.
1930                          */
1931                         DISSECTOR_ASSERT(!is_relative);
1932
1933                         if (length == 8) {
1934                                 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1935                                 /*
1936                                  * Convert 1/2^32s of a second to nanoseconds.
1937                                  */
1938                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1939                         } else {
1940                                 time_stamp->secs  = 0;
1941                                 time_stamp->nsecs = 0;
1942                                 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
1943                         }
1944                         break;
1945
1946                 case ENC_TIME_RTPS|ENC_LITTLE_ENDIAN:
1947                         /*
1948                          * Time stamp using the same seconds/fraction format
1949                          * as NTP, but with the origin of the time stamp being
1950                          * the UNIX epoch rather than the NTP epoch; little-
1951                          * endian.
1952                          *
1953                          * Only supported for absolute times.
1954                          */
1955                         DISSECTOR_ASSERT(!is_relative);
1956
1957                         if (length == 8) {
1958                                 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1959                                 /*
1960                                  * Convert 1/2^32s of a second to nanoseconds.
1961                                  */
1962                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1963                         } else {
1964                                 time_stamp->secs  = 0;
1965                                 time_stamp->nsecs = 0;
1966                                 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
1967                         }
1968                         break;
1969
1970                 case ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN:
1971                         /*
1972                          * 4-byte seconds, followed by 4-byte fractional
1973                          * time in microseconds, both big-endian.
1974                          * For absolute times, the seconds are seconds
1975                          * since the UN*X epoch.
1976                          */
1977                         if (length == 8) {
1978                                 time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
1979                                 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
1980                         } else {
1981                                 time_stamp->secs  = 0;
1982                                 time_stamp->nsecs = 0;
1983                                 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
1984                         }
1985                         break;
1986
1987                 case ENC_TIME_SECS_USECS|ENC_LITTLE_ENDIAN:
1988                         /*
1989                          * 4-byte seconds, followed by 4-byte fractional
1990                          * time in microseconds, both little-endian.
1991                          * For absolute times, the seconds are seconds
1992                          * since the UN*X epoch.
1993                          */
1994                         if (length == 8) {
1995                                 time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
1996                                 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
1997                         } else {
1998                                 time_stamp->secs  = 0;
1999                                 time_stamp->nsecs = 0;
2000                                 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2001                         }
2002                         break;
2003
2004                 case ENC_TIME_SECS|ENC_BIG_ENDIAN:
2005                 case ENC_TIME_SECS|ENC_LITTLE_ENDIAN:
2006                         /*
2007                          * Seconds, 1 to 8 bytes.
2008                          * For absolute times, it's seconds since the
2009                          * UN*X epoch.
2010                          */
2011                         if (length >= 1 && length <= 8) {
2012                                 time_stamp->secs  = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2013                                 time_stamp->nsecs = 0;
2014                         } else {
2015                                 time_stamp->secs  = 0;
2016                                 time_stamp->nsecs = 0;
2017                                 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2018                         }
2019                         break;
2020
2021                 case ENC_TIME_MSECS|ENC_BIG_ENDIAN:
2022                         /*
2023                          * Milliseconds, 1 to 8 bytes.
2024                          * For absolute times, it's milliseconds since the
2025                          * UN*X epoch.
2026                          */
2027                         if (length >= 1 && length <= 8) {
2028                                 guint64 msecs;
2029
2030                                 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2031                                 time_stamp->secs  = (time_t)(msecs / 1000);
2032                                 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2033                         } else {
2034                                 time_stamp->secs  = 0;
2035                                 time_stamp->nsecs = 0;
2036                                 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2037                         }
2038                         break;
2039
2040                 case ENC_TIME_RFC_3971|ENC_BIG_ENDIAN:
2041                         /*
2042                          * 1/64ths of a second since the UN*X epoch,
2043                          * big-endian.
2044                          *
2045                          * Only supported for absolute times.
2046                          */
2047                         DISSECTOR_ASSERT(!is_relative);
2048
2049                         if (length == 8) {
2050                                 /*
2051                                  * The upper 48 bits are seconds since the
2052                                  * UN*X epoch.
2053                                  */
2054                                 time_stamp->secs  = tvb_get_ntoh48(tvb, start);
2055                                 /*
2056                                  * The lower 16 bits are 1/2^16s of a second;
2057                                  * convert them to nanoseconds.
2058                                  *
2059                                  * XXX - this may give the impression of higher
2060                                  * precision than you actually get.
2061                                  */
2062                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2063                         } else {
2064                                 time_stamp->secs  = 0;
2065                                 time_stamp->nsecs = 0;
2066                                 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2067                         }
2068                         break;
2069
2070                 case ENC_TIME_RFC_3971|ENC_LITTLE_ENDIAN:
2071                         /*
2072                          * 1/64ths of a second since the UN*X epoch,
2073                          * little-endian.
2074                          *
2075                          * Only supported for absolute times.
2076                          */
2077                         DISSECTOR_ASSERT(!is_relative);
2078
2079                         if (length == 8) {
2080                                 /*
2081                                  * XXX - this is assuming that, if anybody
2082                                  * were ever to use this format - RFC 3971
2083                                  * doesn't, because that's an Internet
2084                                  * protocol, and those use network byte
2085                                  * order, i.e. big-endian - they'd treat it
2086                                  * as a 64-bit count of 1/2^16s of a second,
2087                                  * putting the upper 48 bits at the end.
2088                                  *
2089                                  * The lower 48 bits are seconds since the
2090                                  * UN*X epoch.
2091                                  */
2092                                 time_stamp->secs  = tvb_get_letoh48(tvb, start+2);
2093                                 /*
2094                                  * The upper 16 bits are 1/2^16s of a second;
2095                                  * convert them to nanoseconds.
2096                                  *
2097                                  * XXX - this may give the impression of higher
2098                                  * precision than you actually get.
2099                                  */
2100                                 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2101                         } else {
2102                                 time_stamp->secs  = 0;
2103                                 time_stamp->nsecs = 0;
2104                                 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2105                         }
2106                         break;
2107
2108                 case ENC_TIME_SECS_NTP|ENC_BIG_ENDIAN:
2109                         /*
2110                          * NTP time stamp, with 1-second resolution (i.e.,
2111                          * seconds since the NTP epoch), big-endian.
2112                          * Only supported for absolute times.
2113                          */
2114                         DISSECTOR_ASSERT(!is_relative);
2115
2116                         if (length == 4) {
2117                                 /*
2118                                 * We need a temporary variable here so the unsigned math
2119                                 * works correctly (for years > 2036 according to RFC 2030
2120                                 * chapter 3).
2121                                 *
2122                                 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2123                                 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2124                                 * If bit 0 is not set, the time is in the range 2036-2104 and
2125                                 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2126                                 */
2127                                 tmpsecs  = tvb_get_ntohl(tvb, start);
2128                                 if ((tmpsecs & 0x80000000) != 0)
2129                                         time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2130                                 else
2131                                         time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2132                                 time_stamp->nsecs = 0;
2133                         } else {
2134                                 time_stamp->secs  = 0;
2135                                 time_stamp->nsecs = 0;
2136                                 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2137                         }
2138                         break;
2139
2140                 case ENC_TIME_SECS_NTP|ENC_LITTLE_ENDIAN:
2141                         /*
2142                          * NTP time stamp, with 1-second resolution (i.e.,
2143                          * seconds since the NTP epoch), little-endian.
2144                          * Only supported for absolute times.
2145                          */
2146                         DISSECTOR_ASSERT(!is_relative);
2147
2148                         /*
2149                          * We need a temporary variable here so the unsigned math
2150                          * works correctly (for years > 2036 according to RFC 2030
2151                          * chapter 3).
2152                          *
2153                          * If bit 0 is set, the UTC time is in the range 1968-2036 and
2154                          * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2155                          * If bit 0 is not set, the time is in the range 2036-2104 and
2156                          * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2157                          */
2158                         if (length == 4) {
2159                                 tmpsecs  = tvb_get_letohl(tvb, start);
2160                                 if ((tmpsecs & 0x80000000) != 0)
2161                                         time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2162                                 else
2163                                         time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2164                                 time_stamp->nsecs = 0;
2165                         } else {
2166                                 time_stamp->secs  = 0;
2167                                 time_stamp->nsecs = 0;
2168                                 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2169                         }
2170                         break;
2171                 case ENC_TIME_MSEC_NTP | ENC_BIG_ENDIAN:
2172                         /*
2173                         * Milliseconds, 1 to 8 bytes.
2174                         * For absolute times, it's milliseconds since the
2175                         * NTP epoch.
2176                         */
2177                         if (length >= 1 && length <= 8) {
2178                                 guint64 msecs;
2179
2180                                 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2181                                 tmpsecs = (guint32)(msecs / 1000);
2182                                 /*
2183                                 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2184                                 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2185                                 * If bit 0 is not set, the time is in the range 2036-2104 and
2186                                 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2187                                 */
2188                                 if ((tmpsecs & 0x80000000) != 0)
2189                                         time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2190                                 else
2191                                         time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2192                                 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2193                         }
2194                         else {
2195                                 time_stamp->secs  = 0;
2196                                 time_stamp->nsecs = 0;
2197                                 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 4));
2198                         }
2199                         break;
2200                 default:
2201                         DISSECTOR_ASSERT_NOT_REACHED();
2202                         break;
2203         }
2204 }
2205
2206 static void
2207 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2208 {
2209         const header_field_info *hfinfo = fi->hfinfo;
2210
2211         if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
2212                 GPtrArray *ptrs = NULL;
2213
2214                 if (tree_data->interesting_hfids == NULL) {
2215                         /* Initialize the hash because we now know that it is needed */
2216                         tree_data->interesting_hfids =
2217                                 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
2218                 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2219                         ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2220                                            GINT_TO_POINTER(hfinfo->id));
2221                 }
2222
2223                 if (!ptrs) {
2224                         /* First element triggers the creation of pointer array */
2225                         ptrs = g_ptr_array_new();
2226                         g_hash_table_insert(tree_data->interesting_hfids,
2227                                             GINT_TO_POINTER(hfinfo->id), ptrs);
2228                 }
2229
2230                 g_ptr_array_add(ptrs, fi);
2231         }
2232 }
2233
2234
2235 /*
2236  * Validates that field length bytes are available starting from
2237  * start (pos/neg). Throws an exception if they aren't.
2238  */
2239 static void
2240 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2241             gint start, gint length, const guint encoding)
2242 {
2243         gint size = length;
2244
2245         if (!tvb)
2246                 return;
2247
2248         if ((hfinfo->type == FT_STRINGZ) ||
2249             ((encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC)) &&
2250              (IS_FT_UINT(hfinfo->type) || IS_FT_INT(hfinfo->type)))) {
2251                 /* If we're fetching until the end of the TVB, only validate
2252                  * that the offset is within range.
2253                  */
2254                 if (length == -1)
2255                         size = 0;
2256         }
2257
2258         tvb_ensure_bytes_exist(tvb, start, size);
2259 }
2260
2261 static void
2262 detect_trailing_stray_characters(enum ftenum type, guint encoding, const char *string, gint length, proto_item *pi)
2263 {
2264         gboolean found_stray_character = FALSE;
2265
2266         if (!string)
2267                 return;
2268
2269         if (type != FT_STRING && type != FT_STRINGZ && type != FT_STRINGZPAD)
2270                 return;
2271
2272         switch (encoding & ENC_CHARENCODING_MASK) {
2273                 case ENC_ASCII:
2274                 case ENC_UTF_8:
2275                         for (gint i = (gint)strlen(string); i < length; i++) {
2276                                 if (string[i] != '\0') {
2277                                         found_stray_character = TRUE;
2278                                         break;
2279                                 }
2280                         }
2281                         break;
2282
2283                 default:
2284                         break;
2285         }
2286
2287         if (found_stray_character) {
2288                 expert_add_info(NULL, pi, &ei_string_trailing_characters);
2289         }
2290 }
2291
2292 /* Add an item to a proto_tree, using the text label registered to that item;
2293    the item is extracted from the tvbuff handed to it. */
2294 static proto_item *
2295 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2296                     tvbuff_t *tvb, gint start, gint length,
2297                     guint encoding)
2298 {
2299         proto_item *pi;
2300         guint32     value, n;
2301         guint64     value64;
2302         float       floatval;
2303         double      doubleval;
2304         const char *stringval = NULL;
2305         nstime_t    time_stamp;
2306         gboolean    length_error;
2307
2308         switch (new_fi->hfinfo->type) {
2309                 case FT_NONE:
2310                         /* no value to set for FT_NONE */
2311                         break;
2312
2313                 case FT_PROTOCOL:
2314                         proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
2315                         break;
2316
2317                 case FT_BYTES:
2318                         proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2319                         break;
2320
2321                 case FT_UINT_BYTES:
2322                         n = get_uint_value(tree, tvb, start, length, encoding);
2323                         proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2324
2325                         /* Instead of calling proto_item_set_len(), since we don't yet
2326                          * have a proto_item, we set the field_info's length ourselves. */
2327                         new_fi->length = n + length;
2328                         break;
2329
2330                 case FT_BOOLEAN:
2331                         /*
2332                          * Map all non-zero values to little-endian for
2333                          * backwards compatibility.
2334                          */
2335                         if (encoding)
2336                                 encoding = ENC_LITTLE_ENDIAN;
2337                         proto_tree_set_boolean(new_fi,
2338                                 get_uint64_value(tree, tvb, start, length, encoding));
2339                         break;
2340
2341                 case FT_CHAR:
2342                 /* XXX - make these just FT_UINT? */
2343                 case FT_UINT8:
2344                 case FT_UINT16:
2345                 case FT_UINT24:
2346                 case FT_UINT32:
2347                         if (encoding & ENC_VARINT_PROTOBUF) {
2348                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2349                                 new_fi->flags |= FI_VARINT;
2350                                 value = (guint32)value64;
2351                         } else if (encoding & ENC_VARINT_QUIC) {
2352                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2353                                 value = (guint32)value64;
2354                         } else {
2355                                 /*
2356                                  * Map all non-zero values to little-endian for
2357                                  * backwards compatibility.
2358                                  */
2359                                 if (encoding)
2360                                         encoding = ENC_LITTLE_ENDIAN;
2361
2362                                 value = get_uint_value(tree, tvb, start, length, encoding);
2363                         }
2364                         proto_tree_set_uint(new_fi, value);
2365                         break;
2366
2367                 case FT_UINT40:
2368                 case FT_UINT48:
2369                 case FT_UINT56:
2370                 case FT_UINT64:
2371
2372                         if (encoding & ENC_VARINT_PROTOBUF) {
2373                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2374                                 new_fi->flags |= FI_VARINT;
2375                         } else if (encoding & ENC_VARINT_QUIC) {
2376                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2377                         } else {
2378                                 /*
2379                                  * Map all other non-zero values to little-endian for
2380                                  * backwards compatibility.
2381                                  */
2382                                 if (encoding)
2383                                         encoding = ENC_LITTLE_ENDIAN;
2384
2385                                 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2386                         }
2387                         proto_tree_set_uint64(new_fi, value64);
2388                         break;
2389
2390                 /* XXX - make these just FT_INT? */
2391                 case FT_INT8:
2392                 case FT_INT16:
2393                 case FT_INT24:
2394                 case FT_INT32:
2395                         /*
2396                          * Map all non-zero values to little-endian for
2397                          * backwards compatibility.
2398                          */
2399                         if (encoding)
2400                                 encoding = ENC_LITTLE_ENDIAN;
2401                         proto_tree_set_int(new_fi,
2402                                 get_int_value(tree, tvb, start, length, encoding));
2403                         break;
2404
2405                 case FT_INT40:
2406                 case FT_INT48:
2407                 case FT_INT56:
2408                 case FT_INT64:
2409                         /*
2410                          * Map all non-zero values to little-endian for
2411                          * backwards compatibility.
2412                          */
2413                         if (encoding)
2414                                 encoding = ENC_LITTLE_ENDIAN;
2415                         proto_tree_set_int64(new_fi,
2416                                 get_int64_value(tree, tvb, start, length, encoding));
2417                         break;
2418
2419                 case FT_IPv4:
2420                         /*
2421                          * Map all non-zero values to little-endian for
2422                          * backwards compatibility.
2423                          */
2424                         if (encoding)
2425                                 encoding = ENC_LITTLE_ENDIAN;
2426                         if (length != FT_IPv4_LEN) {
2427                                 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
2428                                 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2429                         }
2430                         value = tvb_get_ipv4(tvb, start);
2431                         /*
2432                          * NOTE: to support code written when
2433                          * proto_tree_add_item() took a gboolean as its
2434                          * last argument, with FALSE meaning "big-endian"
2435                          * and TRUE meaning "little-endian", we treat any
2436                          * non-zero value of "encoding" as meaning
2437                          * "little-endian".
2438                          */
2439                         proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
2440                         break;
2441
2442                 case FT_IPXNET:
2443                         if (length != FT_IPXNET_LEN) {
2444                                 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
2445                                 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2446                         }
2447                         proto_tree_set_ipxnet(new_fi,
2448                                 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
2449                         break;
2450
2451                 case FT_IPv6:
2452                         if (length != FT_IPv6_LEN) {
2453                                 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
2454                                 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2455                         }
2456                         proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2457                         break;
2458
2459                 case FT_FCWWN:
2460                         if (length != FT_FCWWN_LEN) {
2461                                 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2462                                 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2463                         }
2464                         proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2465                         break;
2466
2467                 case FT_AX25:
2468                         if (length != 7) {
2469                                 length_error = length < 7 ? TRUE : FALSE;
2470                                 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2471                         }
2472                         proto_tree_set_ax25_tvb(new_fi, tvb, start);
2473                         break;
2474
2475                 case FT_VINES:
2476                         if (length != VINES_ADDR_LEN) {
2477                                 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2478                                 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2479                         }
2480                         proto_tree_set_vines_tvb(new_fi, tvb, start);
2481                         break;
2482
2483                 case FT_ETHER:
2484                         if (length != FT_ETHER_LEN) {
2485                                 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2486                                 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2487                         }
2488                         proto_tree_set_ether_tvb(new_fi, tvb, start);
2489                         break;
2490
2491                 case FT_EUI64:
2492                         /*
2493                          * Map all non-zero values to little-endian for
2494                          * backwards compatibility.
2495                          */
2496                         if (encoding)
2497                                 encoding = ENC_LITTLE_ENDIAN;
2498                         if (length != FT_EUI64_LEN) {
2499                                 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2500                                 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2501                         }
2502                         proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2503                         break;
2504                 case FT_GUID:
2505                         /*
2506                          * Map all non-zero values to little-endian for
2507                          * backwards compatibility.
2508                          */
2509                         if (encoding)
2510                                 encoding = ENC_LITTLE_ENDIAN;
2511                         if (length != FT_GUID_LEN) {
2512                                 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2513                                 report_type_length_mismatch(tree, "a GUID", length, length_error);
2514                         }
2515                         proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2516                         break;
2517
2518                 case FT_OID:
2519                 case FT_REL_OID:
2520                         proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2521                         break;
2522
2523                 case FT_SYSTEM_ID:
2524                         proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2525                         break;
2526
2527                 case FT_FLOAT:
2528                         /*
2529                          * NOTE: to support code written when
2530                          * proto_tree_add_item() took a gboolean as its
2531                          * last argument, with FALSE meaning "big-endian"
2532                          * and TRUE meaning "little-endian", we treat any
2533                          * non-zero value of "encoding" as meaning
2534                          * "little-endian".
2535                          *
2536                          * At some point in the future, we might
2537                          * support non-IEEE-binary floating-point
2538                          * formats in the encoding as well
2539                          * (IEEE decimal, System/3x0, VAX).
2540                          */
2541                         if (encoding)
2542                                 encoding = ENC_LITTLE_ENDIAN;
2543                         if (length != 4) {
2544                                 length_error = length < 4 ? TRUE : FALSE;
2545                                 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2546                         }
2547                         if (encoding)
2548                                 floatval = tvb_get_letohieee_float(tvb, start);
2549                         else
2550                                 floatval = tvb_get_ntohieee_float(tvb, start);
2551                         proto_tree_set_float(new_fi, floatval);
2552                         break;
2553
2554                 case FT_DOUBLE:
2555                         /*
2556                          * NOTE: to support code written when
2557                          * proto_tree_add_item() took a gboolean as its
2558                          * last argument, with FALSE meaning "big-endian"
2559                          * and TRUE meaning "little-endian", we treat any
2560                          * non-zero value of "encoding" as meaning
2561                          * "little-endian".
2562                          *
2563                          * At some point in the future, we might
2564                          * support non-IEEE-binary floating-point
2565                          * formats in the encoding as well
2566                          * (IEEE decimal, System/3x0, VAX).
2567                          */
2568                         if (encoding == TRUE)
2569                                 encoding = ENC_LITTLE_ENDIAN;
2570                         if (length != 8) {
2571                                 length_error = length < 8 ? TRUE : FALSE;
2572                                 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2573                         }
2574                         if (encoding)
2575                                 doubleval = tvb_get_letohieee_double(tvb, start);
2576                         else
2577                                 doubleval = tvb_get_ntohieee_double(tvb, start);
2578                         proto_tree_set_double(new_fi, doubleval);
2579                         break;
2580
2581                 case FT_STRING:
2582                         stringval = get_string_value(wmem_packet_scope(),
2583                             tvb, start, length, &length, encoding);
2584                         proto_tree_set_string(new_fi, stringval);
2585
2586                         /* Instead of calling proto_item_set_len(), since we
2587                          * don't yet have a proto_item, we set the
2588                          * field_info's length ourselves.
2589                          *
2590                          * XXX - our caller can't use that length to
2591                          * advance an offset unless they arrange that
2592                          * there always be a protocol tree into which
2593                          * we're putting this item.
2594                          */
2595                         new_fi->length = length;
2596                         break;
2597
2598                 case FT_STRINGZ:
2599                         stringval = get_stringz_value(wmem_packet_scope(),
2600                             tree, tvb, start, length, &length, encoding);
2601                         proto_tree_set_string(new_fi, stringval);
2602
2603                         /* Instead of calling proto_item_set_len(),
2604                          * since we don't yet have a proto_item, we
2605                          * set the field_info's length ourselves.
2606                          *
2607                          * XXX - our caller can't use that length to
2608                          * advance an offset unless they arrange that
2609                          * there always be a protocol tree into which
2610                          * we're putting this item.
2611                          */
2612                         new_fi->length = length;
2613                         break;
2614
2615                 case FT_UINT_STRING:
2616                         /*
2617                          * NOTE: to support code written when
2618                          * proto_tree_add_item() took a gboolean as its
2619                          * last argument, with FALSE meaning "big-endian"
2620                          * and TRUE meaning "little-endian", if the
2621                          * encoding value is TRUE, treat that as
2622                          * ASCII with a little-endian length.
2623                          *
2624                          * This won't work for code that passes
2625                          * arbitrary non-zero values; that code
2626                          * will need to be fixed.
2627                          */
2628                         if (encoding == TRUE)
2629                                 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2630                         stringval = get_uint_string_value(wmem_packet_scope(),
2631                             tree, tvb, start, length, &length, encoding);
2632                         proto_tree_set_string(new_fi, stringval);
2633
2634                         /* Instead of calling proto_item_set_len(), since we
2635                          * don't yet have a proto_item, we set the
2636                          * field_info's length ourselves.
2637                          *
2638                          * XXX - our caller can't use that length to
2639                          * advance an offset unless they arrange that
2640                          * there always be a protocol tree into which
2641                          * we're putting this item.
2642                          */
2643                         new_fi->length = length;
2644                         break;
2645
2646                 case FT_STRINGZPAD:
2647                         stringval = get_stringzpad_value(wmem_packet_scope(),
2648                             tvb, start, length, &length, encoding);
2649                         proto_tree_set_string(new_fi, stringval);
2650
2651                         /* Instead of calling proto_item_set_len(), since we
2652                          * don't yet have a proto_item, we set the
2653                          * field_info's length ourselves.
2654                          *
2655                          * XXX - our caller can't use that length to
2656                          * advance an offset unless they arrange that
2657                          * there always be a protocol tree into which
2658                          * we're putting this item.
2659                          */
2660                         new_fi->length = length;
2661                         break;
2662
2663                 case FT_ABSOLUTE_TIME:
2664                         /*
2665                          * Absolute times can be in any of a number of
2666                          * formats, and they can be big-endian or
2667                          * little-endian.
2668                          *
2669                          * Historically FT_TIMEs were only timespecs;
2670                          * the only question was whether they were stored
2671                          * in big- or little-endian format.
2672                          *
2673                          * For backwards compatibility, we interpret an
2674                          * encoding of 1 as meaning "little-endian timespec",
2675                          * so that passing TRUE is interpreted as that.
2676                          */
2677                         if (encoding == TRUE)
2678                                 encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2679
2680                         get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
2681
2682                         proto_tree_set_time(new_fi, &time_stamp);
2683                         break;
2684
2685                 case FT_RELATIVE_TIME:
2686                         /*
2687                          * Relative times can be in any of a number of
2688                          * formats, and they can be big-endian or
2689                          * little-endian.
2690                          *
2691                          * Historically FT_TIMEs were only timespecs;
2692                          * the only question was whether they were stored
2693                          * in big- or little-endian format.
2694                          *
2695                          * For backwards compatibility, we interpret an
2696                          * encoding of 1 as meaning "little-endian timespec",
2697                          * so that passing TRUE is interpreted as that.
2698                          */
2699                         if (encoding == TRUE)
2700                                 encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2701
2702                         get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
2703
2704                         proto_tree_set_time(new_fi, &time_stamp);
2705                         break;
2706                 case FT_IEEE_11073_SFLOAT:
2707                         if (encoding)
2708                                 encoding = ENC_LITTLE_ENDIAN;
2709                         if (length != 2) {
2710                                 length_error = length < 2 ? TRUE : FALSE;
2711                                 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2712                         }
2713
2714                         fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2715
2716                         break;
2717                 case FT_IEEE_11073_FLOAT:
2718                         if (encoding)
2719                                 encoding = ENC_LITTLE_ENDIAN;
2720                         if (length != 4) {
2721                                 length_error = length < 4 ? TRUE : FALSE;
2722                                 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2723                         }
2724
2725                         break;
2726                 default:
2727                         g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2728                                         new_fi->hfinfo->type,
2729                                         ftype_name(new_fi->hfinfo->type));
2730                         DISSECTOR_ASSERT_NOT_REACHED();
2731                         break;
2732         }
2733         FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2734
2735         /* Don't add new node to proto_tree until now so that any exceptions
2736          * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2737         /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2738          *      to know which item caused exception? */
2739         pi = proto_tree_add_node(tree, new_fi);
2740
2741         detect_trailing_stray_characters(new_fi->hfinfo->type, encoding, stringval, length, pi);
2742
2743         return pi;
2744 }
2745
2746 proto_item *
2747 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2748                             const gint start, gint length,
2749                             const guint encoding, gint32 *retval)
2750 {
2751         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2752         field_info        *new_fi;
2753         gint32             value;
2754
2755         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2756
2757         switch (hfinfo->type) {
2758         case FT_INT8:
2759         case FT_INT16:
2760         case FT_INT24:
2761         case FT_INT32:
2762                 break;
2763         default:
2764                 DISSECTOR_ASSERT_NOT_REACHED();
2765         }
2766
2767         /* length validation for native number encoding caught by get_uint_value() */
2768         /* length has to be -1 or > 0 regardless of encoding */
2769         if (length < -1 || length == 0)
2770                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_int",
2771                         length);
2772
2773         if (encoding & ENC_STRING) {
2774                 REPORT_DISSECTOR_BUG("wrong encoding");
2775         }
2776         /* I believe it's ok if this is called with a NULL tree */
2777         value = get_int_value(tree, tvb, start, length, encoding);
2778
2779         if (retval) {
2780                 gint no_of_bits;
2781                 *retval = value;
2782                 if (hfinfo->bitmask) {
2783                         /* Mask out irrelevant portions */
2784                         *retval &= (guint32)(hfinfo->bitmask);
2785                         /* Shift bits */
2786                         *retval >>= hfinfo_bitshift(hfinfo);
2787                 }
2788                 no_of_bits = ws_count_ones(hfinfo->bitmask);
2789                 *retval = ws_sign_ext32(*retval, no_of_bits);
2790         }
2791
2792         CHECK_FOR_NULL_TREE(tree);
2793
2794         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2795
2796         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2797
2798         proto_tree_set_int(new_fi, value);
2799
2800         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2801
2802         return proto_tree_add_node(tree, new_fi);
2803 }
2804
2805 proto_item *
2806 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2807                              const gint start, gint length,
2808                              const guint encoding, guint32 *retval)
2809 {
2810         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2811         field_info        *new_fi;
2812         guint32            value;
2813
2814         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2815
2816         switch (hfinfo->type) {
2817         case FT_CHAR:
2818         case FT_UINT8:
2819         case FT_UINT16:
2820         case FT_UINT24:
2821         case FT_UINT32:
2822                 break;
2823         default:
2824                 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2825                     hfinfo->abbrev);
2826         }
2827
2828         /* length validation for native number encoding caught by get_uint_value() */
2829         /* length has to be -1 or > 0 regardless of encoding */
2830         if (length < -1 || length == 0)
2831                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
2832                         length);
2833
2834         if (encoding & ENC_STRING) {
2835                 REPORT_DISSECTOR_BUG("wrong encoding");
2836         }
2837         /* I believe it's ok if this is called with a NULL tree */
2838         /* XXX - modify if we ever support EBCDIC FT_CHAR */
2839         if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC)) {
2840                 guint64 temp64;
2841                 tvb_get_varint(tvb, start, length, &temp64, encoding);
2842                 value = (guint32)temp64;
2843         } else {
2844                 value = get_uint_value(tree, tvb, start, length, encoding);
2845         }
2846
2847         if (retval) {
2848                 *retval = value;
2849                 if (hfinfo->bitmask) {
2850                         /* Mask out irrelevant portions */
2851                         *retval &= (guint32)(hfinfo->bitmask);
2852                         /* Shift bits */
2853                         *retval >>= hfinfo_bitshift(hfinfo);
2854                 }
2855         }
2856
2857         CHECK_FOR_NULL_TREE(tree);
2858
2859         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2860
2861         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2862
2863         proto_tree_set_uint(new_fi, value);
2864
2865         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2866         if (encoding & ENC_VARINT_PROTOBUF) {
2867                 new_fi->flags |= FI_VARINT;
2868         }
2869         return proto_tree_add_node(tree, new_fi);
2870 }
2871
2872 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2873  * and returns proto_item* and uint value retreived*/
2874 proto_item *
2875 ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, gint length,
2876               const guint encoding, guint32 *retval)
2877 {
2878         field_info        *new_fi;
2879         header_field_info *hfinfo;
2880         gint               item_length;
2881         int                offset;
2882         guint32            value;
2883
2884         offset = ptvc->offset;
2885         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2886
2887         switch (hfinfo->type) {
2888         case FT_CHAR:
2889         case FT_UINT8:
2890         case FT_UINT16:
2891         case FT_UINT24:
2892         case FT_UINT32:
2893                 break;
2894         default:
2895                 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2896                     hfinfo->abbrev);
2897         }
2898
2899         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
2900         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
2901
2902         /* I believe it's ok if this is called with a NULL tree */
2903         /* XXX - modify if we ever support EBCDIC FT_CHAR */
2904         value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
2905
2906         if (retval) {
2907                 *retval = value;
2908                 if (hfinfo->bitmask) {
2909                         /* Mask out irrelevant portions */
2910                         *retval &= (guint32)(hfinfo->bitmask);
2911                         /* Shift bits */
2912                         *retval >>= hfinfo_bitshift(hfinfo);
2913                 }
2914         }
2915
2916         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2917             item_length, encoding);
2918
2919         CHECK_FOR_NULL_TREE(ptvc->tree);
2920
2921         /* Coast clear. Try and fake it */
2922         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2923
2924         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2925
2926         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2927                 offset, length, encoding);
2928 }
2929
2930 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2931  * and returns proto_item* and int value retreived*/
2932 proto_item *
2933 ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, gint length,
2934               const guint encoding, gint32 *retval)
2935 {
2936         field_info        *new_fi;
2937         header_field_info *hfinfo;
2938         gint               item_length;
2939         int                offset;
2940         guint32            value;
2941
2942         offset = ptvc->offset;
2943         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2944
2945         switch (hfinfo->type) {
2946         case FT_INT8:
2947         case FT_INT16:
2948         case FT_INT24:
2949         case FT_INT32:
2950                 break;
2951         default:
2952                 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2953                     hfinfo->abbrev);
2954         }
2955
2956         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
2957         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
2958
2959         /* I believe it's ok if this is called with a NULL tree */
2960         /* XXX - modify if we ever support EBCDIC FT_CHAR */
2961         value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
2962
2963         if (retval) {
2964                 gint no_of_bits;
2965                 *retval = value;
2966                 if (hfinfo->bitmask) {
2967                         /* Mask out irrelevant portions */
2968                         *retval &= (guint32)(hfinfo->bitmask);
2969                         /* Shift bits */
2970                         *retval >>= hfinfo_bitshift(hfinfo);
2971                 }
2972                 no_of_bits = ws_count_ones(hfinfo->bitmask);
2973                 *retval = ws_sign_ext32(*retval, no_of_bits);
2974         }
2975
2976         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2977             item_length, encoding);
2978
2979         CHECK_FOR_NULL_TREE(ptvc->tree);
2980
2981         /* Coast clear. Try and fake it */
2982         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2983
2984         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2985
2986         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2987                 offset, length, encoding);
2988 }
2989
2990 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2991  * and returns proto_item* and string value retreived */
2992 proto_item*
2993 ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, wmem_allocator_t *scope, const guint8 **retval)
2994 {
2995         header_field_info *hfinfo;
2996         field_info              *new_fi;
2997         const guint8    *value;
2998         gint                    item_length;
2999         int                             offset;
3000
3001         offset = ptvc->offset;
3002
3003         PROTO_REGISTRAR_GET_NTH(hf, hfinfo);
3004
3005         switch (hfinfo->type) {
3006         case FT_STRING:
3007                 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3008                 break;
3009         case FT_STRINGZ:
3010                 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3011                 break;
3012         case FT_UINT_STRING:
3013                 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3014                 break;
3015         case FT_STRINGZPAD:
3016                 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3017                 break;
3018         default:
3019                 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, or FT_STRINGZPAD",
3020                     hfinfo->abbrev);
3021         }
3022
3023         if (retval)
3024                 *retval = value;
3025
3026         ptvc->offset += item_length;
3027
3028         CHECK_FOR_NULL_TREE(ptvc->tree);
3029
3030         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3031
3032         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3033
3034         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3035                 offset, length, encoding);
3036 }
3037
3038 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3039  * and returns proto_item* and boolean value retreived */
3040 proto_item*
3041 ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, gint length, const guint encoding, gboolean *retval)
3042 {
3043         header_field_info *hfinfo;
3044         field_info              *new_fi;
3045         gint                    item_length;
3046         int                             offset;
3047         guint64                 value, bitval;
3048
3049         offset = ptvc->offset;
3050         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3051
3052         if (hfinfo->type != FT_BOOLEAN) {
3053                 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3054                     hfinfo->abbrev);
3055         }
3056
3057         /* length validation for native number encoding caught by get_uint64_value() */
3058         /* length has to be -1 or > 0 regardless of encoding */
3059         if (length < -1 || length == 0)
3060                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3061                         length);
3062
3063         if (encoding & ENC_STRING) {
3064                 REPORT_DISSECTOR_BUG("wrong encoding");
3065         }
3066
3067         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3068         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3069
3070         /* I believe it's ok if this is called with a NULL tree */
3071         value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3072
3073         if (retval) {
3074                 bitval = value;
3075                 if (hfinfo->bitmask) {
3076                         /* Mask out irrelevant portions */
3077                         bitval &= hfinfo->bitmask;
3078                 }
3079                 *retval = (bitval != 0);
3080         }
3081
3082         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3083             item_length, encoding);
3084
3085         CHECK_FOR_NULL_TREE(ptvc->tree);
3086
3087         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3088
3089         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3090
3091         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3092                 offset, length, encoding);
3093 }
3094
3095 proto_item *
3096 proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3097     const gint start, gint length, const guint encoding, guint64 *retval)
3098 {
3099         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3100         field_info        *new_fi;
3101         guint64            value;
3102
3103         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3104
3105         switch (hfinfo->type) {
3106         case FT_UINT40:
3107         case FT_UINT48:
3108         case FT_UINT56:
3109         case FT_UINT64:
3110                 break;
3111         default:
3112                 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
3113                     hfinfo->abbrev);
3114         }
3115
3116         /* length validation for native number encoding caught by get_uint64_value() */
3117         /* length has to be -1 or > 0 regardless of encoding */
3118         if (length < -1 || length == 0)
3119                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3120                         length);
3121
3122         if (encoding & ENC_STRING) {
3123                 REPORT_DISSECTOR_BUG("wrong encoding");
3124         }
3125         /* I believe it's ok if this is called with a NULL tree */
3126         if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC)) {
3127                 tvb_get_varint(tvb, start, length, &value, encoding);
3128         } else {
3129                 value = get_uint64_value(tree, tvb, start, length, encoding);
3130         }
3131
3132         if (retval) {
3133                 *retval = value;
3134                 if (hfinfo->bitmask) {
3135                         /* Mask out irrelevant portions */
3136                         *retval &= hfinfo->bitmask;
3137                         /* Shift bits */
3138                         *retval >>= hfinfo_bitshift(hfinfo);
3139                 }
3140         }
3141
3142         CHECK_FOR_NULL_TREE(tree);
3143
3144         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3145
3146         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3147
3148         proto_tree_set_uint64(new_fi, value);
3149
3150         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3151         if (encoding & ENC_VARINT_PROTOBUF) {
3152                 new_fi->flags |= FI_VARINT;
3153         }
3154
3155         return proto_tree_add_node(tree, new_fi);
3156 }
3157
3158 proto_item *
3159 proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3160     const gint start, gint length, const guint encoding, guint64 *retval, gint *lenretval)
3161 {
3162         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3163         field_info      *new_fi;
3164         guint64         value;
3165
3166         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3167
3168         if ((!IS_FT_INT(hfinfo->type)) && (!IS_FT_UINT(hfinfo->type))) {
3169                 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",
3170                     hfinfo->abbrev);
3171         }
3172
3173         /* length validation for native number encoding caught by get_uint64_value() */
3174         /* length has to be -1 or > 0 regardless of encoding */
3175         if (length == 0)
3176                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",
3177                         length);
3178
3179         if (encoding & ENC_STRING) {
3180                 REPORT_DISSECTOR_BUG("wrong encoding");
3181         }
3182
3183         length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value, encoding);
3184
3185         if (retval) {
3186                 *retval = value;
3187                 if (hfinfo->bitmask) {
3188                         /* Mask out irrelevant portions */
3189                         *retval &= hfinfo->bitmask;
3190                         /* Shift bits */
3191                         *retval >>= hfinfo_bitshift(hfinfo);
3192                 }
3193         }
3194
3195         if (lenretval) {
3196                 *lenretval = length;
3197         }
3198
3199         CHECK_FOR_NULL_TREE(tree);
3200
3201         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3202
3203         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3204
3205         proto_tree_set_uint64(new_fi, value);
3206
3207         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3208         if (encoding & ENC_VARINT_PROTOBUF) {
3209                 new_fi->flags |= FI_VARINT;
3210         }
3211
3212         return proto_tree_add_node(tree, new_fi);
3213
3214 }
3215
3216 proto_item *
3217 proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3218                                 const gint start, gint length,
3219                                 const guint encoding, gboolean *retval)
3220 {
3221         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3222         field_info        *new_fi;
3223         guint64            value, bitval;
3224
3225         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3226
3227         if (hfinfo->type != FT_BOOLEAN) {
3228                 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3229                     hfinfo->abbrev);
3230         }
3231
3232         /* length validation for native number encoding caught by get_uint64_value() */
3233         /* length has to be -1 or > 0 regardless of encoding */
3234         if (length < -1 || length == 0)
3235                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3236                         length);
3237
3238         if (encoding & ENC_STRING) {
3239                 REPORT_DISSECTOR_BUG("wrong encoding");
3240         }
3241         /* I believe it's ok if this is called with a NULL tree */
3242         value = get_uint64_value(tree, tvb, start, length, encoding);
3243
3244         if (retval) {
3245                 bitval = value;
3246                 if (hfinfo->bitmask) {
3247                         /* Mask out irrelevant portions */
3248                         bitval &= hfinfo->bitmask;
3249                 }
3250                 *retval = (bitval != 0);
3251         }
3252
3253         CHECK_FOR_NULL_TREE(tree);
3254
3255         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3256
3257         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3258
3259         proto_tree_set_boolean(new_fi, value);
3260
3261         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3262
3263         return proto_tree_add_node(tree, new_fi);
3264 }
3265
3266 proto_item *
3267 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
3268                                           tvbuff_t *tvb,
3269                                           const gint start, gint length,
3270                                           const guint encoding,
3271                                           wmem_allocator_t *scope,
3272                                           const guint8 **retval,
3273                                           gint *lenretval)
3274 {
3275         proto_item *pi;
3276         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3277         field_info        *new_fi;
3278         const guint8      *value;
3279
3280         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3281
3282         switch (hfinfo->type) {
3283         case FT_STRING:
3284                 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
3285                 break;
3286         case FT_STRINGZ:
3287                 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
3288                 break;
3289         case FT_UINT_STRING:
3290                 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
3291                 break;
3292         case FT_STRINGZPAD:
3293                 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
3294                 break;
3295         default:
3296                 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, or FT_STRINGZPAD",
3297                     hfinfo->abbrev);
3298         }
3299
3300         if (retval)
3301                 *retval = value;
3302
3303         CHECK_FOR_NULL_TREE(tree);
3304
3305         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3306
3307         new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
3308
3309         proto_tree_set_string(new_fi, value);
3310
3311         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3312
3313         pi = proto_tree_add_node(tree, new_fi);
3314
3315         detect_trailing_stray_characters(hfinfo->type, encoding, value, length, pi);
3316
3317         return pi;
3318 }
3319
3320 proto_item *
3321 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3322                                const gint start, gint length,
3323                                const guint encoding, wmem_allocator_t *scope,
3324                                const guint8 **retval)
3325 {
3326         return proto_tree_add_item_ret_string_and_length(tree, hfindex,
3327             tvb, start, length, encoding, scope, retval, &length);
3328 }
3329
3330
3331 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3332    and returns proto_item* */
3333 proto_item *
3334 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
3335               const guint encoding)
3336 {
3337         field_info        *new_fi;
3338         header_field_info *hfinfo;
3339         gint               item_length;
3340         int                offset;
3341
3342         offset = ptvc->offset;
3343         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3344         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3345         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3346
3347         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3348             item_length, encoding);
3349
3350         CHECK_FOR_NULL_TREE(ptvc->tree);
3351
3352         /* Coast clear. Try and fake it */
3353         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3354
3355         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3356
3357         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3358                 offset, length, encoding);
3359 }
3360
3361 /* Add an item to a proto_tree, using the text label registered to that item;
3362    the item is extracted from the tvbuff handed to it. */
3363 proto_item *
3364 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
3365                         const gint start, gint length, const guint encoding)
3366 {
3367         field_info        *new_fi;
3368         gint              item_length;
3369
3370         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3371
3372         get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3373         test_length(hfinfo, tvb, start, item_length, encoding);
3374
3375         CHECK_FOR_NULL_TREE(tree);
3376
3377         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3378
3379         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3380
3381         return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3382 }
3383
3384 proto_item *
3385 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3386                     const gint start, gint length, const guint encoding)
3387 {
3388         register header_field_info *hfinfo;
3389
3390         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3391         return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
3392 }
3393
3394 /* Add an item to a proto_tree, using the text label registered to that item;
3395    the item is extracted from the tvbuff handed to it.
3396
3397    Return the length of the item through the pointer. */
3398 proto_item *
3399 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
3400                                    tvbuff_t *tvb, const gint start,
3401                                    gint length, const guint encoding,
3402                                    gint *lenretval)
3403 {
3404         field_info        *new_fi;
3405         gint              item_length;
3406         proto_item       *item;
3407
3408         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3409
3410         get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3411         test_length(hfinfo, tvb, start, item_length, encoding);
3412
3413         if (!tree) {
3414                 /*
3415                  * We need to get the correct item length here.
3416                  * That's normally done by proto_tree_new_item(),
3417                  * but we won't be calling it.
3418                  */
3419                 *lenretval = get_full_length(hfinfo, tvb, start, length,
3420                     item_length, encoding);
3421                 return NULL;
3422         }
3423
3424         TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
3425                 /*
3426                  * Even if the tree item is not referenced (and thus faked),
3427                  * the caller must still be informed of the actual length.
3428                  */
3429                 *lenretval = get_full_length(hfinfo, tvb, start, length,
3430                     item_length, encoding);
3431         });
3432
3433         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3434
3435         item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3436         *lenretval = new_fi->length;
3437         return item;
3438 }
3439
3440 proto_item *
3441 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3442                                const gint start, gint length,
3443                                const guint encoding, gint *lenretval)
3444 {
3445         register header_field_info *hfinfo;
3446
3447         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3448         return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
3449 }
3450
3451 /* which FT_ types can use proto_tree_add_bytes_item() */
3452 static inline gboolean
3453 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
3454 {
3455         return (type == FT_BYTES      ||
3456                 type == FT_UINT_BYTES ||
3457                 type == FT_OID        ||
3458                 type == FT_REL_OID    ||
3459                 type == FT_SYSTEM_ID  );
3460 }
3461
3462 /* Note: this does no validation that the byte array of an FT_OID or
3463    FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
3464    so I think it's ok to continue not validating it?
3465  */
3466 proto_item *
3467 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3468                            const gint start, gint length, const guint encoding,
3469                            GByteArray *retval, gint *endoff, gint *err)
3470 {
3471         field_info        *new_fi;
3472         GByteArray        *bytes = retval;
3473         GByteArray        *created_bytes = NULL;
3474         gint               saved_err = 0;
3475         guint32            n = 0;
3476         header_field_info *hfinfo;
3477         gboolean           generate = (bytes || tree) ? TRUE : FALSE;
3478
3479         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3480
3481         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3482
3483         DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
3484                 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
3485
3486         /* length has to be -1 or > 0 regardless of encoding */
3487         /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
3488         if (length < -1 || length == 0) {
3489                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_bytes_item for %s",
3490                     length, ftype_name(hfinfo->type));
3491         }
3492
3493         if (encoding & ENC_STR_NUM) {
3494                 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
3495         }
3496
3497         if (generate && (encoding & ENC_STR_HEX)) {
3498                 if (hfinfo->type == FT_UINT_BYTES) {
3499                         /* can't decode FT_UINT_BYTES from strings */
3500                         REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
3501                             "FT_UINT_BYTES type, but as ENC_STR_HEX");
3502                 }
3503
3504                 if (!bytes) {
3505                         /* caller doesn't care about return value, but we need it to
3506                            call tvb_get_string_bytes() and set the tree later */
3507                         bytes = created_bytes = g_byte_array_new();
3508                 }
3509
3510                 /* bytes might be NULL after this, but can't add expert error until later */
3511                 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
3512
3513                 /* grab the errno now before it gets overwritten */
3514                 saved_err = errno;
3515         }
3516         else if (generate) {
3517                 tvb_ensure_bytes_exist(tvb, start, length);
3518
3519                 if (!bytes) {
3520                         /* caller doesn't care about return value, but we need it to
3521                            call tvb_get_string_bytes() and set the tree later */
3522                         bytes = created_bytes = g_byte_array_new();
3523                 }
3524
3525                 if (hfinfo->type == FT_UINT_BYTES) {
3526                         n = length; /* n is now the "header" length */
3527                         length = get_uint_value(tree, tvb, start, n, encoding);
3528                         /* length is now the value's length; only store the value in the array */
3529                         g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
3530                 }
3531                 else if (length > 0) {
3532                         g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
3533                 }
3534
3535                 if (endoff)
3536                     *endoff = start + n + length;
3537         }
3538
3539         if (err) *err = saved_err;
3540
3541         CHECK_FOR_NULL_TREE_AND_FREE(tree,
3542                 {
3543                     if (created_bytes)
3544                         g_byte_array_free(created_bytes, TRUE);
3545                     created_bytes = NULL;
3546                     bytes = NULL;
3547                 } );
3548
3549         TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
3550                 {
3551                     if (created_bytes)
3552                         g_byte_array_free(created_bytes, TRUE);
3553                     created_bytes = NULL;
3554                     bytes = NULL;
3555                 } );
3556
3557         /* n will be zero except when it's a FT_UINT_BYTES */
3558         new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
3559
3560         if (encoding & ENC_STRING) {
3561                 if (saved_err == ERANGE)
3562                     expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
3563                 else if (!bytes || saved_err != 0)
3564                     expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
3565
3566                 if (bytes)
3567                     proto_tree_set_bytes_gbytearray(new_fi, bytes);
3568                 else
3569                     proto_tree_set_bytes(new_fi, NULL, 0);
3570
3571                 if (created_bytes)
3572                     g_byte_array_free(created_bytes, TRUE);
3573         }
3574         else {
3575                 /* n will be zero except when it's a FT_UINT_BYTES */
3576                 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
3577
3578                 FI_SET_FLAG(new_fi,
3579                         (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3580         }
3581
3582         return proto_tree_add_node(tree, new_fi);
3583 }
3584
3585
3586 proto_item *
3587 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3588                            const gint start, gint length, const guint encoding,
3589                            nstime_t *retval, gint *endoff, gint *err)
3590 {
3591         field_info        *new_fi;
3592         nstime_t           time_stamp;
3593         gint               saved_err = 0;
3594         header_field_info *hfinfo;
3595
3596         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3597
3598         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3599
3600         DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3601
3602         /* length has to be -1 or > 0 regardless of encoding */
3603         if (length < -1 || length == 0) {
3604                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_time_item",
3605                     length);
3606         }
3607
3608         time_stamp.secs  = 0;
3609         time_stamp.nsecs = 0;
3610
3611         if (encoding & ENC_STR_TIME_MASK) {
3612                 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
3613                 /* grab the errno now before it gets overwritten */
3614                 saved_err = errno;
3615         }
3616         else {
3617                 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
3618
3619                 tvb_ensure_bytes_exist(tvb, start, length);
3620                 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
3621                 if (endoff) *endoff = length;
3622         }
3623
3624         if (err) *err = saved_err;
3625
3626         if (retval) {
3627                 retval->secs  = time_stamp.secs;
3628                 retval->nsecs = time_stamp.nsecs;
3629         }
3630
3631         CHECK_FOR_NULL_TREE(tree);
3632
3633         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3634
3635         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3636
3637         proto_tree_set_time(new_fi, &time_stamp);
3638
3639         if (encoding & ENC_STRING) {
3640                 if (saved_err == ERANGE)
3641                     expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
3642                 else if (saved_err == EDOM)
3643                     expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
3644         }
3645         else {
3646                 FI_SET_FLAG(new_fi,
3647                         (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3648         }
3649
3650         return proto_tree_add_node(tree, new_fi);
3651 }
3652
3653 /* Add a FT_NONE to a proto_tree */
3654 proto_item *
3655 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
3656                            const gint start, gint length, const char *format,
3657                            ...)
3658 {
3659         proto_item        *pi;
3660         va_list            ap;
3661         header_field_info *hfinfo;
3662
3663         CHECK_FOR_NULL_TREE(tree);
3664
3665         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3666
3667         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
3668
3669         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3670
3671         TRY_TO_FAKE_THIS_REPR(pi);
3672
3673         va_start(ap, format);
3674         proto_tree_set_representation(pi, format, ap);
3675         va_end(ap);
3676
3677         /* no value to set for FT_NONE */
3678         return pi;
3679 }
3680
3681 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
3682  * offset, and returns proto_item* */
3683 proto_item *
3684 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
3685                          const guint encoding)
3686 {
3687         proto_item *item;
3688
3689         item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
3690                                    length, encoding);
3691
3692         return item;
3693 }
3694
3695 /* Advance the ptvcursor's offset within its tvbuff without
3696  * adding anything to the proto_tree. */
3697 void
3698 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
3699 {
3700         ptvc->offset += length;
3701 }
3702
3703
3704 static void
3705 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
3706 {
3707         fvalue_set_protocol(&fi->value, tvb, field_data);
3708 }
3709
3710 /* Add a FT_PROTOCOL to a proto_tree */
3711 proto_item *
3712 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3713                                gint start, gint length, const char *format, ...)
3714 {
3715         proto_item        *pi;
3716         tvbuff_t          *protocol_tvb;
3717         va_list            ap;
3718         header_field_info *hfinfo;
3719         gchar* protocol_rep;
3720
3721         CHECK_FOR_NULL_TREE(tree);
3722
3723         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3724
3725         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
3726
3727         /*
3728          * This can throw an exception, so do it before we allocate anything.
3729          */
3730         protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
3731
3732         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3733
3734         va_start(ap, format);
3735         protocol_rep = g_strdup_vprintf(format, ap);
3736       &n