Add support for protocol aliases. Switch BOOTP to DHCP.
[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/ws_g_warning */
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(const char *string, gint length, proto_item *pi)
2263 {
2264         gboolean found_stray_character = FALSE;
2265
2266         for (gint i = (gint)strlen(string); i < length; i++) {
2267                 if (string[i] != '\0') {
2268                         found_stray_character = TRUE;
2269                         break;
2270                 }
2271         }
2272
2273         if (found_stray_character) {
2274                 expert_add_info(NULL, pi, &ei_string_trailing_characters);
2275         }
2276 }
2277
2278 /* Add an item to a proto_tree, using the text label registered to that item;
2279    the item is extracted from the tvbuff handed to it. */
2280 static proto_item *
2281 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2282                     tvbuff_t *tvb, gint start, gint length,
2283                     guint encoding)
2284 {
2285         proto_item *pi;
2286         guint32     value, n;
2287         guint64     value64;
2288         float       floatval;
2289         double      doubleval;
2290         const char *stringval = NULL;
2291         nstime_t    time_stamp;
2292         gboolean    length_error;
2293
2294         switch (new_fi->hfinfo->type) {
2295                 case FT_NONE:
2296                         /* no value to set for FT_NONE */
2297                         break;
2298
2299                 case FT_PROTOCOL:
2300                         proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
2301                         break;
2302
2303                 case FT_BYTES:
2304                         proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2305                         break;
2306
2307                 case FT_UINT_BYTES:
2308                         n = get_uint_value(tree, tvb, start, length, encoding);
2309                         proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2310
2311                         /* Instead of calling proto_item_set_len(), since we don't yet
2312                          * have a proto_item, we set the field_info's length ourselves. */
2313                         new_fi->length = n + length;
2314                         break;
2315
2316                 case FT_BOOLEAN:
2317                         /*
2318                          * Map all non-zero values to little-endian for
2319                          * backwards compatibility.
2320                          */
2321                         if (encoding)
2322                                 encoding = ENC_LITTLE_ENDIAN;
2323                         proto_tree_set_boolean(new_fi,
2324                                 get_uint64_value(tree, tvb, start, length, encoding));
2325                         break;
2326
2327                 case FT_CHAR:
2328                 /* XXX - make these just FT_UINT? */
2329                 case FT_UINT8:
2330                 case FT_UINT16:
2331                 case FT_UINT24:
2332                 case FT_UINT32:
2333                         if (encoding & ENC_VARINT_PROTOBUF) {
2334                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2335                                 new_fi->flags |= FI_VARINT;
2336                                 value = (guint32)value64;
2337                         } else if (encoding & ENC_VARINT_QUIC) {
2338                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2339                                 value = (guint32)value64;
2340                         } else {
2341                                 /*
2342                                  * Map all non-zero values to little-endian for
2343                                  * backwards compatibility.
2344                                  */
2345                                 if (encoding)
2346                                         encoding = ENC_LITTLE_ENDIAN;
2347
2348                                 value = get_uint_value(tree, tvb, start, length, encoding);
2349                         }
2350                         proto_tree_set_uint(new_fi, value);
2351                         break;
2352
2353                 case FT_UINT40:
2354                 case FT_UINT48:
2355                 case FT_UINT56:
2356                 case FT_UINT64:
2357
2358                         if (encoding & ENC_VARINT_PROTOBUF) {
2359                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2360                                 new_fi->flags |= FI_VARINT;
2361                         } else if (encoding & ENC_VARINT_QUIC) {
2362                                 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2363                         } else {
2364                                 /*
2365                                  * Map all other non-zero values to little-endian for
2366                                  * backwards compatibility.
2367                                  */
2368                                 if (encoding)
2369                                         encoding = ENC_LITTLE_ENDIAN;
2370
2371                                 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2372                         }
2373                         proto_tree_set_uint64(new_fi, value64);
2374                         break;
2375
2376                 /* XXX - make these just FT_INT? */
2377                 case FT_INT8:
2378                 case FT_INT16:
2379                 case FT_INT24:
2380                 case FT_INT32:
2381                         /*
2382                          * Map all non-zero values to little-endian for
2383                          * backwards compatibility.
2384                          */
2385                         if (encoding)
2386                                 encoding = ENC_LITTLE_ENDIAN;
2387                         proto_tree_set_int(new_fi,
2388                                 get_int_value(tree, tvb, start, length, encoding));
2389                         break;
2390
2391                 case FT_INT40:
2392                 case FT_INT48:
2393                 case FT_INT56:
2394                 case FT_INT64:
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_int64(new_fi,
2402                                 get_int64_value(tree, tvb, start, length, encoding));
2403                         break;
2404
2405                 case FT_IPv4:
2406                         /*
2407                          * Map all non-zero values to little-endian for
2408                          * backwards compatibility.
2409                          */
2410                         if (encoding)
2411                                 encoding = ENC_LITTLE_ENDIAN;
2412                         if (length != FT_IPv4_LEN) {
2413                                 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
2414                                 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2415                         }
2416                         value = tvb_get_ipv4(tvb, start);
2417                         /*
2418                          * NOTE: to support code written when
2419                          * proto_tree_add_item() took a gboolean as its
2420                          * last argument, with FALSE meaning "big-endian"
2421                          * and TRUE meaning "little-endian", we treat any
2422                          * non-zero value of "encoding" as meaning
2423                          * "little-endian".
2424                          */
2425                         proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
2426                         break;
2427
2428                 case FT_IPXNET:
2429                         if (length != FT_IPXNET_LEN) {
2430                                 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
2431                                 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2432                         }
2433                         proto_tree_set_ipxnet(new_fi,
2434                                 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
2435                         break;
2436
2437                 case FT_IPv6:
2438                         if (length != FT_IPv6_LEN) {
2439                                 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
2440                                 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2441                         }
2442                         proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2443                         break;
2444
2445                 case FT_FCWWN:
2446                         if (length != FT_FCWWN_LEN) {
2447                                 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2448                                 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2449                         }
2450                         proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2451                         break;
2452
2453                 case FT_AX25:
2454                         if (length != 7) {
2455                                 length_error = length < 7 ? TRUE : FALSE;
2456                                 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2457                         }
2458                         proto_tree_set_ax25_tvb(new_fi, tvb, start);
2459                         break;
2460
2461                 case FT_VINES:
2462                         if (length != VINES_ADDR_LEN) {
2463                                 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2464                                 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2465                         }
2466                         proto_tree_set_vines_tvb(new_fi, tvb, start);
2467                         break;
2468
2469                 case FT_ETHER:
2470                         if (length != FT_ETHER_LEN) {
2471                                 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2472                                 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2473                         }
2474                         proto_tree_set_ether_tvb(new_fi, tvb, start);
2475                         break;
2476
2477                 case FT_EUI64:
2478                         /*
2479                          * Map all non-zero values to little-endian for
2480                          * backwards compatibility.
2481                          */
2482                         if (encoding)
2483                                 encoding = ENC_LITTLE_ENDIAN;
2484                         if (length != FT_EUI64_LEN) {
2485                                 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2486                                 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2487                         }
2488                         proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2489                         break;
2490                 case FT_GUID:
2491                         /*
2492                          * Map all non-zero values to little-endian for
2493                          * backwards compatibility.
2494                          */
2495                         if (encoding)
2496                                 encoding = ENC_LITTLE_ENDIAN;
2497                         if (length != FT_GUID_LEN) {
2498                                 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2499                                 report_type_length_mismatch(tree, "a GUID", length, length_error);
2500                         }
2501                         proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2502                         break;
2503
2504                 case FT_OID:
2505                 case FT_REL_OID:
2506                         proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2507                         break;
2508
2509                 case FT_SYSTEM_ID:
2510                         proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2511                         break;
2512
2513                 case FT_FLOAT:
2514                         /*
2515                          * NOTE: to support code written when
2516                          * proto_tree_add_item() took a gboolean as its
2517                          * last argument, with FALSE meaning "big-endian"
2518                          * and TRUE meaning "little-endian", we treat any
2519                          * non-zero value of "encoding" as meaning
2520                          * "little-endian".
2521                          *
2522                          * At some point in the future, we might
2523                          * support non-IEEE-binary floating-point
2524                          * formats in the encoding as well
2525                          * (IEEE decimal, System/3x0, VAX).
2526                          */
2527                         if (encoding)
2528                                 encoding = ENC_LITTLE_ENDIAN;
2529                         if (length != 4) {
2530                                 length_error = length < 4 ? TRUE : FALSE;
2531                                 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2532                         }
2533                         if (encoding)
2534                                 floatval = tvb_get_letohieee_float(tvb, start);
2535                         else
2536                                 floatval = tvb_get_ntohieee_float(tvb, start);
2537                         proto_tree_set_float(new_fi, floatval);
2538                         break;
2539
2540                 case FT_DOUBLE:
2541                         /*
2542                          * NOTE: to support code written when
2543                          * proto_tree_add_item() took a gboolean as its
2544                          * last argument, with FALSE meaning "big-endian"
2545                          * and TRUE meaning "little-endian", we treat any
2546                          * non-zero value of "encoding" as meaning
2547                          * "little-endian".
2548                          *
2549                          * At some point in the future, we might
2550                          * support non-IEEE-binary floating-point
2551                          * formats in the encoding as well
2552                          * (IEEE decimal, System/3x0, VAX).
2553                          */
2554                         if (encoding == TRUE)
2555                                 encoding = ENC_LITTLE_ENDIAN;
2556                         if (length != 8) {
2557                                 length_error = length < 8 ? TRUE : FALSE;
2558                                 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2559                         }
2560                         if (encoding)
2561                                 doubleval = tvb_get_letohieee_double(tvb, start);
2562                         else
2563                                 doubleval = tvb_get_ntohieee_double(tvb, start);
2564                         proto_tree_set_double(new_fi, doubleval);
2565                         break;
2566
2567                 case FT_STRING:
2568                         stringval = get_string_value(wmem_packet_scope(),
2569                             tvb, start, length, &length, encoding);
2570                         proto_tree_set_string(new_fi, stringval);
2571
2572                         /* Instead of calling proto_item_set_len(), since we
2573                          * don't yet have a proto_item, we set the
2574                          * field_info's length ourselves.
2575                          *
2576                          * XXX - our caller can't use that length to
2577                          * advance an offset unless they arrange that
2578                          * there always be a protocol tree into which
2579                          * we're putting this item.
2580                          */
2581                         new_fi->length = length;
2582                         break;
2583
2584                 case FT_STRINGZ:
2585                         stringval = get_stringz_value(wmem_packet_scope(),
2586                             tree, tvb, start, length, &length, encoding);
2587                         proto_tree_set_string(new_fi, stringval);
2588
2589                         /* Instead of calling proto_item_set_len(),
2590                          * since we don't yet have a proto_item, we
2591                          * set the field_info's length ourselves.
2592                          *
2593                          * XXX - our caller can't use that length to
2594                          * advance an offset unless they arrange that
2595                          * there always be a protocol tree into which
2596                          * we're putting this item.
2597                          */
2598                         new_fi->length = length;
2599                         break;
2600
2601                 case FT_UINT_STRING:
2602                         /*
2603                          * NOTE: to support code written when
2604                          * proto_tree_add_item() took a gboolean as its
2605                          * last argument, with FALSE meaning "big-endian"
2606                          * and TRUE meaning "little-endian", if the
2607                          * encoding value is TRUE, treat that as
2608                          * ASCII with a little-endian length.
2609                          *
2610                          * This won't work for code that passes
2611                          * arbitrary non-zero values; that code
2612                          * will need to be fixed.
2613                          */
2614                         if (encoding == TRUE)
2615                                 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2616                         stringval = get_uint_string_value(wmem_packet_scope(),
2617                             tree, tvb, start, length, &length, encoding);
2618                         proto_tree_set_string(new_fi, stringval);
2619
2620                         /* Instead of calling proto_item_set_len(), since we
2621                          * don't yet have a proto_item, we set the
2622                          * field_info's length ourselves.
2623                          *
2624                          * XXX - our caller can't use that length to
2625                          * advance an offset unless they arrange that
2626                          * there always be a protocol tree into which
2627                          * we're putting this item.
2628                          */
2629                         new_fi->length = length;
2630                         break;
2631
2632                 case FT_STRINGZPAD:
2633                         stringval = get_stringzpad_value(wmem_packet_scope(),
2634                             tvb, start, length, &length, encoding);
2635                         proto_tree_set_string(new_fi, stringval);
2636
2637                         /* Instead of calling proto_item_set_len(), since we
2638                          * don't yet have a proto_item, we set the
2639                          * field_info's length ourselves.
2640                          *
2641                          * XXX - our caller can't use that length to
2642                          * advance an offset unless they arrange that
2643                          * there always be a protocol tree into which
2644                          * we're putting this item.
2645                          */
2646                         new_fi->length = length;
2647                         break;
2648
2649                 case FT_ABSOLUTE_TIME:
2650                         /*
2651                          * Absolute times can be in any of a number of
2652                          * formats, and they can be big-endian or
2653                          * little-endian.
2654                          *
2655                          * Historically FT_TIMEs were only timespecs;
2656                          * the only question was whether they were stored
2657                          * in big- or little-endian format.
2658                          *
2659                          * For backwards compatibility, we interpret an
2660                          * encoding of 1 as meaning "little-endian timespec",
2661                          * so that passing TRUE is interpreted as that.
2662                          */
2663                         if (encoding == TRUE)
2664                                 encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2665
2666                         get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
2667
2668                         proto_tree_set_time(new_fi, &time_stamp);
2669                         break;
2670
2671                 case FT_RELATIVE_TIME:
2672                         /*
2673                          * Relative times can be in any of a number of
2674                          * formats, and they can be big-endian or
2675                          * little-endian.
2676                          *
2677                          * Historically FT_TIMEs were only timespecs;
2678                          * the only question was whether they were stored
2679                          * in big- or little-endian format.
2680                          *
2681                          * For backwards compatibility, we interpret an
2682                          * encoding of 1 as meaning "little-endian timespec",
2683                          * so that passing TRUE is interpreted as that.
2684                          */
2685                         if (encoding == TRUE)
2686                                 encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2687
2688                         get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
2689
2690                         proto_tree_set_time(new_fi, &time_stamp);
2691                         break;
2692                 case FT_IEEE_11073_SFLOAT:
2693                         if (encoding)
2694                                 encoding = ENC_LITTLE_ENDIAN;
2695                         if (length != 2) {
2696                                 length_error = length < 2 ? TRUE : FALSE;
2697                                 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2698                         }
2699
2700                         fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2701
2702                         break;
2703                 case FT_IEEE_11073_FLOAT:
2704                         if (encoding)
2705                                 encoding = ENC_LITTLE_ENDIAN;
2706                         if (length != 4) {
2707                                 length_error = length < 4 ? TRUE : FALSE;
2708                                 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2709                         }
2710
2711                         break;
2712                 default:
2713                         g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2714                                         new_fi->hfinfo->type,
2715                                         ftype_name(new_fi->hfinfo->type));
2716                         DISSECTOR_ASSERT_NOT_REACHED();
2717                         break;
2718         }
2719         FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2720
2721         /* Don't add new node to proto_tree until now so that any exceptions
2722          * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2723         /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2724          *      to know which item caused exception? */
2725         pi = proto_tree_add_node(tree, new_fi);
2726
2727         if (stringval) {
2728                 /* Detect trailing stray characters */
2729                 detect_trailing_stray_characters(stringval, length, pi);
2730         }
2731
2732         return pi;
2733 }
2734
2735 proto_item *
2736 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2737                             const gint start, gint length,
2738                             const guint encoding, gint32 *retval)
2739 {
2740         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2741         field_info        *new_fi;
2742         gint32             value;
2743
2744         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2745
2746         switch (hfinfo->type) {
2747         case FT_INT8:
2748         case FT_INT16:
2749         case FT_INT24:
2750         case FT_INT32:
2751                 break;
2752         default:
2753                 DISSECTOR_ASSERT_NOT_REACHED();
2754         }
2755
2756         /* length validation for native number encoding caught by get_uint_value() */
2757         /* length has to be -1 or > 0 regardless of encoding */
2758         if (length < -1 || length == 0)
2759                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_int",
2760                         length);
2761
2762         if (encoding & ENC_STRING) {
2763                 REPORT_DISSECTOR_BUG("wrong encoding");
2764         }
2765         /* I believe it's ok if this is called with a NULL tree */
2766         value = get_int_value(tree, tvb, start, length, encoding);
2767
2768         if (retval) {
2769                 gint no_of_bits;
2770                 *retval = value;
2771                 if (hfinfo->bitmask) {
2772                         /* Mask out irrelevant portions */
2773                         *retval &= (guint32)(hfinfo->bitmask);
2774                         /* Shift bits */
2775                         *retval >>= hfinfo_bitshift(hfinfo);
2776                 }
2777                 no_of_bits = ws_count_ones(hfinfo->bitmask);
2778                 *retval = ws_sign_ext32(*retval, no_of_bits);
2779         }
2780
2781         CHECK_FOR_NULL_TREE(tree);
2782
2783         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2784
2785         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2786
2787         proto_tree_set_int(new_fi, value);
2788
2789         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2790
2791         return proto_tree_add_node(tree, new_fi);
2792 }
2793
2794 proto_item *
2795 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2796                              const gint start, gint length,
2797                              const guint encoding, guint32 *retval)
2798 {
2799         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2800         field_info        *new_fi;
2801         guint32            value;
2802
2803         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2804
2805         switch (hfinfo->type) {
2806         case FT_CHAR:
2807         case FT_UINT8:
2808         case FT_UINT16:
2809         case FT_UINT24:
2810         case FT_UINT32:
2811                 break;
2812         default:
2813                 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2814                     hfinfo->abbrev);
2815         }
2816
2817         /* length validation for native number encoding caught by get_uint_value() */
2818         /* length has to be -1 or > 0 regardless of encoding */
2819         if (length < -1 || length == 0)
2820                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
2821                         length);
2822
2823         if (encoding & ENC_STRING) {
2824                 REPORT_DISSECTOR_BUG("wrong encoding");
2825         }
2826         /* I believe it's ok if this is called with a NULL tree */
2827         /* XXX - modify if we ever support EBCDIC FT_CHAR */
2828         if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC)) {
2829                 guint64 temp64;
2830                 tvb_get_varint(tvb, start, length, &temp64, encoding);
2831                 value = (guint32)temp64;
2832         } else {
2833                 value = get_uint_value(tree, tvb, start, length, encoding);
2834         }
2835
2836         if (retval) {
2837                 *retval = value;
2838                 if (hfinfo->bitmask) {
2839                         /* Mask out irrelevant portions */
2840                         *retval &= (guint32)(hfinfo->bitmask);
2841                         /* Shift bits */
2842                         *retval >>= hfinfo_bitshift(hfinfo);
2843                 }
2844         }
2845
2846         CHECK_FOR_NULL_TREE(tree);
2847
2848         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2849
2850         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2851
2852         proto_tree_set_uint(new_fi, value);
2853
2854         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2855         if (encoding & ENC_VARINT_PROTOBUF) {
2856                 new_fi->flags |= FI_VARINT;
2857         }
2858         return proto_tree_add_node(tree, new_fi);
2859 }
2860
2861 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2862  * and returns proto_item* and uint value retreived*/
2863 proto_item *
2864 ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, gint length,
2865               const guint encoding, guint32 *retval)
2866 {
2867         field_info        *new_fi;
2868         header_field_info *hfinfo;
2869         gint               item_length;
2870         int                offset;
2871         guint32            value;
2872
2873         offset = ptvc->offset;
2874         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2875
2876         switch (hfinfo->type) {
2877         case FT_CHAR:
2878         case FT_UINT8:
2879         case FT_UINT16:
2880         case FT_UINT24:
2881         case FT_UINT32:
2882                 break;
2883         default:
2884                 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2885                     hfinfo->abbrev);
2886         }
2887
2888         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
2889         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
2890
2891         /* I believe it's ok if this is called with a NULL tree */
2892         /* XXX - modify if we ever support EBCDIC FT_CHAR */
2893         value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
2894
2895         if (retval) {
2896                 *retval = value;
2897                 if (hfinfo->bitmask) {
2898                         /* Mask out irrelevant portions */
2899                         *retval &= (guint32)(hfinfo->bitmask);
2900                         /* Shift bits */
2901                         *retval >>= hfinfo_bitshift(hfinfo);
2902                 }
2903         }
2904
2905         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2906             item_length, encoding);
2907
2908         CHECK_FOR_NULL_TREE(ptvc->tree);
2909
2910         /* Coast clear. Try and fake it */
2911         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2912
2913         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2914
2915         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2916                 offset, length, encoding);
2917 }
2918
2919 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2920  * and returns proto_item* and int value retreived*/
2921 proto_item *
2922 ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, gint length,
2923               const guint encoding, gint32 *retval)
2924 {
2925         field_info        *new_fi;
2926         header_field_info *hfinfo;
2927         gint               item_length;
2928         int                offset;
2929         guint32            value;
2930
2931         offset = ptvc->offset;
2932         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2933
2934         switch (hfinfo->type) {
2935         case FT_INT8:
2936         case FT_INT16:
2937         case FT_INT24:
2938         case FT_INT32:
2939                 break;
2940         default:
2941                 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
2942                     hfinfo->abbrev);
2943         }
2944
2945         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
2946         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
2947
2948         /* I believe it's ok if this is called with a NULL tree */
2949         /* XXX - modify if we ever support EBCDIC FT_CHAR */
2950         value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
2951
2952         if (retval) {
2953                 gint no_of_bits;
2954                 *retval = value;
2955                 if (hfinfo->bitmask) {
2956                         /* Mask out irrelevant portions */
2957                         *retval &= (guint32)(hfinfo->bitmask);
2958                         /* Shift bits */
2959                         *retval >>= hfinfo_bitshift(hfinfo);
2960                 }
2961                 no_of_bits = ws_count_ones(hfinfo->bitmask);
2962                 *retval = ws_sign_ext32(*retval, no_of_bits);
2963         }
2964
2965         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2966             item_length, encoding);
2967
2968         CHECK_FOR_NULL_TREE(ptvc->tree);
2969
2970         /* Coast clear. Try and fake it */
2971         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2972
2973         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2974
2975         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2976                 offset, length, encoding);
2977 }
2978
2979 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2980  * and returns proto_item* and string value retreived */
2981 proto_item*
2982 ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, wmem_allocator_t *scope, const guint8 **retval)
2983 {
2984         header_field_info *hfinfo;
2985         field_info              *new_fi;
2986         const guint8    *value;
2987         gint                    item_length;
2988         int                             offset;
2989
2990         offset = ptvc->offset;
2991
2992         PROTO_REGISTRAR_GET_NTH(hf, hfinfo);
2993
2994         switch (hfinfo->type) {
2995         case FT_STRING:
2996                 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
2997                 break;
2998         case FT_STRINGZ:
2999                 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3000                 break;
3001         case FT_UINT_STRING:
3002                 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3003                 break;
3004         case FT_STRINGZPAD:
3005                 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3006                 break;
3007         default:
3008                 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, or FT_STRINGZPAD",
3009                     hfinfo->abbrev);
3010         }
3011
3012         if (retval)
3013                 *retval = value;
3014
3015         ptvc->offset += item_length;
3016
3017         CHECK_FOR_NULL_TREE(ptvc->tree);
3018
3019         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3020
3021         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3022
3023         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3024                 offset, length, encoding);
3025 }
3026
3027 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3028  * and returns proto_item* and boolean value retreived */
3029 proto_item*
3030 ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, gint length, const guint encoding, gboolean *retval)
3031 {
3032         header_field_info *hfinfo;
3033         field_info              *new_fi;
3034         gint                    item_length;
3035         int                             offset;
3036         guint64                 value, bitval;
3037
3038         offset = ptvc->offset;
3039         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3040
3041         if (hfinfo->type != FT_BOOLEAN) {
3042                 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3043                     hfinfo->abbrev);
3044         }
3045
3046         /* length validation for native number encoding caught by get_uint64_value() */
3047         /* length has to be -1 or > 0 regardless of encoding */
3048         if (length < -1 || length == 0)
3049                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3050                         length);
3051
3052         if (encoding & ENC_STRING) {
3053                 REPORT_DISSECTOR_BUG("wrong encoding");
3054         }
3055
3056         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3057         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3058
3059         /* I believe it's ok if this is called with a NULL tree */
3060         value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3061
3062         if (retval) {
3063                 bitval = value;
3064                 if (hfinfo->bitmask) {
3065                         /* Mask out irrelevant portions */
3066                         bitval &= hfinfo->bitmask;
3067                 }
3068                 *retval = (bitval != 0);
3069         }
3070
3071         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3072             item_length, encoding);
3073
3074         CHECK_FOR_NULL_TREE(ptvc->tree);
3075
3076         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3077
3078         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3079
3080         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3081                 offset, length, encoding);
3082 }
3083
3084 proto_item *
3085 proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3086     const gint start, gint length, const guint encoding, guint64 *retval)
3087 {
3088         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3089         field_info        *new_fi;
3090         guint64            value;
3091
3092         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3093
3094         switch (hfinfo->type) {
3095         case FT_UINT40:
3096         case FT_UINT48:
3097         case FT_UINT56:
3098         case FT_UINT64:
3099                 break;
3100         default:
3101                 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
3102                     hfinfo->abbrev);
3103         }
3104
3105         /* length validation for native number encoding caught by get_uint64_value() */
3106         /* length has to be -1 or > 0 regardless of encoding */
3107         if (length < -1 || length == 0)
3108                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3109                         length);
3110
3111         if (encoding & ENC_STRING) {
3112                 REPORT_DISSECTOR_BUG("wrong encoding");
3113         }
3114         /* I believe it's ok if this is called with a NULL tree */
3115         if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC)) {
3116                 tvb_get_varint(tvb, start, length, &value, encoding);
3117         } else {
3118                 value = get_uint64_value(tree, tvb, start, length, encoding);
3119         }
3120
3121         if (retval) {
3122                 *retval = value;
3123                 if (hfinfo->bitmask) {
3124                         /* Mask out irrelevant portions */
3125                         *retval &= hfinfo->bitmask;
3126                         /* Shift bits */
3127                         *retval >>= hfinfo_bitshift(hfinfo);
3128                 }
3129         }
3130
3131         CHECK_FOR_NULL_TREE(tree);
3132
3133         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3134
3135         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3136
3137         proto_tree_set_uint64(new_fi, value);
3138
3139         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3140         if (encoding & ENC_VARINT_PROTOBUF) {
3141                 new_fi->flags |= FI_VARINT;
3142         }
3143
3144         return proto_tree_add_node(tree, new_fi);
3145 }
3146
3147 proto_item *
3148 proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3149     const gint start, gint length, const guint encoding, guint64 *retval, gint *lenretval)
3150 {
3151         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3152         field_info      *new_fi;
3153         guint64         value;
3154
3155         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3156
3157         if ((!IS_FT_INT(hfinfo->type)) && (!IS_FT_UINT(hfinfo->type))) {
3158                 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",
3159                     hfinfo->abbrev);
3160         }
3161
3162         /* length validation for native number encoding caught by get_uint64_value() */
3163         /* length has to be -1 or > 0 regardless of encoding */
3164         if (length == 0)
3165                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",
3166                         length);
3167
3168         if (encoding & ENC_STRING) {
3169                 REPORT_DISSECTOR_BUG("wrong encoding");
3170         }
3171
3172         length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value, encoding);
3173
3174         if (retval) {
3175                 *retval = value;
3176                 if (hfinfo->bitmask) {
3177                         /* Mask out irrelevant portions */
3178                         *retval &= hfinfo->bitmask;
3179                         /* Shift bits */
3180                         *retval >>= hfinfo_bitshift(hfinfo);
3181                 }
3182         }
3183
3184         if (lenretval) {
3185                 *lenretval = length;
3186         }
3187
3188         CHECK_FOR_NULL_TREE(tree);
3189
3190         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3191
3192         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3193
3194         proto_tree_set_uint64(new_fi, value);
3195
3196         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3197         if (encoding & ENC_VARINT_PROTOBUF) {
3198                 new_fi->flags |= FI_VARINT;
3199         }
3200
3201         return proto_tree_add_node(tree, new_fi);
3202
3203 }
3204
3205 proto_item *
3206 proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3207                                 const gint start, gint length,
3208                                 const guint encoding, gboolean *retval)
3209 {
3210         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3211         field_info        *new_fi;
3212         guint64            value, bitval;
3213
3214         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3215
3216         if (hfinfo->type != FT_BOOLEAN) {
3217                 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3218                     hfinfo->abbrev);
3219         }
3220
3221         /* length validation for native number encoding caught by get_uint64_value() */
3222         /* length has to be -1 or > 0 regardless of encoding */
3223         if (length < -1 || length == 0)
3224                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3225                         length);
3226
3227         if (encoding & ENC_STRING) {
3228                 REPORT_DISSECTOR_BUG("wrong encoding");
3229         }
3230         /* I believe it's ok if this is called with a NULL tree */
3231         value = get_uint64_value(tree, tvb, start, length, encoding);
3232
3233         if (retval) {
3234                 bitval = value;
3235                 if (hfinfo->bitmask) {
3236                         /* Mask out irrelevant portions */
3237                         bitval &= hfinfo->bitmask;
3238                 }
3239                 *retval = (bitval != 0);
3240         }
3241
3242         CHECK_FOR_NULL_TREE(tree);
3243
3244         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3245
3246         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3247
3248         proto_tree_set_boolean(new_fi, value);
3249
3250         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3251
3252         return proto_tree_add_node(tree, new_fi);
3253 }
3254
3255 proto_item *
3256 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
3257                                           tvbuff_t *tvb,
3258                                           const gint start, gint length,
3259                                           const guint encoding,
3260                                           wmem_allocator_t *scope,
3261                                           const guint8 **retval,
3262                                           gint *lenretval)
3263 {
3264         proto_item *pi;
3265         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3266         field_info        *new_fi;
3267         const guint8      *value;
3268
3269         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3270
3271         switch (hfinfo->type) {
3272         case FT_STRING:
3273                 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
3274                 break;
3275         case FT_STRINGZ:
3276                 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
3277                 break;
3278         case FT_UINT_STRING:
3279                 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
3280                 break;
3281         case FT_STRINGZPAD:
3282                 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
3283                 break;
3284         default:
3285                 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, or FT_STRINGZPAD",
3286                     hfinfo->abbrev);
3287         }
3288
3289         if (retval)
3290                 *retval = value;
3291
3292         CHECK_FOR_NULL_TREE(tree);
3293
3294         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3295
3296         new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
3297
3298         proto_tree_set_string(new_fi, value);
3299
3300         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3301
3302         pi = proto_tree_add_node(tree, new_fi);
3303
3304         if (value) {
3305                 /* Detect trailing stray characters */
3306                 detect_trailing_stray_characters(value, length, pi);
3307         }
3308
3309         return pi;
3310 }
3311
3312 proto_item *
3313 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3314                                const gint start, gint length,
3315                                const guint encoding, wmem_allocator_t *scope,
3316                                const guint8 **retval)
3317 {
3318         return proto_tree_add_item_ret_string_and_length(tree, hfindex,
3319             tvb, start, length, encoding, scope, retval, &length);
3320 }
3321
3322
3323 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3324    and returns proto_item* */
3325 proto_item *
3326 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
3327               const guint encoding)
3328 {
3329         field_info        *new_fi;
3330         header_field_info *hfinfo;
3331         gint               item_length;
3332         int                offset;
3333
3334         offset = ptvc->offset;
3335         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3336         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3337         test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3338
3339         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3340             item_length, encoding);
3341
3342         CHECK_FOR_NULL_TREE(ptvc->tree);
3343
3344         /* Coast clear. Try and fake it */
3345         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3346
3347         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3348
3349         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3350                 offset, length, encoding);
3351 }
3352
3353 /* Add an item to a proto_tree, using the text label registered to that item;
3354    the item is extracted from the tvbuff handed to it. */
3355 proto_item *
3356 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
3357                         const gint start, gint length, const guint encoding)
3358 {
3359         field_info        *new_fi;
3360         gint              item_length;
3361
3362         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3363
3364         get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3365         test_length(hfinfo, tvb, start, item_length, encoding);
3366
3367         CHECK_FOR_NULL_TREE(tree);
3368
3369         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3370
3371         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3372
3373         return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3374 }
3375
3376 proto_item *
3377 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3378                     const gint start, gint length, const guint encoding)
3379 {
3380         register header_field_info *hfinfo;
3381
3382         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3383         return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
3384 }
3385
3386 /* Add an item to a proto_tree, using the text label registered to that item;
3387    the item is extracted from the tvbuff handed to it.
3388
3389    Return the length of the item through the pointer. */
3390 proto_item *
3391 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
3392                                    tvbuff_t *tvb, const gint start,
3393                                    gint length, const guint encoding,
3394                                    gint *lenretval)
3395 {
3396         field_info        *new_fi;
3397         gint              item_length;
3398         proto_item       *item;
3399
3400         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3401
3402         get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3403         test_length(hfinfo, tvb, start, item_length, encoding);
3404
3405         if (!tree) {
3406                 /*
3407                  * We need to get the correct item length here.
3408                  * That's normally done by proto_tree_new_item(),
3409                  * but we won't be calling it.
3410                  */
3411                 *lenretval = get_full_length(hfinfo, tvb, start, length,
3412                     item_length, encoding);
3413                 return NULL;
3414         }
3415
3416         TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
3417                 /*
3418                  * Even if the tree item is not referenced (and thus faked),
3419                  * the caller must still be informed of the actual length.
3420                  */
3421                 *lenretval = get_full_length(hfinfo, tvb, start, length,
3422                     item_length, encoding);
3423         });
3424
3425         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3426
3427         item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3428         *lenretval = new_fi->length;
3429         return item;
3430 }
3431
3432 proto_item *
3433 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3434                                const gint start, gint length,
3435                                const guint encoding, gint *lenretval)
3436 {
3437         register header_field_info *hfinfo;
3438
3439         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3440         return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
3441 }
3442
3443 /* which FT_ types can use proto_tree_add_bytes_item() */
3444 static inline gboolean
3445 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
3446 {
3447         return (type == FT_BYTES      ||
3448                 type == FT_UINT_BYTES ||
3449                 type == FT_OID        ||
3450                 type == FT_REL_OID    ||
3451                 type == FT_SYSTEM_ID  );
3452 }
3453
3454 /* Note: this does no validation that the byte array of an FT_OID or
3455    FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
3456    so I think it's ok to continue not validating it?
3457  */
3458 proto_item *
3459 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3460                            const gint start, gint length, const guint encoding,
3461                            GByteArray *retval, gint *endoff, gint *err)
3462 {
3463         field_info        *new_fi;
3464         GByteArray        *bytes = retval;
3465         GByteArray        *created_bytes = NULL;
3466         gint               saved_err = 0;
3467         guint32            n = 0;
3468         header_field_info *hfinfo;
3469         gboolean           generate = (bytes || tree) ? TRUE : FALSE;
3470
3471         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3472
3473         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3474
3475         DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
3476                 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
3477
3478         /* length has to be -1 or > 0 regardless of encoding */
3479         /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
3480         if (length < -1 || length == 0) {
3481                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_bytes_item for %s",
3482                     length, ftype_name(hfinfo->type));
3483         }
3484
3485         if (encoding & ENC_STR_NUM) {
3486                 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
3487         }
3488
3489         if (generate && (encoding & ENC_STR_HEX)) {
3490                 if (hfinfo->type == FT_UINT_BYTES) {
3491                         /* can't decode FT_UINT_BYTES from strings */
3492                         REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
3493                             "FT_UINT_BYTES type, but as ENC_STR_HEX");
3494                 }
3495
3496                 if (!bytes) {
3497                         /* caller doesn't care about return value, but we need it to
3498                            call tvb_get_string_bytes() and set the tree later */
3499                         bytes = created_bytes = g_byte_array_new();
3500                 }
3501
3502                 /* bytes might be NULL after this, but can't add expert error until later */
3503                 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
3504
3505                 /* grab the errno now before it gets overwritten */
3506                 saved_err = errno;
3507         }
3508         else if (generate) {
3509                 tvb_ensure_bytes_exist(tvb, start, length);
3510
3511                 if (!bytes) {
3512                         /* caller doesn't care about return value, but we need it to
3513                            call tvb_get_string_bytes() and set the tree later */
3514                         bytes = created_bytes = g_byte_array_new();
3515                 }
3516
3517                 if (hfinfo->type == FT_UINT_BYTES) {
3518                         n = length; /* n is now the "header" length */
3519                         length = get_uint_value(tree, tvb, start, n, encoding);
3520                         /* length is now the value's length; only store the value in the array */
3521                         g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
3522                 }
3523                 else if (length > 0) {
3524                         g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
3525                 }
3526
3527                 if (endoff)
3528                     *endoff = start + n + length;
3529         }
3530
3531         if (err) *err = saved_err;
3532
3533         CHECK_FOR_NULL_TREE_AND_FREE(tree,
3534                 {
3535                     if (created_bytes)
3536                         g_byte_array_free(created_bytes, TRUE);
3537                     created_bytes = NULL;
3538                     bytes = NULL;
3539                 } );
3540
3541         TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
3542                 {
3543                     if (created_bytes)
3544                         g_byte_array_free(created_bytes, TRUE);
3545                     created_bytes = NULL;
3546                     bytes = NULL;
3547                 } );
3548
3549         /* n will be zero except when it's a FT_UINT_BYTES */
3550         new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
3551
3552         if (encoding & ENC_STRING) {
3553                 if (saved_err == ERANGE)
3554                     expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
3555                 else if (!bytes || saved_err != 0)
3556                     expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
3557
3558                 if (bytes)
3559                     proto_tree_set_bytes_gbytearray(new_fi, bytes);
3560                 else
3561                     proto_tree_set_bytes(new_fi, NULL, 0);
3562
3563                 if (created_bytes)
3564                     g_byte_array_free(created_bytes, TRUE);
3565         }
3566         else {
3567                 /* n will be zero except when it's a FT_UINT_BYTES */
3568                 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
3569
3570                 FI_SET_FLAG(new_fi,
3571                         (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3572         }
3573
3574         return proto_tree_add_node(tree, new_fi);
3575 }
3576
3577
3578 proto_item *
3579 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3580                            const gint start, gint length, const guint encoding,
3581                            nstime_t *retval, gint *endoff, gint *err)
3582 {
3583         field_info        *new_fi;
3584         nstime_t           time_stamp;
3585         gint               saved_err = 0;
3586         header_field_info *hfinfo;
3587
3588         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3589
3590         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3591
3592         DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3593
3594         /* length has to be -1 or > 0 regardless of encoding */
3595         if (length < -1 || length == 0) {
3596                 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_time_item",
3597                     length);
3598         }
3599
3600         time_stamp.secs  = 0;
3601         time_stamp.nsecs = 0;
3602
3603         if (encoding & ENC_STR_TIME_MASK) {
3604                 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
3605                 /* grab the errno now before it gets overwritten */
3606                 saved_err = errno;
3607         }
3608         else {
3609                 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
3610
3611                 tvb_ensure_bytes_exist(tvb, start, length);
3612                 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
3613                 if (endoff) *endoff = length;
3614         }
3615
3616         if (err) *err = saved_err;
3617
3618         if (retval) {
3619                 retval->secs  = time_stamp.secs;
3620                 retval->nsecs = time_stamp.nsecs;
3621         }
3622
3623         CHECK_FOR_NULL_TREE(tree);
3624
3625         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3626
3627         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3628
3629         proto_tree_set_time(new_fi, &time_stamp);
3630
3631         if (encoding & ENC_STRING) {
3632                 if (saved_err == ERANGE)
3633                     expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
3634                 else if (saved_err == EDOM)
3635                     expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
3636         }
3637         else {
3638                 FI_SET_FLAG(new_fi,
3639                         (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3640         }
3641
3642         return proto_tree_add_node(tree, new_fi);
3643 }
3644
3645 /* Add a FT_NONE to a proto_tree */
3646 proto_item *
3647 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
3648                            const gint start, gint length, const char *format,
3649                            ...)
3650 {
3651         proto_item        *pi;
3652         va_list            ap;
3653         header_field_info *hfinfo;
3654
3655         CHECK_FOR_NULL_TREE(tree);
3656
3657         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3658
3659         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
3660
3661         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3662
3663         TRY_TO_FAKE_THIS_REPR(pi);
3664
3665         va_start(ap, format);
3666         proto_tree_set_representation(pi, format, ap);
3667         va_end(ap);
3668
3669         /* no value to set for FT_NONE */
3670         return pi;
3671 }
3672
3673 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
3674  * offset, and returns proto_item* */
3675 proto_item *
3676 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
3677                          const guint encoding)
3678 {
3679         proto_item *item;
3680
3681         item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
3682                                    length, encoding);
3683
3684         return item;
3685 }
3686
3687 /* Advance the ptvcursor's offset within its tvbuff without
3688  * adding anything to the proto_tree. */
3689 void
3690 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
3691 {
3692         ptvc->offset += length;
3693 }
3694
3695
3696 static void
3697 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
3698 {
3699         fvalue_set_protocol(&fi->value, tvb, field_data);
3700 }
3701
3702 /* Add a FT_PROTOCOL to a proto_tree */
3703 proto_item *
3704 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3705                                gint start, gint length, const char *format, ...)
3706 {
3707         proto_item        *pi;
3708         tvbuff_t          *protocol_tvb;
3709         va_list            ap;
3710         header_field_info *hfinfo;
3711         gchar* protocol_rep;
3712
3713         CHECK_FOR_NULL_TREE(tree);
3714
3715         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3716
3717         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
3718
3719         /*
3720          * This can throw an exception, so do it before we allocate anything.
3721          */
3722         protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
3723
3724         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3725
3726         va_start(ap, format);
3727         protocol_rep = g_strdup_vprintf(format, ap);
3728         proto_tree_set_protocol_tvb(PNODE_FINFO(pi), protocol_tvb, protocol_rep);
3729         g_free(protocol_rep);
3730         va_end(ap);
3731
3732         TRY_TO_FAKE_THIS_REPR(pi);
3733
3734         va_start(ap, format);
3735         proto_tree_set_representation(pi, format, ap);
3736         va_end(ap);
3737
3738         return pi;
3739 }
3740
3741 /* Add a FT_BYTES to a proto_tree */
3742 proto_item *
3743 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3744                      gint length, const guint8 *start_ptr)
3745 {
3746         proto_item        *pi;
3747         header_field_info *hfinfo;
3748         gint              item_length;
3749
3750         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3751         get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
3752         test_length(hfinfo, tvb, start, item_length, ENC_NA);
3753
3754         CHECK_FOR_NULL_TREE(tree);
3755
3756         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3757
3758         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
3759
3760         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3761         proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
3762
3763         return pi;
3764 }
3765
3766 /* Add a FT_BYTES to a proto_tree */
3767 proto_item *
3768 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3769              gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
3770 {
3771         proto_item    *pi;
3772         header_field_info *hfinfo;
3773         gint          item_length;
3774
3775         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3776         get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA);
3777         test_length(hfinfo, tvb, start, item_length, ENC_NA);
3778
3779         CHECK_FOR_NULL_TREE(tree);
3780
3781         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3782
3783         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
3784
3785         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
3786         proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
3787
3788         return pi;
3789 }
3790
3791 proto_item *
3792 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3793                                   gint start, gint length,
3794                                   const guint8 *start_ptr,
3795                                   const char *format, ...)
3796 {
3797         proto_item        *pi;
3798         va_list            ap;
3799
3800         if (start_ptr == NULL)
3801                 start_ptr = tvb_get_ptr(tvb, start, length);
3802
3803         pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
3804
3805         TRY_TO_FAKE_THIS_REPR_NESTED(pi);
3806
3807         va_start(ap, format);
3808         proto_tree_set_representation_value(pi, format, ap);
3809         va_end(ap);
3810
3811         return pi;
3812 }
3813
3814 proto_item *
3815 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3816                             gint start, gint length, const guint8 *start_ptr,
3817                             const char *format, ...)
3818 {
3819         proto_item        *pi;
3820         va_list            ap;
3821
3822         if (start_ptr == NULL)
3823                 start_ptr = tvb_get_ptr(tvb, start, length);
3824
3825         pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
3826
3827         TRY_TO_FAKE_THIS_REPR_NESTED(pi);
3828
3829         va_start(ap, format);
3830         proto_tree_set_representation(pi, format, ap);
3831         va_end(ap);
3832
3833         return pi;
3834 }
3835
3836 static void
3837 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
3838 {
3839         GByteArray *bytes;
3840
3841         DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
3842
3843         bytes = g_byte_array_new();
3844         if (length > 0) {
3845                 g_byte_array_append(bytes, start_ptr, length);
3846         }
3847         fvalue_set_byte_array(&fi->value, bytes);
3848 }
3849
3850
3851 static void
3852 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
3853 {
3854         proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
3855 }
3856
3857 static void
3858 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
3859 {
3860         GByteArray *bytes;
3861
3862         DISSECTOR_ASSERT(value != NULL);
3863
3864         bytes = byte_array_dup(value);
3865
3866         fvalue_set_byte_array(&fi->value, bytes);
3867 }
3868
3869 /* Add a FT_*TIME to a proto_tree */
3870 proto_item *
3871 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3872                     gint length, const nstime_t *value_ptr)
3873 {
3874         proto_item        *pi;
3875         header_field_info *hfinfo;
3876
3877         CHECK_FOR_NULL_TREE(tree);
3878
3879         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3880
3881         DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3882
3883         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3884         proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
3885
3886         return pi;
3887 }
3888
3889 proto_item *
3890 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3891                                  gint start, gint length, nstime_t *value_ptr,
3892                                  const char *format, ...)
3893 {
3894         proto_item        *pi;
3895         va_list            ap;
3896
3897         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3898         if (pi != tree) {
3899                 va_start(ap, format);
3900                 proto_tree_set_representation_value(pi, format, ap);
3901                 va_end(ap);
3902         }
3903
3904         return pi;
3905 }
3906
3907 proto_item *
3908 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3909                            gint start, gint length, nstime_t *value_ptr,
3910                            const char *format, ...)
3911 {
3912         proto_item        *pi;
3913         va_list            ap;
3914
3915         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3916         if (pi != tree) {
3917                 TRY_TO_FAKE_THIS_REPR(pi);
3918
3919                 va_start(ap, format);
3920                 proto_tree_set_representation(pi, format, ap);
3921                 va_end(ap);
3922         }
3923
3924         return pi;
3925 }
3926
3927 /* Set the FT_*TIME value */
3928 static void
3929 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
3930 {
3931         DISSECTOR_ASSERT(value_ptr != NULL);
3932
3933         fvalue_set_time(&fi->value, value_ptr);
3934 }
3935
3936 /* Add a FT_IPXNET to a proto_tree */
3937 proto_item *
3938 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3939                       gint length, guint32 value)
3940 {
3941         proto_item        *pi;
3942         header_field_info *hfinfo;
3943
3944         CHECK_FOR_NULL_TREE(tree);
3945
3946         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3947
3948         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
3949
3950         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3951         proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
3952
3953         return pi;
3954 }
3955
3956 proto_item *
3957 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3958                                    gint start, gint length, guint32 value,
3959                                    const char *format, ...)
3960 {
3961         proto_item        *pi;
3962         va_list            ap;
3963
3964         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3965         if (pi != tree) {
3966                 va_start(ap, format);
3967                 proto_tree_set_representation_value(pi, format, ap);
3968                 va_end(ap);
3969         }
3970
3971         return pi;
3972 }
3973
3974 proto_item *
3975 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3976                              gint start, gint length, guint32 value,
3977                              const char *format, ...)
3978 {
3979         proto_item        *pi;
3980         va_list            ap;
3981
3982         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3983         if (pi != tree) {
3984                 TRY_TO_FAKE_THIS_REPR(pi);
3985
3986                 va_start(ap, format);
3987                 proto_tree_set_representation(pi, format, ap);
3988                 va_end(ap);
3989         }
3990
3991         return pi;
3992 }
3993
3994 /* Set the FT_IPXNET value */
3995 static void
3996 proto_tree_set_ipxnet(field_info *fi, guint32 value)
3997 {
3998         fvalue_set_uinteger(&fi->value, value);
3999 }
4000
4001 /* Add a FT_IPv4 to a proto_tree */
4002 proto_item *
4003 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4004                     gint length, guint32 value)
4005 {
4006         proto_item        *pi;
4007         header_field_info *hfinfo;
4008
4009         CHECK_FOR_NULL_TREE(tree);
4010
4011         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4012
4013         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
4014
4015         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4016         proto_tree_set_ipv4(PNODE_FINFO(pi), value);
4017
4018         return pi;
4019 }
4020
4021 proto_item *
4022 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4023                                  gint start, gint length, guint32 value,
4024                                  const char *format, ...)
4025 {
4026         proto_item        *pi;
4027         va_list            ap;
4028
4029         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
4030         if (pi != tree) {
4031                 va_start(ap, format);
4032                 proto_tree_set_representation_value(pi, format, ap);
4033                 va_end(ap);
4034         }
4035
4036         return pi;
4037 }
4038
4039 proto_item *
4040 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4041                            gint start, gint length, guint32 value,
4042                            const char *format, ...)
4043 {
4044         proto_item        *pi;
4045         va_list            ap;
4046
4047         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
4048         if (pi != tree) {
4049                 TRY_TO_FAKE_THIS_REPR(pi);
4050
4051                 va_start(ap, format);
4052                 proto_tree_set_representation(pi, format, ap);
4053                 va_end(ap);
4054         }
4055
4056         return pi;
4057 }
4058
4059 /* Set the FT_IPv4 value */
4060 static void
4061 proto_tree_set_ipv4(field_info *fi, guint32 value)
4062 {
4063         fvalue_set_uinteger(&fi->value, value);
4064 }
4065
4066 /* Add a FT_IPv6 to a proto_tree */
4067 proto_item *
4068 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4069                     gint length, const ws_in6_addr *value_ptr)
4070 {
4071         proto_item        *pi;
4072         header_field_info *hfinfo;
4073
4074         CHECK_FOR_NULL_TREE(tree);
4075
4076         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4077
4078         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
4079
4080         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4081         proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
4082
4083         return pi;
4084 }
4085
4086 proto_item *
4087 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4088                                  gint start, gint length,
4089                                  const ws_in6_addr *value_ptr,
4090                                  const char *format, ...)
4091 {
4092         proto_item        *pi;
4093         va_list            ap;
4094
4095         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
4096         if (pi != tree) {
4097                 va_start(ap, format);
4098                 proto_tree_set_representation_value(pi, format, ap);
4099                 va_end(ap);
4100         }
4101
4102         return pi;
4103 }
4104
4105 proto_item *
4106 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4107                            gint start, gint length,
4108                            const ws_in6_addr *value_ptr,
4109                            const char *format, ...)
4110 {
4111         proto_item        *pi;
4112         va_list            ap;
4113
4114         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
4115         if (pi != tree) {
4116                 TRY_TO_FAKE_THIS_REPR(pi);
4117
4118                 va_start(ap, format);
4119                 proto_tree_set_representation(pi, format, ap);
4120                 va_end(ap);
4121         }
4122
4123         return pi;
4124 }
4125
4126 /* Set the FT_IPv6 value */
4127 static void
4128 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
4129 {
4130         DISSECTOR_ASSERT(value_ptr != NULL);
4131         fvalue_set_bytes(&fi->value, value_ptr);
4132 }
4133
4134 static void
4135 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4136 {
4137         proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
4138 }
4139
4140 /* Set the FT_FCWWN value */
4141 static void
4142 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
4143 {
4144         DISSECTOR_ASSERT(value_ptr != NULL);
4145         fvalue_set_bytes(&fi->value, value_ptr);
4146 }
4147
4148 static void
4149 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4150 {
4151         proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
4152 }
4153
4154 /* Add a FT_GUID to a proto_tree */
4155 proto_item *
4156 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4157                     gint length, const e_guid_t *value_ptr)
4158 {
4159         proto_item        *pi;
4160         header_field_info *hfinfo;
4161
4162         CHECK_FOR_NULL_TREE(tree);
4163
4164         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4165
4166         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
4167
4168         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4169         proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
4170
4171         return pi;
4172 }
4173
4174 proto_item *
4175 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4176                                  gint start, gint length,
4177                                  const e_guid_t *value_ptr,
4178                                  const char *format, ...)
4179 {
4180         proto_item        *pi;
4181         va_list            ap;
4182
4183         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4184         if (pi != tree) {
4185                 va_start(ap, format);
4186                 proto_tree_set_representation_value(pi, format, ap);
4187                 va_end(ap);
4188         }
4189
4190         return pi;
4191 }
4192
4193 proto_item *
4194 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4195                            gint start, gint length, const e_guid_t *value_ptr,
4196                            const char *format, ...)
4197 {
4198         proto_item        *pi;
4199         va_list            ap;
4200
4201         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4202         if (pi != tree) {
4203                 TRY_TO_FAKE_THIS_REPR(pi);
4204
4205                 va_start(ap, format);
4206                 proto_tree_set_representation(pi, format, ap);
4207                 va_end(ap);
4208         }
4209
4210         return pi;
4211 }
4212
4213 /* Set the FT_GUID value */
4214 static void
4215 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
4216 {
4217         DISSECTOR_ASSERT(value_ptr != NULL);
4218         fvalue_set_guid(&fi->value, value_ptr);
4219 }
4220
4221 static void
4222 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
4223                         const guint encoding)
4224 {
4225         e_guid_t guid;
4226
4227         tvb_get_guid(tvb, start, &guid, encoding);
4228         proto_tree_set_guid(fi, &guid);
4229 }
4230
4231 /* Add a FT_OID to a proto_tree */
4232 proto_item *
4233 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4234                    gint length, const guint8* value_ptr)
4235 {
4236         proto_item        *pi;
4237         header_field_info *hfinfo;
4238
4239         CHECK_FOR_NULL_TREE(tree);
4240
4241         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4242
4243         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
4244
4245         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4246         proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
4247
4248         return pi;
4249 }
4250
4251 proto_item *
4252 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4253                                 gint start, gint length,
4254                                 const guint8* value_ptr,
4255                                 const char *format, ...)
4256 {
4257         proto_item        *pi;
4258         va_list            ap;
4259
4260         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4261         if (pi != tree) {
4262                 va_start(ap, format);
4263                 proto_tree_set_representation_value(pi, format, ap);
4264                 va_end(ap);
4265         }
4266
4267         return pi;
4268 }
4269
4270 proto_item *
4271 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4272                           gint start, gint length, const guint8* value_ptr,
4273                           const char *format, ...)
4274 {
4275         proto_item        *pi;
4276         va_list            ap;
4277
4278         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4279         if (pi != tree) {
4280                 TRY_TO_FAKE_THIS_REPR(pi);
4281
4282                 va_start(ap, format);
4283                 proto_tree_set_representation(pi, format, ap);
4284                 va_end(ap);
4285         }
4286
4287         return pi;
4288 }
4289
4290 /* Set the FT_OID value */
4291 static void
4292 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
4293 {
4294         GByteArray *bytes;
4295
4296         DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4297
4298         bytes = g_byte_array_new();
4299         if (length > 0) {
4300                 g_byte_array_append(bytes, value_ptr, length);
4301         }
4302         fvalue_set_byte_array(&fi->value, bytes);
4303 }
4304
4305 static void
4306 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4307 {
4308         proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
4309 }
4310
4311 /* Set the FT_SYSTEM_ID value */
4312 static void
4313 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
4314 {
4315         GByteArray *bytes;
4316
4317         DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4318
4319         bytes = g_byte_array_new();
4320         if (length > 0) {
4321                 g_byte_array_append(bytes, value_ptr, length);
4322         }
4323         fvalue_set_byte_array(&fi->value, bytes);
4324 }
4325
4326 static void
4327 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4328 {
4329         proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
4330 }
4331
4332 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
4333  * own copy of string, and frees it when the proto_tree is destroyed. */
4334 proto_item *
4335 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4336                       gint length, const char* value)
4337 {
4338         proto_item        *pi;
4339         header_field_info *hfinfo;
4340         gint              item_length;
4341
4342         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4343         get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
4344         /*
4345          * Special case - if the length is 0, skip the test, so that
4346          * we can have an empty string right after the end of the
4347          * packet.  (This handles URL-encoded forms where the last field
4348          * has no value so the form ends right after the =.)
4349          */
4350         if (item_length != 0)
4351                 test_length(hfinfo, tvb, start, item_length, ENC_NA);
4352
4353         CHECK_FOR_NULL_TREE(tree);
4354
4355         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4356
4357         DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
4358
4359         if (hfinfo->display == STR_UNICODE) {
4360                 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
4361         }
4362
4363         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4364         DISSECTOR_ASSERT(length >= 0);
4365         proto_tree_set_string(PNODE_FINFO(pi), value);
4366
4367         return pi;
4368 }
4369
4370 proto_item *
4371 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4372                                    gint start, gint length, const char* value,
4373                                    const char *format,
4374                                    ...)
4375 {
4376         proto_item        *pi;
4377         va_list            ap;
4378
4379         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4380         if (pi != tree) {
4381                 va_start(ap, format);
4382                 proto_tree_set_representation_value(pi, format, ap);
4383                 va_end(ap);
4384         }
4385
4386         return pi;
4387 }
4388
4389 proto_item *
4390 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4391                              gint start, gint length, const char* value,
4392                              const char *format, ...)
4393 {
4394         proto_item        *pi;
4395         va_list            ap;
4396
4397         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4398         if (pi != tree) {
4399                 TRY_TO_FAKE_THIS_REPR(pi);
4400
4401                 va_start(ap, format);
4402                 proto_tree_set_representation(pi, format, ap);
4403                 va_end(ap);
4404         }
4405
4406         return pi;
4407 }
4408
4409 /* Set the FT_STRING value */
4410 static void
4411 proto_tree_set_string(field_info *fi, const char* value)
4412 {
4413         if (value) {
4414                 fvalue_set_string(&fi->value, value);
4415         } else {
4416                 /*
4417                  * XXX - why is a null value for a string field
4418                  * considered valid?
4419                  */
4420                 fvalue_set_string(&fi->value, "[ Null ]");
4421         }
4422 }
4423
4424 /* Set the FT_AX25 value */
4425 static void
4426 proto_tree_set_ax25(field_info *fi, const guint8* value)
4427 {
4428         fvalue_set_bytes(&fi->value, value);
4429 }
4430
4431 static void
4432 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
4433 {
4434         proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
4435 }
4436
4437 /* Set the FT_VINES value */
4438 static void
4439 proto_tree_set_vines(field_info *fi, const guint8* value)
4440 {
4441         fvalue_set_bytes(&fi->value, value);
4442 }
4443
4444 static void
4445 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
4446 {
4447         proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
4448 }
4449
4450 /* Add a FT_ETHER to a proto_tree */
4451 proto_item *
4452 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4453                      gint length, const guint8* value)
4454 {
4455         proto_item        *pi;
4456         header_field_info *hfinfo;
4457
4458         CHECK_FOR_NULL_TREE(tree);
4459
4460         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4461
4462         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
4463
4464         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4465         proto_tree_set_ether(PNODE_FINFO(pi), value);
4466
4467         return pi;
4468 }
4469
4470 proto_item *
4471 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4472                                   gint start, gint length, const guint8* value,
4473                                   const char *format, ...)
4474 {
4475         proto_item        *pi;
4476         va_list            ap;
4477
4478         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
4479         if (pi != tree) {
4480                 va_start(ap, format);
4481                 proto_tree_set_representation_value(pi, format, ap);
4482                 va_end(ap);
4483         }
4484
4485         return pi;
4486 }
4487
4488 proto_item *
4489 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4490                             gint start, gint length, const guint8* value,
4491                             const char *format, ...)
4492 {
4493         proto_item        *pi;
4494         va_list            ap;
4495
4496         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
4497         if (pi != tree) {
4498                 TRY_TO_FAKE_THIS_REPR(pi);
4499
4500                 va_start(ap, format);
4501                 proto_tree_set_representation(pi, format, ap);
4502                 va_end(ap);
4503         }
4504
4505         return pi;
4506 }
4507
4508 /* Set the FT_ETHER value */
4509 static void
4510 proto_tree_set_ether(field_info *fi, const guint8* value)
4511 {
4512         fvalue_set_bytes(&fi->value, value);
4513 }
4514
4515 static void
4516 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
4517 {
4518         proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
4519 }
4520
4521 /* Add a FT_BOOLEAN to a proto_tree */
4522 proto_item *
4523 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4524                        gint length, guint32 value)
4525 {
4526         proto_item        *pi;
4527         header_field_info *hfinfo;
4528
4529         CHECK_FOR_NULL_TREE(tree);
4530
4531         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4532
4533         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
4534
4535         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4536         proto_tree_set_boolean(PNODE_FINFO(pi), value);
4537
4538         return pi;
4539 }
4540
4541 proto_item *
4542 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
4543                                     tvbuff_t *tvb, gint start, gint length,
4544                                     guint32 value, const char *format, ...)
4545 {
4546         proto_item        *pi;
4547         va_list            ap;
4548
4549         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
4550         if (pi != tree) {
4551                 va_start(ap, format);
4552                 proto_tree_set_representation_value(pi, format, ap);
4553                 va_end(ap);
4554         }
4555
4556         return pi;
4557 }
4558
4559 proto_item *
4560 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4561                               gint start, gint length, guint32 value,
4562                               const char *format, ...)
4563 {
4564         proto_item        *pi;
4565         va_list            ap;
4566
4567         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
4568         if (pi != tree) {
4569                 TRY_TO_FAKE_THIS_REPR(pi);
4570
4571                 va_start(ap, format);
4572                 proto_tree_set_representation(pi, format, ap);
4573                 va_end(ap);
4574         }
4575
4576         return pi;
4577 }
4578
4579 static proto_item *
4580 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4581                          gint length, guint64 value)
4582 {
4583         proto_item        *pi;
4584         header_field_info *hfinfo;
4585
4586         CHECK_FOR_NULL_TREE(tree);
4587
4588         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4589
4590         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
4591
4592         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4593         proto_tree_set_boolean(PNODE_FINFO(pi), value);
4594
4595         return pi;
4596 }
4597
4598 /* Set the FT_BOOLEAN value */
4599 static void
4600 proto_tree_set_boolean(field_info *fi, guint64 value)
4601 {
4602         proto_tree_set_uint64(fi, value);
4603 }
4604
4605 /* Generate, into "buf", a string showing the bits of a bitfield.
4606    Return a pointer to the character after that string. */
4607 /*XXX this needs a buf_len check */
4608 static char *
4609 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
4610 {
4611         int i;
4612         guint64 bit;
4613         char *p;
4614
4615         i = 0;
4616         p = buf;
4617         bit = G_GUINT64_CONSTANT(1) << (width - 1);
4618         for (;;) {
4619                 if (mask & bit) {
4620                         /* This bit is part of the field.  Show its value. */
4621                         if (val & bit)
4622                                 *p++ = '1';
4623                         else
4624                                 *p++ = '0';
4625                 } else {
4626                         /* This bit is not part of the field. */
4627                         *p++ = '.';
4628                 }
4629                 bit >>= 1;
4630                 i++;
4631                 if (i >= width)
4632                         break;
4633                 if (i % 4 == 0)
4634                         *p++ = ' ';
4635         }
4636         *p = '\0';
4637         return p;
4638 }
4639
4640 static char *
4641 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
4642 {
4643         char *p;
4644
4645         p = other_decode_bitfield_value(buf, val, mask, width);
4646         p = g_stpcpy(p, " = ");
4647
4648         return p;
4649 }
4650
4651 static char *
4652 other_decode_bitfield_varint_value(char *buf, guint64 val, guint64 mask, const int width)
4653 {
4654         int i = 0;
4655         guint64 bit;
4656         char *p;
4657
4658         p = buf;
4659         bit = G_GUINT64_CONSTANT(1) << (width - 1);
4660         for (;;) {
4661                 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
4662                         (mask & bit)) {
4663                         /* This bit is part of the field.  Show its value. */
4664                         if (val & bit)
4665                                 *p++ = '1';
4666                         else
4667                                 *p++ = '0';
4668                 } else {
4669                         /* This bit is not part of the field. */
4670                         *p++ = '.';
4671                 }
4672                 bit >>= 1;
4673                 i++;
4674                 if (i >= width)
4675                         break;
4676                 if (i % 4 == 0)
4677                         *p++ = ' ';
4678         }
4679
4680         *p = '\0';
4681         return p;
4682 }
4683
4684 static char *
4685 decode_bitfield_varint_value(char *buf, const guint64 val, const guint64 mask, const int width)
4686 {
4687         char *p;
4688
4689         p = other_decode_bitfield_varint_value(buf, val, mask, width);
4690         p = g_stpcpy(p, " = ");
4691
4692         return p;
4693 }
4694
4695 /* Add a FT_FLOAT to a proto_tree */
4696 proto_item *
4697 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4698                      gint length, float value)
4699 {
4700         proto_item        *pi;
4701         header_field_info *hfinfo;
4702
4703         CHECK_FOR_NULL_TREE(tree);
4704
4705         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4706
4707         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
4708
4709         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4710         proto_tree_set_float(PNODE_FINFO(pi), value);
4711
4712         return pi;
4713 }
4714
4715 proto_item *
4716 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4717                                   gint start, gint length, float value,
4718                                   const char *format, ...)
4719 {
4720         proto_item        *pi;
4721         va_list            ap;
4722
4723         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
4724         if (pi != tree) {
4725                 va_start(ap, format);
4726                 proto_tree_set_representation_value(pi, format, ap);
4727                 va_end(ap);
4728         }
4729
4730         return pi;
4731 }
4732
4733 proto_item *
4734 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4735                             gint start, gint length, float value,
4736                             const char *format, ...)
4737 {
4738         proto_item        *pi;
4739         va_list            ap;
4740
4741         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
4742         if (pi != tree) {
4743                 TRY_TO_FAKE_THIS_REPR(pi);
4744
4745                 va_start(ap, format);
4746                 proto_tree_set_representation(pi, format, ap);
4747                 va_end(ap);
4748         }
4749
4750         return pi;
4751 }
4752
4753 /* Set the FT_FLOAT value */
4754 static void
4755 proto_tree_set_float(field_info *fi, float value)
4756 {
4757         fvalue_set_floating(&fi->value, value);
4758 }
4759
4760 /* Add a FT_DOUBLE to a proto_tree */
4761 proto_item *
4762 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4763                       gint length, double value)
4764 {
4765         proto_item        *pi;
4766         header_field_info *hfinfo;
4767
4768         CHECK_FOR_NULL_TREE(tree);
4769
4770         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4771
4772         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
4773
4774         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4775         proto_tree_set_double(PNODE_FINFO(pi), value);
4776
4777         return pi;
4778 }
4779
4780 proto_item *
4781 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4782                                    gint start, gint length, double value,
4783                                    const char *format, ...)
4784 {
4785         proto_item        *pi;
4786         va_list            ap;
4787
4788         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
4789         if (pi != tree) {
4790                 va_start(ap, format);
4791                 proto_tree_set_representation_value(pi, format, ap);
4792                 va_end(ap);
4793         }
4794
4795         return pi;
4796 }
4797
4798 proto_item *
4799 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4800                              gint start, gint length, double value,
4801                              const char *format, ...)
4802 {
4803         proto_item        *pi;
4804         va_list            ap;
4805
4806         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
4807         if (pi != tree) {
4808                 TRY_TO_FAKE_THIS_REPR(pi);
4809
4810                 va_start(ap, format);
4811                 proto_tree_set_representation(pi, format, ap);
4812                 va_end(ap);
4813         }
4814
4815         return pi;
4816 }
4817
4818 /* Set the FT_DOUBLE value */
4819 static void
4820 proto_tree_set_double(field_info *fi, double value)
4821 {
4822         fvalue_set_floating(&fi->value, value);
4823 }
4824
4825 /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
4826 proto_item *
4827 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4828                     gint length, guint32 value)
4829 {
4830         proto_item        *pi = NULL;
4831         header_field_info *hfinfo;
4832
4833         CHECK_FOR_NULL_TREE(tree);
4834
4835         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4836
4837         switch (hfinfo->type) {
4838                 case FT_CHAR:
4839                 case FT_UINT8:
4840                 case FT_UINT16:
4841                 case FT_UINT24:
4842                 case FT_UINT32:
4843                 case FT_FRAMENUM:
4844                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4845                         proto_tree_set_uint(PNODE_FINFO(pi), value);
4846                         break;
4847
4848                 default:
4849                         REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",
4850                             hfinfo->abbrev);
4851         }
4852
4853         return pi;
4854 }
4855
4856 proto_item *
4857 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4858                                  gint start, gint length, guint32 value,
4859                                  const char *format, ...)
4860 {
4861         proto_item        *pi;
4862         va_list            ap;
4863
4864         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
4865         if (pi != tree) {
4866                 va_start(ap, format);
4867                 proto_tree_set_representation_value(pi, format, ap);
4868                 va_end(ap);
4869         }
4870
4871         return pi;
4872 }
4873
4874 proto_item *
4875 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4876                            gint start, gint length, guint32 value,
4877                            const char *format, ...)
4878 {
4879         proto_item        *pi;
4880         va_list            ap;
4881
4882         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
4883         if (pi != tree) {
4884                 TRY_TO_FAKE_THIS_REPR(pi);
4885
4886                 va_start(ap, format);
4887                 proto_tree_set_representation(pi, format, ap);
4888                 va_end(ap);
4889         }
4890
4891         return pi;
4892 }
4893
4894 /* Set the FT_UINT{8,16,24,32} value */
4895 static void
4896 proto_tree_set_uint(field_info *fi, guint32 value)
4897 {
4898         header_field_info *hfinfo;
4899         guint32            integer;
4900
4901         hfinfo = fi->hfinfo;
4902         integer = value;
4903
4904         if (hfinfo->bitmask) {
4905                 /* Mask out irrelevant portions */
4906                 integer &= (guint32)(hfinfo->bitmask);
4907
4908                 /* Shift bits */
4909                 integer >>= hfinfo_bitshift(hfinfo);
4910         }
4911
4912         fvalue_set_uinteger(&fi->value, integer);
4913 }
4914
4915 /* Add FT_UINT{40,48,56,64} to a proto_tree */
4916 proto_item *
4917 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4918                       gint length, guint64 value)
4919 {
4920         proto_item        *pi = NULL;
4921         header_field_info *hfinfo;
4922
4923         CHECK_FOR_NULL_TREE(tree);
4924
4925         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4926
4927         switch (hfinfo->type) {
4928                 case FT_UINT40:
4929                 case FT_UINT48:
4930                 case FT_UINT56:
4931                 case FT_UINT64:
4932                 case FT_FRAMENUM:
4933                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4934                         proto_tree_set_uint64(PNODE_FINFO(pi), value);
4935                         break;
4936
4937                 default:
4938                         REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",
4939                             hfinfo->abbrev);
4940         }
4941
4942         return pi;
4943 }
4944
4945 proto_item *
4946 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4947                                    gint start, gint length, guint64 value,
4948                                    const char *format, ...)
4949 {
4950         proto_item        *pi;
4951         va_list            ap;
4952
4953         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4954         if (pi != tree) {
4955                 va_start(ap, format);
4956                 proto_tree_set_representation_value(pi, format, ap);
4957                 va_end(ap);
4958         }
4959
4960         return pi;
4961 }
4962
4963 proto_item *
4964 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4965                              gint start, gint length, guint64 value,
4966                              const char *format, ...)
4967 {
4968         proto_item        *pi;
4969         va_list            ap;
4970
4971         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4972         if (pi != tree) {
4973                 TRY_TO_FAKE_THIS_REPR(pi);
4974
4975                 va_start(ap, format);
4976                 proto_tree_set_representation(pi, format, ap);
4977                 va_end(ap);
4978         }
4979
4980         return pi;
4981 }
4982
4983 /* Set the FT_UINT{40,48,56,64} value */
4984 static void
4985 proto_tree_set_uint64(field_info *fi, guint64 value)
4986 {
4987         header_field_info *hfinfo;
4988         guint64            integer;
4989
4990         hfinfo = fi->hfinfo;
4991         integer = value;
4992
4993         if (hfinfo->bitmask) {
4994                 /* Mask out irrelevant portions */
4995                 integer &= hfinfo->bitmask;
4996
4997                 /* Shift bits */
4998                 integer >>= hfinfo_bitshift(hfinfo);
4999         }
5000
5001         fvalue_set_uinteger64(&fi->value, integer);
5002 }
5003
5004 /* Add FT_INT{8,16,24,32} to a proto_tree */
5005 proto_item *
5006 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5007                    gint length, gint32 value)
5008 {
5009         proto_item        *pi = NULL;
5010         header_field_info *hfinfo;
5011
5012         CHECK_FOR_NULL_TREE(tree);
5013
5014         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5015
5016         switch (hfinfo->type) {
5017                 case FT_INT8:
5018                 case FT_INT16:
5019                 case FT_INT24:
5020                 case FT_INT32:
5021                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5022                         proto_tree_set_int(PNODE_FINFO(pi), value);
5023                         break;
5024
5025                 default:
5026                         REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
5027                             hfinfo->abbrev);
5028         }
5029
5030         return pi;
5031 }
5032
5033 proto_item *
5034 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5035                                 gint start, gint length, gint32 value,
5036                                 const char *format, ...)
5037 {
5038         proto_item  *pi;
5039         va_list      ap;
5040
5041         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
5042         if (pi != tree) {
5043                 va_start(ap, format);
5044                 proto_tree_set_representation_value(pi, format, ap);
5045                 va_end(ap);
5046         }
5047
5048         return pi;
5049 }
5050
5051 proto_item *
5052 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5053                           gint start, gint length, gint32 value,
5054                           const char *format, ...)
5055 {
5056         proto_item *pi;
5057         va_list     ap;
5058
5059         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
5060         if (pi != tree) {
5061                 TRY_TO_FAKE_THIS_REPR(pi);
5062
5063                 va_start(ap, format);
5064                 proto_tree_set_representation(pi, format, ap);
5065                 va_end(ap);
5066         }
5067
5068         return pi;
5069 }
5070
5071 /* Set the FT_INT{8,16,24,32} value */
5072 static void
5073 proto_tree_set_int(field_info *fi, gint32 value)
5074 {
5075         header_field_info *hfinfo;
5076         guint32            integer;
5077         gint               no_of_bits;
5078
5079         hfinfo = fi->hfinfo;
5080         integer = (guint32) value;
5081
5082         if (hfinfo->bitmask) {
5083                 /* Mask out irrelevant portions */
5084                 integer &= (guint32)(hfinfo->bitmask);
5085
5086                 /* Shift bits */
5087                 integer >>= hfinfo_bitshift(hfinfo);
5088
5089                 no_of_bits = ws_count_ones(hfinfo->bitmask);
5090                 integer = ws_sign_ext32(integer, no_of_bits);
5091         }
5092
5093         fvalue_set_sinteger(&fi->value, integer);
5094 }
5095
5096 /* Add FT_INT{40,48,56,64} to a proto_tree */
5097 proto_item *
5098 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5099                      gint length, gint64 value)
5100 {
5101         proto_item        *pi = NULL;
5102         header_field_info *hfinfo;
5103
5104         CHECK_FOR_NULL_TREE(tree);
5105
5106         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5107
5108         switch (hfinfo->type) {
5109                 case FT_INT40:
5110                 case FT_INT48:
5111                 case FT_INT56:
5112                 case FT_INT64:
5113                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5114                         proto_tree_set_int64(PNODE_FINFO(pi), value);
5115                         break;
5116
5117                 default:
5118                         REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
5119                             hfinfo->abbrev);
5120         }
5121
5122         return pi;
5123 }
5124
5125 proto_item *
5126 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5127                                   gint start, gint length, gint64 value,
5128                                   const char *format, ...)
5129 {
5130         proto_item        *pi;
5131         va_list            ap;
5132
5133         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
5134         if (pi != tree) {
5135                 va_start(ap, format);
5136                 proto_tree_set_representation_value(pi, format, ap);
5137                 va_end(ap);
5138         }
5139
5140         return pi;
5141 }
5142
5143 /* Set the FT_INT{40,48,56,64} value */
5144 static void
5145 proto_tree_set_int64(field_info *fi, gint64 value)
5146 {
5147         header_field_info *hfinfo;
5148         guint64            integer;
5149         gint               no_of_bits;
5150
5151         hfinfo = fi->hfinfo;
5152         integer = value;
5153
5154         if (hfinfo->bitmask) {
5155                 /* Mask out irrelevant portions */
5156                 integer &= hfinfo->bitmask;
5157
5158                 /* Shift bits */
5159                 integer >>= hfinfo_bitshift(hfinfo);
5160
5161                 no_of_bits = ws_count_ones(hfinfo->bitmask);
5162                 integer = ws_sign_ext64(integer, no_of_bits);
5163         }
5164
5165         fvalue_set_sinteger64(&fi->value, integer);
5166 }
5167
5168 proto_item *
5169 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5170                            gint start, gint length, gint64 value,
5171                            const char *format, ...)
5172 {
5173         proto_item        *pi;
5174         va_list            ap;
5175
5176         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
5177         if (pi != tree) {
5178                 TRY_TO_FAKE_THIS_REPR(pi);
5179
5180                 va_start(ap, format);
5181                 proto_tree_set_representation(pi, format, ap);
5182                 va_end(ap);
5183         }
5184
5185         return pi;
5186 }
5187
5188 /* Add a FT_EUI64 to a proto_tree */
5189 proto_item *
5190 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5191                      gint length, const guint64 value)
5192 {
5193         proto_item        *pi;
5194         header_field_info *hfinfo;
5195
5196         CHECK_FOR_NULL_TREE(tree);
5197
5198         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5199
5200         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
5201
5202         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5203         proto_tree_set_eui64(PNODE_FINFO(pi), value);
5204
5205         return pi;
5206 }
5207
5208 proto_item *
5209 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5210                                   gint start, gint length, const guint64 value,
5211                                   const char *format, ...)
5212 {
5213         proto_item        *pi;
5214         va_list            ap;
5215
5216         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5217         if (pi != tree) {
5218                 va_start(ap, format);
5219                 proto_tree_set_representation_value(pi, format, ap);
5220                 va_end(ap);
5221         }
5222
5223         return pi;
5224 }
5225
5226 proto_item *
5227 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5228                             gint start, gint length, const guint64 value,
5229                             const char *format, ...)
5230 {
5231         proto_item        *pi;
5232         va_list            ap;
5233
5234         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5235         if (pi != tree) {
5236                 TRY_TO_FAKE_THIS_REPR(pi);
5237
5238                 va_start(ap, format);
5239                 proto_tree_set_representation(pi, format, ap);
5240                 va_end(ap);
5241         }
5242
5243         return pi;
5244 }
5245
5246 /* Set the FT_EUI64 value */
5247 static void
5248 proto_tree_set_eui64(field_info *fi, const guint64 value)
5249 {
5250         fvalue_set_uinteger64(&fi->value, value);
5251 }
5252 static void
5253 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
5254 {
5255         if (encoding)
5256         {
5257                 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
5258         } else {
5259                 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
5260         }
5261 }
5262
5263 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
5264 static proto_item *
5265 proto_tree_add_node(proto_tree *tree, field_info *fi)
5266 {
5267         proto_node *pnode, *tnode, *sibling;
5268         field_info *tfi;
5269         int depth = 1;
5270
5271         /*
5272          * Restrict our depth. proto_tree_traverse_pre_order and
5273          * proto_tree_traverse_post_order (and possibly others) are recursive
5274          * so we need to be mindful of our stack size.
5275          */
5276         if (tree->first_child == NULL) {
5277                 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
5278                         depth++;
5279                         if (G_UNLIKELY(depth > MAX_TREE_LEVELS)) {
5280                                 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
5281                                                      "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u)",
5282                                                      MAX_TREE_LEVELS,
5283                                                      fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
5284                         }
5285                 }
5286         }
5287
5288         /*
5289          * Make sure "tree" is ready to have subtrees under it, by
5290          * checking whether it's been given an ett_ value.
5291          *
5292          * "PNODE_FINFO(tnode)" may be null; that's the case for the root
5293          * node of the protocol tree.  That node is not displayed,
5294          * so it doesn't need an ett_ value to remember whether it
5295          * was expanded.
5296          */
5297         tnode = tree;
5298         tfi = PNODE_FINFO(tnode);
5299         if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
5300                 REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
5301                                      fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__);
5302                 /* XXX - is it safe to continue here? */
5303         }
5304
5305         pnode = wmem_new(PNODE_POOL(tree), proto_node);
5306         PROTO_NODE_INIT(pnode);
5307         pnode->parent = tnode;
5308         PNODE_FINFO(pnode) = fi;
5309         pnode->tree_data = PTREE_DATA(tree);
5310
5311         if (tnode->last_child != NULL) {
5312                 sibling = tnode->last_child;
5313                 DISSECTOR_ASSERT(sibling->next == NULL);
5314                 sibling->next = pnode;
5315         } else
5316                 tnode->first_child = pnode;
5317         tnode->last_child = pnode;
5318
5319         tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
5320
5321         return (proto_item *)pnode;
5322 }
5323
5324
5325 /* Generic way to allocate field_info and add to proto_tree.
5326  * Sets *pfi to address of newly-allocated field_info struct */
5327 static proto_item *
5328 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
5329                   gint *length)
5330 {
5331         proto_item *pi;
5332         field_info *fi;
5333         gint            item_length;
5334
5335         get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA);
5336         fi = new_field_info(tree, hfinfo, tvb, start, item_length);
5337         pi = proto_tree_add_node(tree, fi);
5338
5339         return pi;
5340 }
5341
5342
5343 static void
5344 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
5345                    gint *item_length, const guint encoding)
5346 {
5347         gint length_remaining;
5348
5349         /*
5350          * We only allow a null tvbuff if the item has a zero length,
5351          * i.e. if there's no data backing it.
5352          */
5353         DISSECTOR_ASSERT(tvb != NULL || *length == 0);
5354
5355         /*
5356          * XXX - in some protocols, there are 32-bit unsigned length
5357          * fields, so lengths in protocol tree and tvbuff routines
5358          * should really be unsigned.  We should have, for those
5359          * field types for which "to the end of the tvbuff" makes sense,
5360          * additional routines that take no length argument and
5361          * add fields that run to the end of the tvbuff.
5362          */
5363         if (*length == -1) {
5364                 /*
5365                  * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
5366                  * FT_STRINGZPAD fields, a length of -1 means "set the
5367                  * length to what remains in the tvbuff".
5368                  *
5369                  * The assumption is either that
5370                  *
5371                  *      1) the length of the item can only be determined
5372                  *         by dissection (typically true of items with
5373                  *         subitems, which are probably FT_NONE or
5374                  *         FT_PROTOCOL)
5375                  *
5376                  * or
5377                  *
5378                  *      2) if the tvbuff is "short" (either due to a short
5379                  *         snapshot length or due to lack of reassembly of
5380                  *         fragments/segments/whatever), we want to display
5381                  *         what's available in the field (probably FT_BYTES
5382                  *         or FT_STRING) and then throw an exception later
5383                  *
5384                  * or
5385                  *
5386                  *      3) the field is defined to be "what's left in the
5387                  *         packet"
5388                  *
5389                  * so we set the length to what remains in the tvbuff so
5390                  * that, if we throw an exception while dissecting, it
5391                  * has what is probably the right value.
5392                  *
5393                  * For FT_STRINGZ, it means "the string is null-terminated,
5394                  * not null-padded; set the length to the actual length
5395                  * of the string", and if the tvbuff if short, we just
5396                  * throw an exception.
5397                  *
5398                  * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC, it means "find the end of the string",
5399                  * and if the tvbuff if short, we just throw an exception.
5400                  *
5401                  * It's not valid for any other type of field.  For those
5402                  * fields, we treat -1 the same way we treat other
5403                  * negative values - we assume the length is a Really
5404                  * Big Positive Number, and throw a ReportedBoundsError
5405                  * exception, under the assumption that the Really Big
5406                  * Length would run past the end of the packet.
5407                  */
5408                 if ((IS_FT_INT(hfinfo->type)) || (IS_FT_UINT(hfinfo->type))) {
5409                         if (encoding & ENC_VARINT_PROTOBUF) {
5410                                 /*
5411                                  * Leave the length as -1, so our caller knows
5412                                  * it was -1.
5413                                  */
5414                                 *item_length = *length;
5415                                 return;
5416                         } else if (encoding & ENC_VARINT_QUIC) {
5417                                 switch (tvb_get_guint8(tvb, start) >> 6)
5418                                 {
5419                                 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
5420                                         *item_length = 1;
5421                                         break;
5422                                 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
5423                                         *item_length = 2;
5424                                         break;
5425                                 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
5426                                         *item_length = 4;
5427                                         break;
5428                                 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
5429                                         *item_length = 8;
5430                                         break;
5431                                 }
5432                         }
5433                 }
5434
5435                 switch (hfinfo->type) {
5436
5437                 case FT_PROTOCOL:
5438                 case FT_NONE:
5439                 case FT_BYTES:
5440                 case FT_STRING:
5441                 case FT_STRINGZPAD:
5442                         /*
5443                          * We allow FT_PROTOCOLs to be zero-length -
5444                          * for example, an ONC RPC NULL procedure has
5445                          * neither arguments nor reply, so the
5446                          * payload for that protocol is empty.
5447                          *
5448                          * We also allow the others to be zero-length -
5449                          * because that's the way the code has been for a
5450                          * long, long time.
5451                          *
5452                          * However, we want to ensure that the start
5453                          * offset is not *past* the byte past the end
5454                          * of the tvbuff: we throw an exception in that
5455                          * case.
5456                          */
5457                         *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
5458                         DISSECTOR_ASSERT(*length >= 0);
5459                         break;
5460
5461                 case FT_STRINGZ:
5462                         /*
5463                          * Leave the length as -1, so our caller knows
5464                          * it was -1.
5465                          */
5466                         break;
5467
5468                 default:
5469                         THROW(ReportedBoundsError);
5470                         DISSECTOR_ASSERT_NOT_REACHED();
5471                 }
5472                 *item_length = *length;
5473         } else {
5474                 *item_length = *length;
5475                 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
5476                         /*
5477                          * These types are for interior nodes of the
5478                          * tree, and don't have data associated with
5479                          * them; if the length is negative (XXX - see
5480                          * above) or goes past the end of the tvbuff,
5481                          * cut it short at the end of the tvbuff.
5482                          * That way, if this field is selected in
5483                          * Wireshark, we don't highlight stuff past
5484                          * the end of the data.
5485                          */
5486                         /* XXX - what to do, if we don't have a tvb? */
5487                         if (tvb) {
5488                                 length_remaining = tvb_captured_length_remaining(tvb, start);
5489                                 if (*item_length < 0 ||
5490                                         (*item_length > 0 &&
5491                                           (length_remaining < *item_length)))
5492                                         *item_length = length_remaining;
5493                         }
5494                 }
5495                 if (*item_length < 0) {
5496                         THROW(ReportedBoundsError);
5497                 }
5498         }
5499 }
5500
5501 static gint
5502 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
5503                 gint length, guint item_length, const gint encoding)
5504 {
5505         guint32 n;
5506
5507         /*
5508          * We need to get the correct item length here.
5509          * That's normally done by proto_tree_new_item(),
5510          * but we won't be calling it.
5511          */
5512         switch (hfinfo->type) {
5513
5514         case FT_NONE:
5515         case FT_PROTOCOL:
5516         case FT_BYTES:
5517                 /*
5518                  * The length is the specified length.
5519                  */
5520                 break;
5521
5522         case FT_UINT_BYTES:
5523                 n = get_uint_value(NULL, tvb, start, length, encoding);
5524                 item_length += n;
5525                 break;
5526
5527         /* XXX - make these just FT_UINT? */
5528         case FT_UINT8:
5529         case FT_UINT16:
5530         case FT_UINT24:
5531         case FT_UINT32:
5532         case FT_UINT40:
5533         case FT_UINT48:
5534         case FT_UINT56:
5535         case FT_UINT64:
5536         /* XXX - make these just FT_INT? */
5537         case FT_INT8:
5538         case FT_INT16:
5539         case FT_INT24:
5540         case FT_INT32:
5541         case FT_INT40:
5542         case FT_INT48:
5543         case FT_INT56:
5544         case FT_INT64:
5545                 if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC)) {
5546                         if (length < -1) {
5547                                 report_type_length_mismatch(NULL, "a FT_[U]INT", length, TRUE);
5548                         }
5549                         if (length == -1) {
5550                                 guint64 dummy;
5551                                 /* This can throw an exception */
5552                                 /* XXX - do this without fetching the varint? */
5553                                 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN, &dummy, encoding);
5554                                 if (length == 0) {
5555                                         THROW(ReportedBoundsError);
5556                                 }
5557                         }
5558                         item_length = length;
5559                         break;
5560                 }
5561
5562                 /*
5563                  * The length is the specified length.
5564                  */
5565                 break;
5566
5567         case FT_BOOLEAN:
5568         case FT_CHAR:
5569         case FT_IPv4:
5570         case FT_IPXNET:
5571         case FT_IPv6:
5572         case FT_FCWWN:
5573         case FT_AX25:
5574         case FT_VINES:
5575         case FT_ETHER:
5576         case FT_EUI64:
5577         case FT_GUID:
5578         case FT_OID:
5579         case FT_REL_OID:
5580         case FT_SYSTEM_ID:
5581         case FT_FLOAT:
5582         case FT_DOUBLE:
5583         case FT_STRING:
5584                 /*
5585                  * The length is the specified length.
5586                  */
5587                 break;
5588
5589         case FT_STRINGZ:
5590                 if (length < -1) {
5591                         report_type_length_mismatch(NULL, "a string", length, TRUE);
5592                 }
5593                 if (length == -1) {
5594                         /* This can throw an exception */
5595                         /* XXX - do this without fetching the string? */
5596                         tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
5597                 }
5598                 item_length = length;
5599                 break;
5600
5601         case FT_UINT_STRING:
5602                 if (encoding & ENC_ZIGBEE) {
5603                         n = get_uint_value(NULL, tvb, start, length, encoding);
5604                 } else {
5605                         n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
5606                 }
5607                 item_length += n;
5608                 break;
5609
5610         case FT_STRINGZPAD:
5611         case FT_ABSOLUTE_TIME:
5612         case FT_RELATIVE_TIME:
5613         case FT_IEEE_11073_SFLOAT:
5614         case FT_IEEE_11073_FLOAT:
5615                 /*
5616                  * The length is the specified length.
5617                  */
5618                 break;
5619
5620         default:
5621                 g_error("hfinfo->type %d (%s) not handled\n",
5622                                 hfinfo->type,
5623                                 ftype_name(hfinfo->type));
5624                 DISSECTOR_ASSERT_NOT_REACHED();
5625                 break;
5626         }
5627         return item_length;
5628 }
5629
5630 static field_info *
5631 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
5632                const gint start, const gint item_length)
5633 {
5634         field_info *fi;
5635
5636         FIELD_INFO_NEW(PNODE_POOL(tree), fi);
5637
5638         fi->hfinfo     = hfinfo;
5639         fi->start      = start;
5640         fi->start     += (tvb)?tvb_raw_offset(tvb):0;
5641         fi->length     = item_length;
5642         fi->tree_type  = -1;
5643         fi->flags      = 0;
5644         if (!PTREE_DATA(tree)->visible)
5645                 FI_SET_FLAG(fi, FI_HIDDEN);
5646         fvalue_init(&fi->value, fi->hfinfo->type);
5647         fi->rep        = NULL;
5648
5649         /* add the data source tvbuff */
5650         fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
5651
5652         fi->appendix_start  = 0;
5653         fi->appendix_length = 0;
5654
5655         return fi;
5656 }
5657
5658 /* If the protocol tree is to be visible, set the representation of a
5659    proto_tree entry with the name of the field for the item and with
5660    the value formatted with the supplied printf-style format and
5661    argument list. */
5662 static void
5663 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
5664 {
5665         g_assert(pi);
5666
5667         /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
5668          * items string representation */
5669         if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
5670                 int               ret = 0;
5671                 field_info        *fi = PITEM_FINFO(pi);
5672                 header_field_info *hf;
5673
5674                 DISSECTOR_ASSERT(fi);
5675
5676                 hf = fi->hfinfo;
5677
5678                 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5679                 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
5680                         guint64 val;
5681                         char *p;
5682
5683                         if (IS_FT_UINT32(hf->type))
5684                                 val = fvalue_get_uinteger(&fi->value);
5685                         else
5686                                 val = fvalue_get_uinteger64(&fi->value);
5687
5688                         val <<= hfinfo_bitshift(hf);
5689
5690                         p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
5691                         ret = (int) (p - fi->rep->representation);
5692                 }
5693
5694                 /* put in the hf name */
5695                 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
5696
5697                 /* If possible, Put in the value of the string */
5698                 if (ret < ITEM_LABEL_LENGTH) {
5699                         ret += g_vsnprintf(fi->rep->representation + ret,
5700                                           ITEM_LABEL_LENGTH - ret, format, ap);
5701                 }
5702                 if (ret >= ITEM_LABEL_LENGTH) {
5703                         /* Uh oh, we don't have enough room.  Tell the user
5704                          * that the field is truncated.
5705                          */
5706                         LABEL_MARK_TRUNCATED_START(fi->rep->representation);
5707                 }
5708         }
5709 }
5710
5711 /* If the protocol tree is to be visible, set the representation of a
5712    proto_tree entry with the representation formatted with the supplied
5713    printf-style format and argument list. */
5714 static void
5715 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
5716 {
5717         int         ret;        /*tmp return value */
5718         field_info *fi = PITEM_FINFO(pi);
5719
5720         DISSECTOR_ASSERT(fi);
5721
5722         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5723                 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5724                 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
5725                                   format, ap);
5726                 if (ret >= ITEM_LABEL_LENGTH) {
5727                         /* Uh oh, we don't have enough room.  Tell the user
5728                          * that the field is truncated.
5729                          */
5730                         LABEL_MARK_TRUNCATED_START(fi->rep->representation);
5731                 }
5732         }
5733 }
5734
5735 static char *
5736 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
5737 {
5738         switch (hfinfo->display) {
5739                 case STR_ASCII:
5740                         return format_text(NULL, string, strlen(string));
5741 /*
5742                 case STR_ASCII_WSP
5743                         return format_text_wsp(string, strlen(string));
5744  */
5745                 case STR_UNICODE:
5746                         /* XXX, format_unicode_text() */
5747                         return wmem_strdup(NULL, string);
5748         }
5749
5750         return format_text(NULL, string, strlen(string));
5751 }
5752
5753 static int
5754 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
5755 {
5756         gsize res = g_strlcpy(dest, src, dest_size);
5757
5758         if (res > dest_size)
5759                 res = dest_size;
5760         return (int) res;
5761 }
5762
5763 static header_field_info *
5764 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
5765 {
5766         header_field_info *dup_hfinfo;
5767
5768         if (hfinfo->same_name_prev_id == -1)
5769                 return NULL;
5770         PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
5771         return dup_hfinfo;
5772 }
5773
5774 static void
5775 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
5776 {
5777         g_free(last_field_name);
5778         last_field_name = NULL;
5779
5780         if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
5781                 /* No hfinfo with the same name */
5782                 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
5783                 return;
5784         }
5785
5786         if (hfinfo->same_name_next) {
5787                 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
5788         }
5789
5790         if (hfinfo->same_name_prev_id != -1) {
5791                 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
5792                 same_name_prev->same_name_next = hfinfo->same_name_next;
5793                 if (!hfinfo->same_name_next) {
5794                         /* It's always the latest added hfinfo which is stored in gpa_name_map */
5795                         g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
5796                 }
5797         }
5798 }
5799
5800 /* -------------------------- */
5801 const gchar *
5802 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
5803                  gchar *result, gchar *expr, const int size)
5804 {
5805         guint32             number;
5806         guint64             number64;
5807         guint8             *bytes;
5808         guint32             ipv4;
5809         ws_in6_addr        *ipv6;
5810         address             addr;
5811
5812         const true_false_string  *tfstring;
5813
5814         int                 len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
5815         GPtrArray          *finfos;
5816         field_info         *finfo         = NULL;
5817         header_field_info*  hfinfo;
5818         const gchar        *abbrev        = NULL;
5819
5820         const char *hf_str_val;
5821         char number_buf[48];
5822         const char *number_out;
5823         char *tmpbuf, *str;
5824         int *field_idx;
5825         int field_id;
5826         int ii = 0;
5827
5828         g_assert(field_ids != NULL);
5829         while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
5830                 field_id = *field_idx;
5831                 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
5832
5833                 /* do we need to rewind ? */
5834                 if (!hfinfo)
5835                         return "";
5836
5837                 if (occurrence < 0) {
5838                         /* Search other direction */
5839                         while (hfinfo->same_name_prev_id != -1) {
5840                                 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
5841                         }
5842                 }
5843
5844                 while (hfinfo) {
5845                         finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
5846
5847                         if (!finfos || !(len = g_ptr_array_len(finfos))) {
5848                                 if (occurrence < 0) {
5849                                         hfinfo = hfinfo->same_name_next;
5850                                 } else {
5851                                         hfinfo = hfinfo_same_name_get_prev(hfinfo);
5852                                 }
5853                                 continue;
5854                         }
5855
5856                         /* Are there enough occurrences of the field? */
5857                         if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
5858                                 if (occurrence < 0) {
5859                                         hfinfo = hfinfo->same_name_next;
5860                                 } else {
5861                                         hfinfo = hfinfo_same_name_get_prev(hfinfo);
5862                                 }
5863                                 prev_len += len;
5864                                 continue;
5865                         }
5866
5867                         /* Calculate single index or set outer bounderies */
5868                         if (occurrence < 0) {
5869                                 i = occurrence + len + prev_len;
5870                                 last = i;
5871                         } else if (occurrence > 0) {
5872                                 i = occurrence - 1 - prev_len;
5873                                 last = i;
5874                         } else {
5875                                 i = 0;
5876                                 last = len - 1;
5877                         }
5878
5879                         prev_len += len; /* Count handled occurrences */
5880
5881                         while (i <= last) {
5882                                 finfo = (field_info *)g_ptr_array_index(finfos, i);
5883
5884                                 if (offset_r && (offset_r < (size - 2)))
5885                                         result[offset_r++] = ',';
5886
5887                                 if (offset_e && (offset_e < (size - 2)))
5888                                         expr[offset_e++] = ',';
5889
5890                                 switch (hfinfo->type) {
5891
5892                                         case FT_NONE:
5893                                         case FT_PROTOCOL:
5894                                                 /* prevent multiple check marks by setting result directly */
5895                                                 g_strlcpy(result, UTF8_CHECK_MARK, size);
5896                                                 break;
5897
5898                                         case FT_UINT_BYTES:
5899                                         case FT_BYTES:
5900                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
5901                                                 if (bytes) {
5902                                                         switch (hfinfo->display) {
5903                                                         case SEP_DOT:
5904                                                                 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
5905                                                                 break;
5906                                                         case SEP_DASH:
5907                                                                 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
5908                                                                 break;
5909                                                         case SEP_COLON:
5910                                                                 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
5911                                                                 break;
5912                                                         case SEP_SPACE:
5913                                                                 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5914                                                                 break;
5915                                                         case BASE_NONE:
5916                                                         default:
5917                                                                 if (prefs.display_byte_fields_with_spaces) {
5918                                                                         str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
5919                                                                 } else {
5920                                                                         str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
5921                                                                 }
5922                                                                 break;
5923                                                         }
5924                                                         offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5925                                                         wmem_free(NULL, str);
5926                                                 }
5927                                                 else {
5928                                                         if (hfinfo->display & BASE_ALLOW_ZERO) {
5929                                                                 offset_r += protoo_strlcpy(result+offset_r, "<none>", size-offset_r);
5930                                                         } else {
5931                                                                 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
5932                                                         }
5933                                                 }
5934                                                 break;
5935
5936                                         case FT_ABSOLUTE_TIME:
5937                                                 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
5938                                                 offset_r += protoo_strlcpy(result+offset_r,
5939                                                                 tmpbuf,
5940                                                                 size-offset_r);
5941                                                 wmem_free(NULL, tmpbuf);
5942                                                 break;
5943
5944                                         case FT_RELATIVE_TIME:
5945                                                 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
5946                                                 offset_r += protoo_strlcpy(result+offset_r,
5947                                                                 tmpbuf,
5948                                                                 size-offset_r);
5949                                                 wmem_free(NULL, tmpbuf);
5950                                                 break;
5951
5952                                         case FT_BOOLEAN:
5953                                                 number64 = fvalue_get_uinteger64(&finfo->value);
5954                                                 tfstring = (const true_false_string *)&tfs_true_false;
5955                                                 if (hfinfo->strings) {
5956                                                         tfstring = (const struct true_false_string*) hfinfo->strings;
5957                                                 }
5958                                                 offset_r += protoo_strlcpy(result+offset_r,
5959                                                                 number64 ?
5960                                                                 tfstring->true_string :
5961                                                                 tfstring->false_string, size-offset_r);
5962
5963                                                 offset_e += protoo_strlcpy(expr+offset_e,
5964                                                                 number64 ? "1" : "0", size-offset_e);
5965                                                 break;
5966
5967                                         case FT_CHAR:
5968                                                 hf_str_val = NULL;
5969                                                 number = fvalue_get_uinteger(&finfo->value);
5970
5971                                                 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
5972                                                         gchar tmp[ITEM_LABEL_LENGTH];
5973                                                         custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5974
5975                                                         DISSECTOR_ASSERT(fmtfunc);
5976                                                         fmtfunc(tmp, number);
5977
5978                                                         offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5979
5980                                                 } else if (hfinfo->strings) {
5981                                                         number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5982
5983                                                         if (!number_out)
5984                                                                 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
5985
5986                                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5987
5988                                                 } else {
5989                                                         number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5990
5991                                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5992                                                 }
5993
5994                                                 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
5995                                                         g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5996                                                 } else {
5997                                                         number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
5998
5999                                                         g_strlcpy(expr+offset_e, number_out, size-offset_e);
6000                                                 }
6001
6002                                                 offset_e = (int)strlen(expr);
6003                                                 break;
6004
6005                                                 /* XXX - make these just FT_NUMBER? */
6006                                         case FT_INT8:
6007                                         case FT_INT16:
6008                                         case FT_INT24:
6009                                         case FT_INT32:
6010                                         case FT_UINT8:
6011                                         case FT_UINT16:
6012                                         case FT_UINT24:
6013                                         case FT_UINT32:
6014                                         case FT_FRAMENUM:
6015                                                 hf_str_val = NULL;
6016                                                 number = IS_FT_INT(hfinfo->type) ?
6017                                                         (guint32) fvalue_get_sinteger(&finfo->value) :
6018                                                         fvalue_get_uinteger(&finfo->value);
6019
6020                                                 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6021                                                         gchar tmp[ITEM_LABEL_LENGTH];
6022                                                         custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
6023
6024                                                         DISSECTOR_ASSERT(fmtfunc);
6025                                                         fmtfunc(tmp, number);
6026
6027                                                         offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
6028
6029                                                 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
6030                                                         if (hfinfo->display & BASE_UNIT_STRING) {
6031                                                                 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
6032                                                                 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6033                                                                 hf_str_val = hf_try_val_to_str(number, hfinfo);
6034                                                                 offset_r += protoo_strlcpy(result+offset_r, hf_str_val, size-offset_r);
6035                                                         } else {
6036                                                                 number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
6037
6038                                                                 if (!number_out)
6039                                                                         number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
6040
6041                                                                 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6042                                                         }
6043                                                 } else {
6044                                                         number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
6045
6046                                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6047                                                 }
6048
6049                                                 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6050                                                         g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6051                                                 } else {
6052                                                         number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
6053
6054                                                         g_strlcpy(expr+offset_e, number_out, size-offset_e);
6055                                                 }
6056
6057                                                 offset_e = (int)strlen(expr);
6058                                                 break;
6059
6060                                         case FT_INT40:
6061                                         case FT_INT48:
6062                                         case FT_INT56:
6063                                         case FT_INT64:
6064                                         case FT_UINT40:
6065                                         case FT_UINT48:
6066                                         case FT_UINT56:
6067                                         case FT_UINT64:
6068                                                 hf_str_val = NULL;
6069                                                 number64 = IS_FT_INT(hfinfo->type) ?
6070                                                         (guint64) fvalue_get_sinteger64(&finfo->value) :
6071                                                         fvalue_get_uinteger64(&finfo->value);
6072
6073                                                 if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6074                                                         gchar tmp[ITEM_LABEL_LENGTH];
6075                                                         custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
6076
6077                                                         DISSECTOR_ASSERT(fmtfunc64);
6078                                                         fmtfunc64(tmp, number64);
6079                                                         offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
6080                                                 } else if (hfinfo->strings) {
6081                                                         if (hfinfo->display & BASE_UNIT_STRING) {
6082                                                                 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
6083                                                                 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6084                                                                 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6085                                                                 offset_r += protoo_strlcpy(result+offset_r, hf_str_val, size-offset_r);
6086                                                         } else {
6087                                                                 number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6088
6089                                                                 if (!number_out)
6090                                                                         number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
6091
6092                                                                 offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6093                                                         }
6094                                                 } else {
6095                                                         number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
6096
6097                                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
6098                                                 }
6099
6100                                                 if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6101                                                         g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6102                                                 } else {
6103                                                         number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
6104
6105                                                         g_strlcpy(expr+offset_e, number_out, size-offset_e);
6106                                                 }
6107
6108                                                 offset_e = (int)strlen(expr);
6109                                                 break;
6110
6111                                         case FT_EUI64:
6112                                                 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
6113                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6114                                                 wmem_free(NULL, str);
6115                                                 break;
6116
6117                                         case FT_IPv4:
6118                                                 ipv4 = fvalue_get_uinteger(&finfo->value);
6119                                                 set_address (&addr, AT_IPv4, 4, &ipv4);
6120                                                 address_to_str_buf(&addr, result+offset_r, size-offset_r);
6121                                                 offset_r = (int)strlen(result);
6122                                                 break;
6123
6124                                         case FT_IPv6:
6125                                                 ipv6 = (ws_in6_addr *)fvalue_get(&finfo->value);
6126                                                 set_address (&addr, AT_IPv6, sizeof(ws_in6_addr), ipv6);
6127                                                 address_to_str_buf(&addr, result+offset_r, size-offset_r);
6128                                                 offset_r = (int)strlen(result);
6129                                                 break;
6130
6131                                         case FT_FCWWN:
6132                                                 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
6133                                                 address_to_str_buf(&addr, result+offset_r, size-offset_r);
6134                                                 offset_r = (int)strlen(result);
6135                                                 break;
6136
6137                                         case FT_ETHER:
6138                                                 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
6139                                                 address_to_str_buf(&addr, result+offset_r, size-offset_r);
6140                                                 offset_r = (int)strlen(result);
6141                                                 break;
6142
6143                                         case FT_GUID:
6144                                                 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
6145                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6146                                                 wmem_free(NULL, str);
6147                                                 break;
6148
6149                                         case FT_REL_OID:
6150                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
6151                                                 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
6152                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6153                                                 wmem_free(NULL, str);
6154
6155                                                 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
6156                                                 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6157                                                 wmem_free(NULL, str);
6158                                                 break;
6159
6160                                         case FT_OID:
6161                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
6162                                                 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
6163                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6164                                                 wmem_free(NULL, str);
6165
6166                                                 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
6167                                                 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6168                                                 wmem_free(NULL, str);
6169                                                 break;
6170
6171                                         case FT_SYSTEM_ID:
6172                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
6173                                                 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
6174                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6175                                                 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6176                                                 wmem_free(NULL, str);
6177                                                 break;
6178
6179                                         case FT_FLOAT:
6180                                                 if (hfinfo->display & BASE_UNIT_STRING) {
6181                                                         double d_value = fvalue_get_floating(&finfo->value);
6182                                                         g_snprintf(result+offset_r, size-offset_r,
6183                                                                         "%." G_STRINGIFY(FLT_DIG) "g%s", d_value,
6184                                                                         unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
6185                                                 } else {
6186                                                         g_snprintf(result+offset_r, size-offset_r,
6187                                                                         "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
6188                                                 }
6189                                                 offset_r = (int)strlen(result);
6190                                                 break;
6191
6192                                         case FT_DOUBLE:
6193                                                 if (hfinfo->display & BASE_UNIT_STRING) {
6194                                                         double d_value = fvalue_get_floating(&finfo->value);
6195                                                         g_snprintf(result+offset_r, size-offset_r,
6196                                                                         "%." G_STRINGIFY(DBL_DIG) "g%s", d_value,
6197                                                                         unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
6198                                                 } else {
6199                                                         g_snprintf(result+offset_r, size-offset_r,
6200                                                                         "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
6201                                                 }
6202                                                 offset_r = (int)strlen(result);
6203                                                 break;
6204
6205                                         case FT_STRING:
6206                                         case FT_STRINGZ:
6207                                         case FT_UINT_STRING:
6208                                         case FT_STRINGZPAD:
6209                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
6210                                                 str = hfinfo_format_text(hfinfo, bytes);
6211                                                 offset_r += protoo_strlcpy(result+offset_r,
6212                                                                 str, size-offset_r);
6213                                                 wmem_free(NULL, str);
6214                                                 break;
6215
6216                                         default:
6217                                                 /* First try ftype string representation */
6218                                                 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
6219                                                 if (!str) {
6220                                                         /* Default to show as bytes */
6221                                                         bytes = (guint8 *)fvalue_get(&finfo->value);
6222                                                         str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
6223                                                 }
6224                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
6225                                                 wmem_free(NULL, str);
6226                                                 break;
6227                                 }
6228                                 i++;
6229                         }
6230
6231                         switch (hfinfo->type) {
6232
6233                                 case FT_BOOLEAN:
6234                                 case FT_CHAR:
6235                                 case FT_UINT8:
6236                                 case FT_UINT16:
6237                                 case FT_UINT24:
6238                                 case FT_UINT32:
6239                                 case FT_UINT40:
6240                                 case FT_UINT48:
6241                                 case FT_UINT56:
6242                                 case FT_UINT64:
6243                                 case FT_FRAMENUM:
6244                                 case FT_INT8:
6245                                 case FT_INT16:
6246                                 case FT_INT24:
6247                                 case FT_INT32:
6248                                 case FT_INT40:
6249                                 case FT_INT48:
6250                                 case FT_INT56:
6251                                 case FT_INT64:
6252                                 case FT_OID:
6253                                 case FT_REL_OID:
6254                                 case FT_SYSTEM_ID:
6255                                         /* for these types, "expr" is filled in the loop above */
6256                                         break;
6257
6258                                 default:
6259                                         /* for all others, just copy "result" to "expr" */
6260                                         g_strlcpy(expr, result, size);
6261                                         break;
6262                         }
6263
6264                         if (!abbrev) {
6265                                 /* Store abbrev for return value */
6266                                 abbrev = hfinfo->abbrev;
6267                         }
6268
6269                         if (occurrence == 0) {
6270                                 /* Fetch next hfinfo with same name (abbrev) */
6271                                 hfinfo = hfinfo_same_name_get_prev(hfinfo);
6272                         } else {
6273                                 hfinfo = NULL;
6274                         }
6275                 }
6276         }
6277
6278         return abbrev ? abbrev : "";
6279 }
6280
6281
6282 /* Set text of proto_item after having already been created. */
6283 void
6284 proto_item_set_text(proto_item *pi, const char *format, ...)
6285 {
6286         field_info *fi = NULL;
6287         va_list     ap;
6288
6289         TRY_TO_FAKE_THIS_REPR_VOID(pi);
6290
6291         fi = PITEM_FINFO(pi);
6292         if (fi == NULL)
6293                 return;
6294
6295         if (fi->rep) {
6296                 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
6297                 fi->rep = NULL;
6298         }
6299
6300         va_start(ap, format);
6301         proto_tree_set_representation(pi, format, ap);
6302         va_end(ap);
6303 }
6304
6305 /* Append to text of proto_item after having already been created. */
6306 void
6307 proto_item_append_text(proto_item *pi, const char *format, ...)
6308 {
6309         field_info *fi = NULL;
6310         size_t      curlen;
6311         va_list     ap;
6312
6313         TRY_TO_FAKE_THIS_REPR_VOID(pi);
6314
6315         fi = PITEM_FINFO(pi);
6316         if (fi == NULL) {
6317                 return;
6318         }
6319
6320         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
6321                 /*
6322                  * If we don't already have a representation,
6323                  * generate the default representation.
6324                  */
6325                 if (fi->rep == NULL) {
6326                         ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6327                         proto_item_fill_label(fi, fi->rep->representation);
6328                 }
6329
6330                 curlen = strlen(fi->rep->representation);
6331                 if (ITEM_LABEL_LENGTH > curlen) {
6332                         va_start(ap, format);
6333                         g_vsnprintf(fi->rep->representation + curlen,
6334                                 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
6335                         va_end(ap);
6336                 }
6337         }
6338 }
6339
6340 /* Prepend to text of proto_item after having already been created. */
6341 void
6342 proto_item_prepend_text(proto_item *pi, const char *format, ...)
6343 {
6344         field_info *fi = NULL;
6345         char        representation[ITEM_LABEL_LENGTH];
6346         va_list     ap;
6347
6348         TRY_TO_FAKE_THIS_REPR_VOID(pi);
6349
6350         fi = PITEM_FINFO(pi);
6351         if (fi == NULL) {
6352                 return;
6353         }
6354
6355         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
6356                 /*
6357                  * If we don't already have a representation,
6358                  * generate the default representation.
6359                  */
6360                 if (fi->rep == NULL) {
6361                         ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6362                         proto_item_fill_label(fi, representation);
6363                 } else
6364                         g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
6365
6366                 va_start(ap, format);
6367                 g_vsnprintf(fi->rep->representation,
6368                         ITEM_LABEL_LENGTH, format, ap);
6369                 va_end(ap);
6370                 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
6371         }
6372 }
6373
6374 static void
6375 finfo_set_len(field_info *fi, const gint length)
6376 {
6377         gint length_remaining;
6378
6379         DISSECTOR_ASSERT(length >= 0);
6380         length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
6381         if (length > length_remaining)
6382                 fi->length = length_remaining;
6383         else
6384                 fi->length = length;
6385
6386         /*
6387          * You cannot just make the "len" field of a GByteArray
6388          * larger, if there's no data to back that length;
6389          * you can only make it smaller.
6390          */
6391         if (fi->value.ftype->ftype == FT_BYTES && fi->length <= (gint)fi->value.value.bytes->len)
6392                 fi->value.value.bytes->len = fi->length;
6393 }
6394
6395 void
6396 proto_item_set_len(proto_item *pi, const gint length)
6397 {
6398         field_info *fi;
6399
6400         TRY_TO_FAKE_THIS_REPR_VOID(pi);
6401
6402         fi = PITEM_FINFO(pi);
6403         if (fi == NULL)
6404                 return;
6405
6406         finfo_set_len(fi, length);
6407 }
6408
6409 /*
6410  * Sets the length of the item based on its start and on the specified
6411  * offset, which is the offset past the end of the item; as the start
6412  * in the item is relative to the beginning of the data source tvbuff,
6413  * we need to pass in a tvbuff - the end offset is relative to the beginning
6414  * of that tvbuff.
6415  */
6416 void
6417 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
6418 {
6419         field_info *fi;
6420         gint length;
6421
6422         TRY_TO_FAKE_THIS_REPR_VOID(pi);
6423
6424         fi = PITEM_FINFO(pi);
6425         if (fi == NULL)
6426                 return;
6427
6428         end += tvb_raw_offset(tvb);
6429         DISSECTOR_ASSERT(end >= fi->start);
6430         length = end - fi->start;
6431
6432         finfo_set_len(fi, length);
6433 }
6434
6435 int
6436 proto_item_get_len(const proto_item *pi)
6437 {
6438         field_info *fi;
6439
6440         if (!pi)
6441                 return -1;
6442         fi = PITEM_FINFO(pi);
6443         return fi ? fi->length : -1;
6444 }
6445
6446 proto_tree *
6447 proto_tree_create_root(packet_info *pinfo)
6448 {
6449         proto_node *pnode;
6450
6451         /* Initialize the proto_node */
6452         pnode = g_slice_new(proto_tree);
6453         PROTO_NODE_INIT(pnode);
6454         pnode->parent = NULL;
6455         PNODE_FINFO(pnode) = NULL;
6456         pnode->tree_data = g_slice_new(tree_data_t);
6457
6458         /* Make sure we can access pinfo everywhere */
6459         pnode->tree_data->pinfo = pinfo;
6460
6461         /* Don't initialize the tree_data_t. Wait until we know we need it */
6462         pnode->tree_data->interesting_hfids = NULL;
6463
6464         /* Set the default to FALSE so it's easier to
6465          * find errors; if we expect to see the protocol tree
6466          * but for some reason the default 'visible' is not
6467          * changed, then we'll find out very quickly. */
6468         pnode->tree_data->visible = FALSE;
6469
6470         /* Make sure that we fake protocols (if possible) */
6471         pnode->tree_data->fake_protocols = TRUE;
6472
6473         /* Keep track of the number of children */
6474         pnode->tree_data->count = 0;
6475
6476         return (proto_tree *)pnode;
6477 }
6478
6479
6480 /* "prime" a proto_tree with a single hfid that a dfilter
6481  * is interested in. */
6482 void
6483 proto_tree_prime_with_hfid(proto_tree *tree _U_, const gint hfid)
6484 {
6485         header_field_info *hfinfo;
6486
6487         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
6488         /* this field is referenced by a filter so increase the refcount.
6489            also increase the refcount for the parent, i.e the protocol.
6490         */
6491         hfinfo->ref_type = HF_REF_TYPE_DIRECT;
6492         /* only increase the refcount if there is a parent.
6493            if this is a protocol and not a field then parent will be -1
6494            and there is no parent to add any refcounting for.
6495         */
6496         if (hfinfo->parent != -1) {
6497                 header_field_info *parent_hfinfo;
6498                 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
6499
6500                 /* Mark parent as indirectly referenced unless it is already directly
6501                  * referenced, i.e. the user has specified the parent in a filter.
6502                  */
6503                 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
6504                         parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
6505         }
6506 }
6507
6508 proto_tree *
6509 proto_item_add_subtree(proto_item *pi,  const gint idx) {
6510         field_info *fi;
6511
6512         if (!pi)
6513                 return NULL;
6514
6515         DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
6516
6517         fi = PITEM_FINFO(pi);
6518         if (!fi)
6519                 return (proto_tree *)pi;
6520
6521         fi->tree_type = idx;
6522
6523         return (proto_tree *)pi;
6524 }
6525
6526 proto_tree *
6527 proto_item_get_subtree(proto_item *pi) {
6528         field_info *fi;
6529
6530         if (!pi)
6531                 return NULL;
6532         fi = PITEM_FINFO(pi);
6533         if ( (!fi) || (fi->tree_type == -1) )
6534                 return NULL;
6535         return (proto_tree *)pi;
6536 }
6537
6538 proto_item *
6539 proto_item_get_parent(const proto_item *ti) {
6540         if (!ti)
6541                 return NULL;
6542         return ti->parent;
6543 }
6544
6545 proto_item *
6546 proto_item_get_parent_nth(proto_item *ti, int gen) {
6547         if (!ti)
6548                 return NULL;
6549         while (gen--) {
6550                 ti = ti->parent;
6551                 if (!ti)
6552                         return NULL;
6553         }
6554         return ti;
6555 }
6556
6557
6558 proto_item *
6559 proto_tree_get_parent(proto_tree *tree) {
6560         if (!tree)
6561                 return NULL;
6562         return (proto_item *)tree;
6563 }
6564
6565 proto_tree *
6566 proto_tree_get_parent_tree(proto_tree *tree) {
6567         if (!tree)
6568                 return NULL;
6569
6570         /* we're the root tree, there's no parent
6571            return ourselves so the caller has at least a tree to attach to */
6572         if (!tree->parent)
6573                 return tree;
6574
6575         return (proto_tree *)tree->parent;
6576 }
6577
6578 proto_tree *
6579 proto_tree_get_root(proto_tree *tree) {
6580         if (!tree)
6581                 return NULL;
6582         while (tree->parent) {
6583                 tree = tree->parent;
6584         }
6585         return tree;
6586 }
6587
6588 void
6589 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
6590                      proto_item *item_to_move)
6591 {
6592
6593         /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
6594          * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
6595          */
6596         /* This function doesn't generate any values. It only reorganizes the prococol tree
6597          * so we can bail out immediately if it isn't visible. */
6598         if (!tree || !PTREE_DATA(tree)->visible)
6599                 return;
6600
6601         DISSECTOR_ASSERT(item_to_move->parent == tree);
6602         DISSECTOR_ASSERT(fixed_item->parent == tree);
6603
6604         /*** cut item_to_move out ***/
6605
6606         /* is item_to_move the first? */
6607         if (tree->first_child == item_to_move) {
6608                 /* simply change first child to next */
6609                 tree->first_child = item_to_move->next;
6610
6611                 DISSECTOR_ASSERT(tree->last_child != item_to_move);
6612         } else {
6613                 proto_item *curr_item;
6614                 /* find previous and change it's next */
6615                 for (curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
6616                         if (curr_item->next == item_to_move) {
6617                                 break;
6618                         }
6619                 }
6620
6621                 DISSECTOR_ASSERT(curr_item);
6622
6623                 curr_item->next = item_to_move->next;
6624
6625                 /* fix last_child if required */
6626                 if (tree->last_child == item_to_move) {
6627                         tree->last_child = curr_item;
6628                 }
6629         }
6630
6631         /*** insert to_move after fixed ***/
6632         item_to_move->next = fixed_item->next;
6633         fixed_item->next = item_to_move;
6634         if (tree->last_child == fixed_item) {
6635                 tree->last_child = item_to_move;
6636         }
6637 }
6638
6639 void
6640 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
6641                         const gint length)
6642 {
6643         field_info *fi;
6644
6645         if (tree == NULL)
6646                 return;
6647
6648         fi = PTREE_FINFO(tree);
6649         if (fi == NULL)
6650                 return;
6651
6652         start += tvb_raw_offset(tvb);
6653         DISSECTOR_ASSERT(start >= 0);
6654         DISSECTOR_ASSERT(length >= 0);
6655
6656         fi->appendix_start = start;
6657         fi->appendix_length = length;
6658 }
6659
6660 static void
6661 check_valid_filter_name_or_fail(const char *filter_name)
6662 {
6663         gboolean found_invalid = proto_check_field_name(filter_name);
6664
6665         /* Additionally forbid upper case characters. */
6666         if (!found_invalid) {
6667                 for (guint i = 0; filter_name[i]; i++) {
6668                         if (g_ascii_isupper(filter_name[i])) {
6669                                 found_invalid = TRUE;
6670                                 break;
6671                         }
6672                 }
6673         }
6674
6675         if (found_invalid) {
6676                 g_error("Protocol filter name \"%s\" has one or more invalid characters."
6677                         " Allowed are lower characters, digits, '-', '_' and non-repeating '.'."
6678                         " This might be caused by an inappropriate plugin or a development error.", filter_name);
6679         }
6680 }
6681
6682 int
6683 proto_register_protocol(const char *name, const char *short_name,
6684                         const char *filter_name)
6685 {
6686         protocol_t *protocol;
6687         header_field_info *hfinfo;
6688
6689         /*
6690          * Make sure there's not already a protocol with any of those
6691          * names.  Crash if there is, as that's an error in the code
6692          * or an inappropriate plugin.
6693          * This situation has to be fixed to not register more than one
6694          * protocol with the same name.
6695          */
6696
6697         if (g_hash_table_lookup(proto_names, name)) {
6698                 /* g_error will terminate the program */
6699                 g_error("Duplicate protocol name \"%s\"!"
6700                         " This might be caused by an inappropriate plugin or a development error.", name);
6701         }
6702
6703         if (g_hash_table_lookup(proto_short_names, short_name)) {
6704                 g_error("Duplicate protocol short_name \"%s\"!"
6705                         " This might be caused by an inappropriate plugin or a development error.", short_name);
6706         }
6707
6708         check_valid_filter_name_or_fail(filter_name);
6709
6710         if (g_hash_table_lookup(proto_filter_names, filter_name)) {
6711                 g_error("Duplicate protocol filter_name \"%s\"!"
6712                         " This might be caused by an inappropriate plugin or a development error.", filter_name);
6713         }
6714
6715         /*
6716          * Add this protocol to the list of known protocols;
6717          * the list is sorted by protocol short name.
6718          */
6719         protocol = g_new(protocol_t, 1);
6720         protocol->name = name;
6721         protocol->short_name = short_name;
6722         protocol->filter_name = filter_name;
6723         protocol->fields = NULL; /* Delegate until actually needed */
6724         protocol->is_enabled = TRUE; /* protocol is enabled by default */
6725         protocol->enabled_by_default = TRUE; /* see previous comment */
6726         protocol->can_toggle = TRUE;
6727         protocol->parent_proto_id = -1;
6728         protocol->heur_list = NULL;
6729
6730         /* List will be sorted later by name, when all protocols completed registering */
6731         protocols = g_list_prepend(protocols, protocol);
6732         g_hash_table_insert(proto_names, (gpointer)name, protocol);
6733         g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
6734         g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
6735
6736         /* Here we allocate a new header_field_info struct */
6737         hfinfo = g_slice_new(header_field_info);
6738         hfinfo->name = name;
6739         hfinfo->abbrev = filter_name;
6740         hfinfo->type = FT_PROTOCOL;
6741         hfinfo->display = BASE_NONE;
6742         hfinfo->strings = protocol;
6743         hfinfo->bitmask = 0;
6744         hfinfo->ref_type = HF_REF_TYPE_NONE;
6745         hfinfo->blurb = NULL;
6746         hfinfo->parent = -1; /* This field differentiates protos and fields */
6747
6748         protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
6749         return protocol->proto_id;
6750 }
6751
6752 int
6753 proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
6754 {
6755         protocol_t *protocol;
6756         header_field_info *hfinfo;
6757
6758         /*
6759          * Helper protocols don't need the strict rules as a "regular" protocol
6760          * Just register it in a list and make a hf_ field from it
6761          */
6762         if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
6763                 g_error("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name);
6764         }
6765
6766         if (parent_proto < 0) {
6767                 g_error("Must have a valid parent protocol for helper protocol \"%s\"!"
6768                         " This might be caused by an inappropriate plugin or a development error.", name);
6769         }
6770
6771         check_valid_filter_name_or_fail(filter_name);
6772
6773         /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
6774         protocol = g_new(protocol_t, 1);
6775         protocol->name = name;
6776         protocol->short_name = short_name;
6777         protocol->filter_name = filter_name;
6778         protocol->fields = NULL; /* Delegate until actually needed */
6779
6780         /* Enabling and toggling is really determined by parent protocol,
6781            but provide default values here */
6782         protocol->is_enabled = TRUE;
6783         protocol->enabled_by_default = TRUE;
6784         protocol->can_toggle = TRUE;
6785
6786         protocol->parent_proto_id = parent_proto;
6787         protocol->heur_list = NULL;
6788
6789         /* List will be sorted later by name, when all protocols completed registering */
6790         pino_protocols = g_list_prepend(pino_protocols, protocol);
6791
6792         /* Here we allocate a new header_field_info struct */
6793         hfinfo = g_slice_new(header_field_info);
6794         hfinfo->name = name;
6795         hfinfo->abbrev = filter_name;
6796         hfinfo->type = field_type;
6797         hfinfo->display = BASE_NONE;
6798         if (field_type == FT_BYTES) {
6799                 hfinfo->display |= (BASE_NO_DISPLAY_VALUE|BASE_PROTOCOL_INFO);
6800         }
6801         hfinfo->strings = protocol;
6802         hfinfo->bitmask = 0;
6803         hfinfo->ref_type = HF_REF_TYPE_NONE;
6804         hfinfo->blurb = NULL;
6805         hfinfo->parent = -1; /* This field differentiates protos and fields */
6806
6807         protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
6808         return protocol->proto_id;
6809 }
6810
6811 gboolean
6812 proto_deregister_protocol(const char *short_name)
6813 {
6814         protocol_t *protocol;
6815         header_field_info *hfinfo;
6816         int proto_id;
6817         guint i;
6818
6819         proto_id = proto_get_id_by_short_name(short_name);
6820         protocol = find_protocol_by_id(proto_id);
6821         if (protocol == NULL)
6822                 return FALSE;
6823
6824         g_hash_table_remove(proto_names, protocol->name);
6825         g_hash_table_remove(proto_short_names, (gpointer)short_name);
6826         g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
6827
6828         if (protocol->fields) {
6829                 for (i = 0; i < protocol->fields->len; i++) {
6830                         hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
6831                         hfinfo_remove_from_gpa_name_map(hfinfo);
6832                         expert_deregister_expertinfo(hfinfo->abbrev);
6833                         g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
6834                 }
6835                 g_ptr_array_free(protocol->fields, TRUE);
6836                 protocol->fields = NULL;
6837         }
6838
6839         /* Remove this protocol from the list of known protocols */
6840         protocols = g_list_remove(protocols, protocol);
6841
6842         g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
6843         g_hash_table_steal(gpa_name_map, protocol->filter_name);
6844
6845         g_free(last_field_name);
6846         last_field_name = NULL;
6847
6848         return TRUE;
6849 }
6850
6851 void
6852 proto_register_alias(const int proto_id, const char *alias_name)
6853 {
6854         protocol_t *protocol;
6855
6856         protocol = find_protocol_by_id(proto_id);
6857         if (alias_name && protocol) {
6858                 g_hash_table_insert(gpa_protocol_aliases, (gpointer) alias_name, (gpointer)protocol->filter_name);
6859         }
6860 }
6861
6862 /*
6863  * Routines to use to iterate over the protocols.
6864  * The argument passed to the iterator routines is an opaque cookie to
6865  * their callers; it's the GList pointer for the current element in
6866  * the list.
6867  * The ID of the protocol is returned, or -1 if there is no protocol.
6868  */
6869 int
6870 proto_get_first_protocol(void **cookie)
6871 {
6872         protocol_t *protocol;
6873
6874         if (protocols == NULL)
6875                 return -1;
6876         *cookie = protocols;
6877         protocol = (protocol_t *)protocols->data;
6878         return protocol->proto_id;
6879 }
6880
6881 int
6882 proto_get_data_protocol(void *cookie)
6883 {
6884         GList *list_item = (GList *)cookie;
6885
6886         protocol_t *protocol = (protocol_t *)list_item->data;
6887         return protocol->proto_id;
6888 }
6889
6890 int
6891 proto_get_next_protocol(void **cookie)
6892 {
6893         GList      *list_item = (GList *)*cookie;
6894         protocol_t *protocol;
6895
6896         list_item = g_list_next(list_item);
6897         if (list_item == NULL)
6898                 return -1;
6899         *cookie = list_item;
6900         protocol = (protocol_t *)list_item->data;
6901         return protocol->proto_id;
6902 }
6903
6904 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
6905         assume that the cookie stored by
6906         proto_get_(first|next)_protocol_field() will never have a
6907         value of NULL. So, to preserve this semantic, the cookie value
6908         below is adjusted so that the cookie value stored is 1 + the
6909         current (zero-based) array index.
6910 */
6911 header_field_info *
6912 proto_get_first_protocol_field(const int proto_id, void **cookie)
6913 {
6914         protocol_t *protocol = find_protocol_by_id(proto_id);
6915
6916         if ((protocol == NULL) || (protocol->fields == NULL) || (protocol->fields->len == 0))
6917                 return NULL;
6918
6919         *cookie = GUINT_TO_POINTER(0 + 1);
6920         return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
6921 }
6922
6923 header_field_info *
6924 proto_get_next_protocol_field(const int proto_id, void **cookie)
6925 {
6926         protocol_t *protocol = find_protocol_by_id(proto_id);
6927         guint       i        = GPOINTER_TO_UINT(*cookie) - 1;
6928
6929         i++;
6930
6931         if ((protocol->fields == NULL) || (i >= protocol->fields->len))
6932                 return NULL;
6933
6934         *cookie = GUINT_TO_POINTER(i + 1);
6935         return (header_field_info *)g_ptr_array_index(protocol->fields, i);
6936 }
6937
6938 protocol_t *
6939 find_protocol_by_id(const int proto_id)
6940 {
6941         header_field_info *hfinfo;
6942
6943         if (proto_id < 0)
6944                 return NULL;
6945
6946         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
6947         if (hfinfo->type != FT_PROTOCOL) {
6948                 DISSECTOR_ASSERT(hfinfo->display & BASE_PROTOCOL_INFO);
6949         }
6950         return (protocol_t *)hfinfo->strings;
6951 }
6952
6953 int
6954 proto_get_id(const protocol_t *protocol)
6955 {
6956         return protocol->proto_id;
6957 }
6958
6959 gboolean
6960 proto_name_already_registered(const gchar *name)
6961 {
6962         DISSECTOR_ASSERT_HINT(name, "No name present");
6963
6964         if (g_hash_table_lookup(proto_names, name) != NULL)
6965                 return TRUE;
6966         return FALSE;
6967 }
6968
6969 int
6970 proto_get_id_by_filter_name(const gchar *filter_name)
6971 {
6972         const protocol_t *protocol = NULL;
6973
6974         DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
6975
6976         protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
6977
6978         if (protocol == NULL)
6979                 return -1;
6980         return protocol->proto_id;
6981 }
6982
6983 int
6984 proto_get_id_by_short_name(const gchar *short_name)
6985 {
6986         const protocol_t *protocol = NULL;
6987
6988         DISSECTOR_ASSERT_HINT(short_name, "No short name present");
6989
6990         protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
6991
6992         if (protocol == NULL)
6993                 return -1;
6994         return protocol->proto_id;
6995 }
6996
6997 const char *
6998 proto_get_protocol_name(const int proto_id)
6999 {
7000         protocol_t *protocol;
7001
7002         protocol = find_protocol_by_id(proto_id);
7003
7004         if (protocol == NULL)
7005                 return NULL;
7006         return protocol->name;
7007 }
7008
7009 const char *
7010 proto_get_protocol_short_name(const protocol_t *protocol)
7011 {
7012         if (protocol == NULL)
7013                 return "(none)";
7014         return protocol->short_name;
7015 }
7016
7017 const char *
7018 proto_get_protocol_long_name(const protocol_t *protocol)
7019 {
7020         if (protocol == NULL)
7021                 return "(none)";
7022         return protocol->name;
7023 }
7024
7025 const char *
7026 proto_get_protocol_filter_name(const int proto_id)
7027 {
7028         protocol_t *protocol;
7029
7030         protocol = find_protocol_by_id(proto_id);
7031         if (protocol == NULL)
7032                 return "(none)";
7033         return protocol->filter_name;
7034 }
7035
7036 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
7037 {
7038         heur_dtbl_entry_t* heuristic_dissector;
7039
7040         if (protocol == NULL)
7041                 return;
7042
7043         heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
7044         if (heuristic_dissector != NULL)
7045         {
7046                 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
7047         }
7048 }
7049
7050 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
7051 {
7052         if (protocol == NULL)
7053                 return;
7054
7055         g_list_foreach(protocol->heur_list, func, user_data);
7056 }
7057
7058 void
7059 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
7060                           gboolean *is_tcp, gboolean *is_udp,
7061                           gboolean *is_sctp, gboolean *is_ssl,
7062                           gboolean *is_rtp,
7063                           gboolean *is_lte_rlc)
7064 {
7065         wmem_list_frame_t *protos = wmem_list_head(layers);
7066         int         proto_id;
7067         const char *proto_name;
7068
7069         /* Walk the list of a available protocols in the packet and
7070            find "major" ones. */
7071         /* It might make more sense to assemble and return a bitfield. */
7072         while (protos != NULL)
7073         {
7074                 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
7075                 proto_name = proto_get_protocol_filter_name(proto_id);
7076
7077                 if (is_ip && ((!strcmp(proto_name, "ip")) ||
7078                               (!strcmp(proto_name, "ipv6")))) {
7079                         *is_ip = TRUE;
7080                 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
7081                         *is_tcp = TRUE;
7082                 } else if (is_udp && !strcmp(proto_name, "udp")) {
7083                         *is_udp = TRUE;
7084                 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
7085                         *is_sctp = TRUE;
7086                 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
7087                         *is_ssl = TRUE;
7088                 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
7089                         *is_rtp = TRUE;
7090                 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
7091                         *is_lte_rlc = TRUE;
7092                 }
7093
7094                 protos = wmem_list_frame_next(protos);
7095         }
7096 }
7097
7098 gboolean
7099 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
7100 {
7101         wmem_list_frame_t *protos = wmem_list_head(layers);
7102         int         proto_id;
7103         const char *name;
7104
7105         /* Walk the list of a available protocols in the packet and
7106            find "major" ones. */
7107         /* It might make more sense to assemble and return a bitfield. */
7108         while (protos != NULL)
7109         {
7110                 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
7111                 name = proto_get_protocol_filter_name(proto_id);
7112
7113                 if (!strcmp(name, proto_name))
7114                 {
7115                         return TRUE;
7116                 }
7117
7118                 protos = wmem_list_frame_next(protos);
7119         }
7120
7121         return FALSE;
7122 }
7123
7124 gboolean
7125 proto_is_pino(const protocol_t *protocol)
7126 {
7127         return (protocol->parent_proto_id != -1);
7128 }
7129
7130 gboolean
7131 proto_is_protocol_enabled(const protocol_t *protocol)
7132 {
7133         if (protocol == NULL)
7134                 return FALSE;
7135
7136         //parent protocol determines enable/disable for helper dissectors
7137         if (proto_is_pino(protocol))
7138                 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
7139
7140         return protocol->is_enabled;
7141 }
7142
7143 gboolean
7144 proto_is_protocol_enabled_by_default(const protocol_t *protocol)
7145 {
7146         //parent protocol determines enable/disable for helper dissectors
7147         if (proto_is_pino(protocol))
7148                 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
7149
7150         return protocol->enabled_by_default;
7151 }
7152
7153 gboolean
7154 proto_can_toggle_protocol(const int proto_id)
7155 {
7156         protocol_t *protocol;
7157
7158         protocol = find_protocol_by_id(proto_id);
7159         //parent protocol determines toggling for helper dissectors
7160         if (proto_is_pino(protocol))
7161                 return proto_can_toggle_protocol(protocol->parent_proto_id);
7162
7163         return protocol->can_toggle;
7164 }
7165
7166 void
7167 proto_disable_by_default(const int proto_id)
7168 {
7169         protocol_t *protocol;
7170
7171         protocol = find_protocol_by_id(proto_id);
7172         DISSECTOR_ASSERT(protocol->can_toggle);
7173         DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
7174         protocol->is_enabled = FALSE;
7175         protocol->enabled_by_default = FALSE;
7176 }
7177
7178 void
7179 proto_set_decoding(const int proto_id, const gboolean enabled)
7180 {
7181         protocol_t *protocol;
7182
7183         protocol = find_protocol_by_id(proto_id);
7184         DISSECTOR_ASSERT(protocol->can_toggle);
7185         DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
7186         protocol->is_enabled = enabled;
7187 }
7188
7189 void
7190 proto_reenable_all(void)
7191 {
7192         protocol_t *protocol;
7193         GList      *list_item = protocols;
7194
7195         if (protocols == NULL)
7196                 return;
7197
7198         while (list_item) {
7199                 protocol = (protocol_t *)list_item->data;
7200                 if (protocol->can_toggle && protocol->enabled_by_default)
7201                         protocol->is_enabled = TRUE;
7202                 list_item = g_list_next(list_item);
7203         }
7204 }
7205
7206 void
7207 proto_set_cant_toggle(const int proto_id)
7208 {
7209         protocol_t *protocol;
7210
7211         protocol = find_protocol_by_id(proto_id);
7212         protocol->can_toggle = FALSE;
7213 }
7214
7215 static int
7216 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
7217 {
7218         if (proto != NULL) {
7219                 g_ptr_array_add(proto->fields, hfi);
7220         }
7221
7222         return proto_register_field_init(hfi, parent);
7223 }
7224
7225 /* for use with static arrays only, since we don't allocate our own copies
7226 of the header_field_info struct contained within the hf_register_info struct */
7227 void
7228 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
7229 {
7230         hf_register_info *ptr = hf;
7231         protocol_t       *proto;
7232         int               i;
7233
7234         proto = find_protocol_by_id(parent);
7235
7236         if (proto->fields == NULL) {
7237                 proto->fields = g_ptr_array_sized_new(num_records);
7238         }
7239
7240         for (i = 0; i < num_records; i++, ptr++) {
7241                 /*
7242                  * Make sure we haven't registered this yet.
7243                  * Most fields have variables associated with them
7244                  * that are initialized to -1; some have array elements,
7245                  * or possibly uninitialized variables, so we also allow
7246                  * 0 (which is unlikely to be the field ID we get back
7247                  * from "proto_register_field_init()").
7248                  */
7249                 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
7250                         fprintf(stderr,
7251                                 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
7252                                 ptr->hfinfo.abbrev);
7253                         return;
7254                 }
7255
7256                 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
7257         }
7258 }
7259
7260 void
7261 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
7262 {
7263         int               i;
7264         protocol_t       *proto;
7265
7266         proto = find_protocol_by_id(parent);
7267
7268         if (proto->fields == NULL) {
7269                 proto->fields = g_ptr_array_sized_new(num_records);
7270         }
7271
7272         for (i = 0; i < num_records; i++) {
7273                 /*
7274                  * Make sure we haven't registered this yet.
7275                  */
7276                 if (hfi[i].id != -1) {
7277                         fprintf(stderr,
7278                                 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7279                                 hfi[i].abbrev);
7280                         return;
7281                 }
7282
7283                 proto_register_field_common(proto, &hfi[i], parent);
7284         }
7285 }
7286
7287 void
7288 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
7289 {
7290         int               i;
7291         protocol_t       *proto;
7292
7293         proto = find_protocol_by_id(parent);
7294
7295         if (proto->fields == NULL) {
7296                 proto->fields = g_ptr_array_sized_new(num_records);
7297         }
7298
7299
7300         for (i = 0; i < num_records; i++) {
7301                 /*
7302                  * Make sure we haven't registered this yet.
7303                  */
7304                 if (hfi[i]->id != -1) {
7305                         fprintf(stderr,
7306                                 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7307                                 hfi[i]->abbrev);
7308                         return;
7309                 }
7310
7311                 proto_register_field_common(proto, hfi[i], parent);
7312         }
7313 }
7314
7315 /* deregister already registered fields */
7316 void
7317 proto_deregister_field (const int parent, gint hf_id)
7318 {
7319         header_field_info *hfi;
7320         protocol_t       *proto;
7321         guint             i;
7322
7323         g_free(last_field_name);
7324         last_field_name = NULL;
7325
7326         if (hf_id == -1 || hf_id == 0)
7327                 return;
7328
7329         proto = find_protocol_by_id (parent);
7330         if (!proto || proto->fields == NULL) {
7331                 return;
7332         }
7333
7334         for (i = 0; i < proto->fields->len; i++) {
7335                 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
7336                 if (hfi->id == hf_id) {
7337                         /* Found the hf_id in this protocol */
7338                         g_hash_table_steal(gpa_name_map, hfi->abbrev);
7339                         g_ptr_array_remove_index_fast(proto->fields, i);
7340                         g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
7341                         return;
7342                 }
7343         }
7344 }
7345
7346 void
7347 proto_add_deregistered_data (void *data)
7348 {
7349         g_ptr_array_add(deregistered_data, data);
7350 }
7351
7352 static void
7353 free_deregistered_field (gpointer data, gpointer user_data _U_)
7354 {
7355         header_field_info *hfi = (header_field_info *) data;
7356         gint hf_id = hfi->id;
7357
7358         g_free((char *)hfi->name);
7359         g_free((char *)hfi->abbrev);
7360         g_free((char *)hfi->blurb);
7361
7362         if (hfi->strings) {
7363                 switch (hfi->type) {
7364                         case FT_FRAMENUM:
7365                                 /* This is just an integer represented as a pointer */
7366                                 break;
7367                         case FT_PROTOCOL: {
7368                                 protocol_t *protocol = (protocol_t *)hfi->strings;
7369                                 g_free((gchar *)protocol->short_name);
7370                                 break;
7371                         }
7372                         case FT_BOOLEAN: {
7373                                 true_false_string *tf = (true_false_string *)hfi->strings;
7374                                 g_free ((gchar *)tf->true_string);
7375                                 g_free ((gchar *)tf->false_string);
7376                                 break;
7377                         }
7378                         case FT_UINT40:
7379                         case FT_INT40:
7380                         case FT_UINT48:
7381                         case FT_INT48:
7382                         case FT_UINT56:
7383                         case FT_INT56:
7384                         case FT_UINT64:
7385                         case FT_INT64: {
7386                                 /*
7387                                  * XXX - if it's BASE_RANGE_STRING, or
7388                                  * BASE_EXT_STRING, should we free it?
7389                                  */
7390                                 if (hfi->display & BASE_UNIT_STRING) {
7391                                         unit_name_string *unit = (unit_name_string*)hfi->strings;
7392                                         g_free ((gchar *)unit->singular);
7393                                         g_free ((gchar *)unit->plural);
7394                                 } else {
7395                                         val64_string *vs64 = (val64_string *)hfi->strings;
7396                                         while (vs64->strptr) {
7397                                                 g_free((gchar *)vs64->strptr);
7398                                                 vs64++;
7399                                         }
7400                                 }
7401                                 break;
7402                         }
7403                         case FT_CHAR:
7404                         case FT_UINT8:
7405                         case FT_INT8:
7406                         case FT_UINT16:
7407                         case FT_INT16:
7408                         case FT_UINT24:
7409                         case FT_INT24:
7410                         case FT_UINT32:
7411                         case FT_INT32:
7412                         case FT_FLOAT:
7413                         case FT_DOUBLE: {
7414                                 /*
7415                                  * XXX - if it's BASE_RANGE_STRING, or
7416                                  * BASE_EXT_STRING, should we free it?
7417                                  */
7418                                 if (hfi->display & BASE_UNIT_STRING) {
7419                                         unit_name_string *unit = (unit_name_string*)hfi->strings;
7420                                         g_free ((gchar *)unit->singular);
7421                                         g_free ((gchar *)unit->plural);
7422                                 } else {
7423                                         value_string *vs = (value_string *)hfi->strings;
7424                                         while (vs->strptr) {
7425                                                 g_free((gchar *)vs->strptr);
7426                                                 vs++;
7427                                         }
7428                                 }
7429                                 break;
7430                         default:
7431                                 break;
7432                         }
7433                 }
7434                 if (hfi->type != FT_FRAMENUM) {
7435                         g_free((void *)hfi->strings);
7436                 }
7437         }
7438
7439         if (hfi->parent == -1)
7440                 g_slice_free(header_field_info, hfi);
7441
7442         gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
7443 }
7444
7445 static void
7446 free_deregistered_data (gpointer data, gpointer user_data _U_)
7447 {
7448         g_free (data);
7449 }
7450
7451 /* free deregistered fields and data */
7452 void
7453 proto_free_deregistered_fields (void)
7454 {
7455         expert_free_deregistered_expertinfos();
7456
7457         g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
7458         g_ptr_array_free(deregistered_fields, TRUE);
7459         deregistered_fields = g_ptr_array_new();
7460
7461         g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
7462         g_ptr_array_free(deregistered_data, TRUE);
7463         deregistered_data = g_ptr_array_new();
7464 }
7465
7466 /* chars allowed in field abbrev: alphanumerics, '-', "_", and ".". */
7467 static
7468 const guint8 fld_abbrev_chars[256] = {
7469         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
7470         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
7471         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.'      */
7472         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9'       */
7473         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O'       */
7474         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
7475         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o'       */
7476         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z'       */
7477         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
7478         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
7479         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
7480         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
7481         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
7482         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
7483         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
7484         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
7485 };
7486
7487 static const value_string hf_display[] = {
7488         { BASE_NONE,                      "BASE_NONE"                      },
7489         { BASE_DEC,                       "BASE_DEC"                       },
7490         { BASE_HEX,                       "BASE_HEX"                       },
7491         { BASE_OCT,                       "BASE_OCT"                       },
7492         { BASE_DEC_HEX,                   "BASE_DEC_HEX"                   },
7493         { BASE_HEX_DEC,                   "BASE_HEX_DEC"                   },
7494         { BASE_CUSTOM,                    "BASE_CUSTOM"                    },
7495         { BASE_NONE|BASE_RANGE_STRING,    "BASE_NONE|BASE_RANGE_STRING"    },
7496         { BASE_DEC|BASE_RANGE_STRING,     "BASE_DEC|BASE_RANGE_STRING"     },
7497         { BASE_HEX|BASE_RANGE_STRING,     "BASE_HEX|BASE_RANGE_STRING"     },
7498         { BASE_OCT|BASE_RANGE_STRING,     "BASE_OCT|BASE_RANGE_STRING"     },
7499         { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
7500         { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
7501         { BASE_CUSTOM|BASE_RANGE_STRING,  "BASE_CUSTOM|BASE_RANGE_STRING"  },
7502         { BASE_NONE|BASE_VAL64_STRING,    "BASE_NONE|BASE_VAL64_STRING"    },
7503         { BASE_DEC|BASE_VAL64_STRING,     "BASE_DEC|BASE_VAL64_STRING"     },
7504         { BASE_HEX|BASE_VAL64_STRING,     "BASE_HEX|BASE_VAL64_STRING"     },
7505         { BASE_OCT|BASE_VAL64_STRING,     "BASE_OCT|BASE_VAL64_STRING"     },
7506         { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
7507         { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
7508         { BASE_CUSTOM|BASE_VAL64_STRING,  "BASE_CUSTOM|BASE_VAL64_STRING"  },
7509         /* Alias: BASE_NONE { BASE_FLOAT,                       "BASE_FLOAT" }, */
7510         /* Alias: BASE_NONE { STR_ASCII,                          "STR_ASCII" }, */
7511         { STR_UNICODE,                    "STR_UNICODE" },
7512         { ABSOLUTE_TIME_LOCAL,            "ABSOLUTE_TIME_LOCAL"            },
7513         { ABSOLUTE_TIME_UTC,              "ABSOLUTE_TIME_UTC"              },
7514         { ABSOLUTE_TIME_DOY_UTC,          "ABSOLUTE_TIME_DOY_UTC"          },
7515         { BASE_PT_UDP,                    "BASE_PT_UDP"                    },
7516         { BASE_PT_TCP,                    "BASE_PT_TCP"                    },
7517         { BASE_PT_DCCP,                   "BASE_PT_DCCP"                   },
7518         { BASE_PT_SCTP,                   "BASE_PT_SCTP"                   },
7519         { BASE_OUI,                       "BASE_OUI"                       },
7520         { 0,                              NULL } };
7521
7522 const char* proto_field_display_to_string(int field_display)
7523 {
7524         return val_to_str_const(field_display, hf_display, "Unknown");
7525 }
7526
7527 static inline port_type
7528 display_to_port_type(field_display_e e)
7529 {
7530         switch (e) {
7531         case BASE_PT_UDP:
7532                 return PT_UDP;
7533         case BASE_PT_TCP:
7534                 return PT_TCP;
7535         case BASE_PT_DCCP:
7536                 return PT_DCCP;
7537         case BASE_PT_SCTP:
7538                 return PT_SCTP;
7539         default:
7540                 break;
7541         }
7542         return PT_NONE;
7543 }
7544
7545 /* temporary function containing assert part for easier profiling */
7546 static void
7547 tmp_fld_check_assert(header_field_info *hfinfo)
7548 {
7549         gchar* tmp_str;
7550
7551         /* The field must have a name (with length > 0) */
7552         if (!hfinfo->name || !hfinfo->name[0]) {
7553                 if (hfinfo->abbrev)
7554                         /* Try to identify the field */
7555                         g_error("Field (abbrev='%s') does not have a name\n",
7556                                 hfinfo->abbrev);
7557                 else
7558                         /* Hum, no luck */
7559                         g_error("Field does not have a name (nor an abbreviation)\n");
7560         }
7561
7562         /* fields with an empty string for an abbreviation aren't filterable */
7563         if (!hfinfo->abbrev || !hfinfo->abbrev[0])
7564                 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
7565
7566         /*  These types of fields are allowed to have value_strings,
7567          *  true_false_strings or a protocol_t struct
7568          */
7569         if (hfinfo->strings != NULL) {
7570                 switch (hfinfo->type) {
7571                 case FT_CHAR:
7572                 case FT_UINT8:
7573                 case FT_UINT16:
7574                 case FT_UINT24:
7575                 case FT_UINT32:
7576                 case FT_UINT40:
7577                 case FT_UINT48:
7578                 case FT_UINT56:
7579                 case FT_UINT64:
7580                 case FT_INT8:
7581                 case FT_INT16:
7582                 case FT_INT24:
7583                 case FT_INT32:
7584                 case FT_INT40:
7585                 case FT_INT48:
7586                 case FT_INT56:
7587                 case FT_INT64:
7588                 case FT_BOOLEAN:
7589                 case FT_PROTOCOL:
7590                 case FT_FRAMENUM:
7591                         break;
7592                 case FT_FLOAT:
7593                 case FT_DOUBLE:
7594                         //allowed to support string if its a unit decsription
7595                         if (hfinfo->display & BASE_UNIT_STRING)
7596                                 break;
7597
7598                         //fallthrough
7599                 case FT_BYTES:
7600                         //allowed to support string if its a protocol (for pinos)
7601                         if (hfinfo->display & BASE_PROTOCOL_INFO)
7602                                 break;
7603
7604                         //fallthrough
7605                 default:
7606                         g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
7607                                 " (which is not allowed to have strings)\n",
7608                                 hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
7609                 }
7610         }
7611
7612         /* TODO: This check may slow down startup, and output quite a few warnings.
7613            It would be good to be able to enable this (and possibly other checks?)
7614            in non-release builds.   */
7615 #if ENABLE_CHECK_FILTER
7616         /* Check for duplicate value_string values.
7617            There are lots that have the same value *and* string, so for now only
7618            report those that have same value but different string. */
7619         if ((hfinfo->strings != NULL) &&
7620             !(hfinfo->display & BASE_RANGE_STRING) &&
7621             !(hfinfo->display & BASE_UNIT_STRING) &&
7622             !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
7623             (
7624                     (hfinfo->type == FT_CHAR)  ||
7625                     (hfinfo->type == FT_UINT8)  ||
7626                     (hfinfo->type == FT_UINT16) ||
7627                     (hfinfo->type == FT_UINT24) ||
7628                     (hfinfo->type == FT_UINT32) ||
7629                     (hfinfo->type == FT_INT8)   ||
7630                     (hfinfo->type == FT_INT16)  ||
7631                     (hfinfo->type == FT_INT24)  ||
7632                     (hfinfo->type == FT_INT32)  )) {
7633
7634                 int n, m;
7635                 const value_string *start_values;
7636                 const value_string *current;
7637
7638                 if (hfinfo->display & BASE_EXT_STRING)
7639                         start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
7640                 else
7641                         start_values = (const value_string*)hfinfo->strings;
7642                 current = start_values;
7643
7644                 for (n=0; current; n++, current++) {
7645                         /* Drop out if we reached the end. */
7646                         if ((current->value == 0) && (current->strptr == NULL)) {
7647                                 break;
7648                         }
7649
7650                         /* Check value against all previous */
7651                         for (m=0; m < n; m++) {
7652                                 /* There are lots of duplicates with the same string,
7653                                    so only report if different... */
7654                                 if ((start_values[m].value == current->value) &&
7655                                     (strcmp(start_values[m].strptr, current->strptr) != 0)) {
7656                                         ws_g_warning("Field '%s' (%s) has a conflicting entry in its"
7657                                                   " value_string: %u is at indices %u (%s) and %u (%s)\n",
7658                                                   hfinfo->name, hfinfo->abbrev,
7659                                                   current->value, m, start_values[m].strptr, n, current->strptr);
7660                                 }
7661                         }
7662                 }
7663         }
7664 #endif
7665
7666
7667         switch (hfinfo->type) {
7668
7669                 case FT_CHAR:
7670                         /*  Require the char type to have BASE_HEX, BASE_OCT,
7671                          *  BASE_CUSTOM, or BASE_NONE as its base.
7672                          *
7673                          *  If the display value is BASE_NONE and there is a
7674                          *  strings conversion then the dissector writer is
7675                          *  telling us that the field's numerical value is
7676                          *  meaningless; we'll avoid showing the value to the
7677                          *  user.
7678                          */
7679                         switch (FIELD_DISPLAY(hfinfo->display)) {
7680                                 case BASE_HEX:
7681                                 case BASE_OCT:
7682                                 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
7683                                         break;
7684                                 case BASE_NONE:
7685                                         if (hfinfo->strings == NULL)
7686                                                 g_error("Field '%s' (%s) is an integral value (%s)"
7687                                                         " but is being displayed as BASE_NONE but"
7688                                                         " without a strings conversion",
7689                                                         hfinfo->name, hfinfo->abbrev,
7690                                                         ftype_name(hfinfo->type));
7691                                         break;
7692                                 default:
7693                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7694                                         g_error("Field '%s' (%s) is a character value (%s)"
7695                                                 " but is being displayed as %s\n",
7696                                                 hfinfo->name, hfinfo->abbrev,
7697                                                 ftype_name(hfinfo->type), tmp_str);
7698                                         wmem_free(NULL, tmp_str);
7699                         }
7700                         if (hfinfo->display & BASE_UNIT_STRING) {
7701                                 g_error("Field '%s' (%s) is a character value (%s) but has a unit string\n",
7702                                         hfinfo->name, hfinfo->abbrev,
7703                                         ftype_name(hfinfo->type));
7704                         }
7705                         break;
7706                 case FT_INT8:
7707                 case FT_INT16:
7708                 case FT_INT24:
7709                 case FT_INT32:
7710                 case FT_INT40:
7711                 case FT_INT48:
7712                 case FT_INT56:
7713                 case FT_INT64:
7714                         /*      Hexadecimal and octal are, in printf() and everywhere
7715                          *      else, unsigned so don't allow dissectors to register a
7716                          *      signed field to be displayed unsigned.  (Else how would
7717                          *      we display negative values?)
7718                          */
7719                         switch (FIELD_DISPLAY(hfinfo->display)) {
7720                                 case BASE_HEX:
7721                                 case BASE_OCT:
7722                                 case BASE_DEC_HEX:
7723                                 case BASE_HEX_DEC:
7724                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7725                                         g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
7726                                                 hfinfo->name, hfinfo->abbrev,
7727                                                 ftype_name(hfinfo->type), tmp_str);
7728                                         wmem_free(NULL, tmp_str);
7729                         }
7730                         /* FALL THROUGH */
7731                 case FT_UINT8:
7732                 case FT_UINT16:
7733                 case FT_UINT24:
7734                 case FT_UINT32:
7735                 case FT_UINT40:
7736                 case FT_UINT48:
7737                 case FT_UINT56:
7738                 case FT_UINT64:
7739                         if (IS_BASE_PORT(hfinfo->display)) {
7740                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7741                                 if (hfinfo->type != FT_UINT16) {
7742                                         g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
7743                                                 hfinfo->name, hfinfo->abbrev,
7744                                                 tmp_str, ftype_name(hfinfo->type));
7745                                 }
7746                                 if (hfinfo->strings != NULL) {
7747                                         g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
7748                                                 hfinfo->name, hfinfo->abbrev,
7749                                                 ftype_name(hfinfo->type), tmp_str);
7750                                 }
7751                                 if (hfinfo->bitmask != 0) {
7752                                         g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
7753                                                 hfinfo->name, hfinfo->abbrev,
7754                                                 ftype_name(hfinfo->type), tmp_str);
7755                                 }
7756                                 wmem_free(NULL, tmp_str);
7757                                 break;
7758                         }
7759
7760                         if (hfinfo->display == BASE_OUI) {
7761                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7762                                 if (hfinfo->type != FT_UINT24) {
7763                                         g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s\n",
7764                                                 hfinfo->name, hfinfo->abbrev,
7765                                                 tmp_str, ftype_name(hfinfo->type));
7766                                 }
7767                                 if (hfinfo->strings != NULL) {
7768                                         g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
7769                                                 hfinfo->name, hfinfo->abbrev,
7770                                                 ftype_name(hfinfo->type), tmp_str);
7771                                 }
7772                                 if (hfinfo->bitmask != 0) {
7773                                         g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
7774                                                 hfinfo->name, hfinfo->abbrev,
7775                                                 ftype_name(hfinfo->type), tmp_str);
7776                                 }
7777                                 wmem_free(NULL, tmp_str);
7778                                 break;
7779                         }
7780
7781                         /*  Require integral types (other than frame number,
7782                          *  which is always displayed in decimal) to have a
7783                          *  number base.
7784                          *
7785                          *  If the display value is BASE_NONE and there is a
7786                          *  strings conversion then the dissector writer is
7787                          *  telling us that the field's numerical value is
7788                          *  meaningless; we'll avoid showing the value to the
7789                          *  user.
7790                          */
7791                         switch (FIELD_DISPLAY(hfinfo->display)) {
7792                                 case BASE_DEC:
7793                                 case BASE_HEX:
7794                                 case BASE_OCT:
7795                                 case BASE_DEC_HEX:
7796                                 case BASE_HEX_DEC:
7797                                 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
7798                                         break;
7799                                 case BASE_NONE:
7800                                         if (hfinfo->strings == NULL) {
7801                                                 g_error("Field '%s' (%s) is an integral value (%s)"
7802                                                         " but is being displayed as BASE_NONE but"
7803                                                         " without a strings conversion",
7804                                                         hfinfo->name, hfinfo->abbrev,
7805                                                         ftype_name(hfinfo->type));
7806                                         }
7807                                         if (hfinfo->display & BASE_SPECIAL_VALS) {
7808                                                 g_error("Field '%s' (%s) is an integral value (%s)"
7809                                                         " that is being displayed as BASE_NONE but"
7810                                                         " with BASE_SPECIAL_VALS",
7811                                                         hfinfo->name, hfinfo->abbrev,
7812                                                         ftype_name(hfinfo->type));
7813                                         }
7814                                         break;
7815
7816                                 default:
7817                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7818                                         g_error("Field '%s' (%s) is an integral value (%s)"
7819                                                 " but is being displayed as %s\n",
7820                                                 hfinfo->name, hfinfo->abbrev,
7821                                                 ftype_name(hfinfo->type), tmp_str);
7822                                         wmem_free(NULL, tmp_str);
7823                         }
7824                         break;
7825                 case FT_BYTES:
7826                 case FT_UINT_BYTES:
7827                         /*  Require bytes to have a "display type" that could
7828                          *  add a character between displayed bytes.
7829                          */
7830                         switch (FIELD_DISPLAY(hfinfo->display)) {
7831                                 case BASE_NONE:
7832                                 case SEP_DOT:
7833                                 case SEP_DASH:
7834                                 case SEP_COLON:
7835                                 case SEP_SPACE:
7836                                         break;
7837                                 default:
7838                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7839                                         g_error("Field '%s' (%s) is an byte array but is being displayed as %s instead of BASE_NONE, SEP_DOT, SEP_DASH, SEP_COLON, or SEP_SPACE\n",
7840                                                 hfinfo->name, hfinfo->abbrev, tmp_str);
7841                                         wmem_free(NULL, tmp_str);
7842                         }
7843                         if (hfinfo->bitmask != 0)
7844                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7845                                         hfinfo->name, hfinfo->abbrev,
7846                                         ftype_name(hfinfo->type));
7847                         //allowed to support string if its a protocol (for pinos)
7848                         if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_PROTOCOL_INFO)))
7849                                 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7850                                         hfinfo->name, hfinfo->abbrev,
7851                                         ftype_name(hfinfo->type));
7852                         break;
7853
7854                 case FT_PROTOCOL:
7855                 case FT_FRAMENUM:
7856                         if (hfinfo->display != BASE_NONE) {
7857                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7858                                 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7859                                         hfinfo->name, hfinfo->abbrev,
7860                                         ftype_name(hfinfo->type), tmp_str);
7861                                 wmem_free(NULL, tmp_str);
7862                         }
7863                         if (hfinfo->bitmask != 0)
7864                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7865                                         hfinfo->name, hfinfo->abbrev,
7866                                         ftype_name(hfinfo->type));
7867                         break;
7868
7869                 case FT_BOOLEAN:
7870                         break;
7871
7872                 case FT_ABSOLUTE_TIME:
7873                         if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
7874                               hfinfo->display == ABSOLUTE_TIME_UTC   ||
7875                               hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
7876                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7877                                 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
7878                                         hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
7879                                 wmem_free(NULL, tmp_str);
7880                         }
7881                         if (hfinfo->bitmask != 0)
7882                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7883                                         hfinfo->name, hfinfo->abbrev,
7884                                         ftype_name(hfinfo->type));
7885                         break;
7886
7887                 case FT_STRING:
7888                 case FT_STRINGZ:
7889                 case FT_UINT_STRING:
7890                 case FT_STRINGZPAD:
7891                         switch (hfinfo->display) {
7892                                 case STR_ASCII:
7893                                 case STR_UNICODE:
7894                                         break;
7895
7896                                 default:
7897                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7898                                         g_error("Field '%s' (%s) is an string value (%s)"
7899                                                 " but is being displayed as %s\n",
7900                                                 hfinfo->name, hfinfo->abbrev,
7901                                                 ftype_name(hfinfo->type), tmp_str);
7902                                         wmem_free(NULL, tmp_str);
7903                         }
7904
7905                         if (hfinfo->bitmask != 0)
7906                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7907                                         hfinfo->name, hfinfo->abbrev,
7908                                         ftype_name(hfinfo->type));
7909                         if (hfinfo->strings != NULL)
7910                                 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7911                                         hfinfo->name, hfinfo->abbrev,
7912                                         ftype_name(hfinfo->type));
7913                         break;
7914
7915                 case FT_IPv4:
7916                         switch (hfinfo->display) {
7917                                 case BASE_NONE:
7918                                 case BASE_NETMASK:
7919                                         break;
7920
7921                                 default:
7922                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
7923                                         g_error("Field '%s' (%s) is an IPv4 value (%s)"
7924                                                 " but is being displayed as %s\n",
7925                                                 hfinfo->name, hfinfo->abbrev,
7926                                                 ftype_name(hfinfo->type), tmp_str);
7927                                         wmem_free(NULL, tmp_str);
7928                                         break;
7929                         }
7930                         break;
7931                 case FT_FLOAT:
7932                 case FT_DOUBLE:
7933                         if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
7934                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7935                                 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7936                                         hfinfo->name, hfinfo->abbrev,
7937                                         ftype_name(hfinfo->type),
7938                                         tmp_str);
7939                                 wmem_free(NULL, tmp_str);
7940                         }
7941                         if (hfinfo->bitmask != 0)
7942                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7943                                         hfinfo->name, hfinfo->abbrev,
7944                                         ftype_name(hfinfo->type));
7945                         if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_UNIT_STRING)))
7946                                 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7947                                         hfinfo->name, hfinfo->abbrev,
7948                                         ftype_name(hfinfo->type));
7949                         break;
7950                 default:
7951                         if (hfinfo->display != BASE_NONE) {
7952                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
7953                                 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
7954                                         hfinfo->name, hfinfo->abbrev,
7955                                         ftype_name(hfinfo->type),
7956                                         tmp_str);
7957                                 wmem_free(NULL, tmp_str);
7958                         }
7959                         if (hfinfo->bitmask != 0)
7960                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
7961                                         hfinfo->name, hfinfo->abbrev,
7962                                         ftype_name(hfinfo->type));
7963                         if (hfinfo->strings != NULL)
7964                                 g_error("Field '%s' (%s) is an %s but has a strings value\n",
7965                                         hfinfo->name, hfinfo->abbrev,
7966                                         ftype_name(hfinfo->type));
7967                         break;
7968         }
7969 }
7970
7971 #ifdef ENABLE_CHECK_FILTER
7972 static enum ftenum
7973 _ftype_common(enum ftenum type)
7974 {
7975         switch (type) {
7976                 case FT_INT8:
7977                 case FT_INT16:
7978                 case FT_INT24:
7979                 case FT_INT32:
7980                         return FT_INT32;
7981
7982                 case FT_CHAR:
7983                 case FT_UINT8:
7984                 case FT_UINT16:
7985                 case FT_UINT24:
7986                 case FT_UINT32:
7987                 case FT_IPXNET:
7988                 case FT_FRAMENUM:
7989                         return FT_UINT32;
7990
7991                 case FT_UINT64:
7992                 case FT_EUI64:
7993                         return FT_UINT64;
7994
7995                 case FT_STRING:
7996                 case FT_STRINGZ:
7997                 case FT_UINT_STRING:
7998                         return FT_STRING;
7999
8000                 case FT_FLOAT:
8001                 case FT_DOUBLE:
8002                         return FT_DOUBLE;
8003
8004                 case FT_BYTES:
8005                 case FT_UINT_BYTES:
8006                 case FT_ETHER:
8007                 case FT_OID:
8008                         return FT_BYTES;
8009
8010                 case FT_ABSOLUTE_TIME:
8011                 case FT_RELATIVE_TIME:
8012                         return FT_ABSOLUTE_TIME;
8013
8014                 default:
8015                         return type;
8016         }
8017 }
8018 #endif
8019
8020 static void
8021 register_type_length_mismatch(void)
8022 {
8023         static ei_register_info ei[] = {
8024                 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
8025                 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
8026         };
8027
8028         expert_module_t* expert_type_length_mismatch;
8029
8030         proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
8031
8032         expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
8033         expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
8034
8035         /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
8036            disabling them makes no sense. */
8037         proto_set_cant_toggle(proto_type_length_mismatch);
8038 }
8039
8040 static void
8041 register_number_string_decoding_error(void)
8042 {
8043         static ei_register_info ei[] = {
8044                 { &ei_number_string_decoding_failed_error,
8045                         { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
8046                           "Failed to decode number from string", EXPFILL
8047                         }
8048                 },
8049                 { &ei_number_string_decoding_erange_error,
8050                         { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
8051                           "Decoded number from string is out of valid range", EXPFILL
8052                         }
8053                 },
8054         };
8055
8056         expert_module_t* expert_number_string_decoding_error;
8057
8058         proto_number_string_decoding_error =
8059                 proto_register_protocol("Number-String Decoding Error",
8060                                         "Number-string decoding error",
8061                                         "_ws.number_string.decoding_error");
8062
8063         expert_number_string_decoding_error =
8064                 expert_register_protocol(proto_number_string_decoding_error);
8065         expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
8066
8067         /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
8068            disabling them makes no sense. */
8069         proto_set_cant_toggle(proto_number_string_decoding_error);
8070 }
8071
8072 static void
8073 register_string_errors(void)
8074 {
8075         static ei_register_info ei[] = {
8076                 { &ei_string_trailing_characters,
8077                         { "_ws.string.trailing_stray_characters", PI_UNDECODED, PI_WARN, "Trailing stray characters", EXPFILL }
8078                 },
8079         };
8080
8081         expert_module_t* expert_string_errors;
8082
8083         proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
8084
8085         expert_string_errors = expert_register_protocol(proto_string_errors);
8086         expert_register_field_array(expert_string_errors, ei, array_length(ei));
8087
8088         /* "String Errors" isn't really a protocol, it's an error indication;
8089            disabling them makes no sense. */
8090         proto_set_cant_toggle(proto_string_errors);
8091 }
8092
8093 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (201000+PRE_ALLOC_EXPERT_FIELDS_MEM)
8094 static int
8095 proto_register_field_init(header_field_info *hfinfo, const int parent)
8096 {
8097
8098         tmp_fld_check_assert(hfinfo);
8099
8100         hfinfo->parent         = parent;
8101         hfinfo->same_name_next = NULL;
8102         hfinfo->same_name_prev_id = -1;
8103
8104         /* if we always add and never delete, then id == len - 1 is correct */
8105         if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
8106                 if (!gpa_hfinfo.hfi) {
8107                         gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
8108                         gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8109                 } else {
8110                         gpa_hfinfo.allocated_len += 1000;
8111                         gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
8112                                                    sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
8113                         /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
8114                 }
8115         }
8116         gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
8117         gpa_hfinfo.len++;
8118         hfinfo->id = gpa_hfinfo.len - 1;
8119
8120         /* if we have real names, enter this field in the name tree */
8121         if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
8122
8123                 header_field_info *same_name_next_hfinfo;
8124                 guchar c;
8125
8126                 /* Check that the filter name (abbreviation) is legal;
8127                  * it must contain only alphanumerics, '-', "_", and ".". */
8128                 c = proto_check_field_name(hfinfo->abbrev);
8129                 if (c) {
8130                         if (c == '.') {
8131                                 fprintf(stderr, "Invalid leading, duplicated or trailing '.' found in filter name '%s'\n", hfinfo->abbrev);
8132                         } else if (g_ascii_isprint(c)) {
8133                                 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
8134                         } else {
8135                                 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
8136                         }
8137                         DISSECTOR_ASSERT_NOT_REACHED();
8138                 }
8139
8140                 /* We allow multiple hfinfo's to be registered under the same
8141                  * abbreviation. This was done for X.25, as, depending
8142                  * on whether it's modulo-8 or modulo-128 operation,
8143                  * some bitfield fields may be in different bits of
8144                  * a byte, and we want to be able to refer to that field
8145                  * with one name regardless of whether the packets
8146                  * are modulo-8 or modulo-128 packets. */
8147
8148                 same_name_hfinfo = NULL;
8149
8150                 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
8151                 /* GLIB 2.x - if it is already present
8152                  * the previous hfinfo with the same name is saved
8153                  * to same_name_hfinfo by value destroy callback */
8154                 if (same_name_hfinfo) {
8155                         /* There's already a field with this name.
8156                          * Put the current field *before* that field
8157                          * in the list of fields with this name, Thus,
8158                          * we end up with an effectively
8159                          * doubly-linked-list of same-named hfinfo's,
8160                          * with the head of the list (stored in the
8161                          * hash) being the last seen hfinfo.
8162                          */
8163                         same_name_next_hfinfo =
8164                                 same_name_hfinfo->same_name_next;
8165
8166                         hfinfo->same_name_next = same_name_next_hfinfo;
8167                         if (same_name_next_hfinfo)
8168                                 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
8169
8170                         same_name_hfinfo->same_name_next = hfinfo;
8171                         hfinfo->same_name_prev_id = same_name_hfinfo->id;
8172 #ifdef ENABLE_CHECK_FILTER
8173                         while (same_name_hfinfo) {
8174                                 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
8175                                         fprintf(stderr, "'%s' exists multiple times with NOT compatible types: %s and %s\n", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type));
8176                                 same_name_hfinfo = same_name_hfinfo->same_name_next;
8177                         }
8178 #endif
8179                 }
8180         }
8181
8182         return hfinfo->id;
8183 }
8184
8185 void
8186 proto_register_subtree_array(gint *const *indices, const int num_indices)
8187 {
8188         int     i;
8189         gint    *const *ptr = indices;
8190
8191         /*
8192          * If we've already allocated the array of tree types, expand
8193          * it; this lets plugins such as mate add tree types after
8194          * the initial startup.  (If we haven't already allocated it,
8195          * we don't allocate it; on the first pass, we just assign
8196          * ett values and keep track of how many we've assigned, and
8197          * when we're finished registering all dissectors we allocate
8198          * the array, so that we do only one allocation rather than
8199          * wasting CPU time and memory by growing the array for each
8200          * dissector that registers ett values.)
8201          */
8202         if (tree_is_expanded != NULL) {
8203                 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
8204
8205                 /* set new items to 0 */
8206                 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
8207                 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
8208                         tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
8209         }
8210
8211         /*
8212          * Assign "num_indices" subtree numbers starting at "num_tree_types",
8213          * returning the indices through the pointers in the array whose
8214          * first element is pointed to by "indices", and update
8215          * "num_tree_types" appropriately.
8216          */
8217         for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
8218                 if (**ptr != -1) {
8219                         /* g_error will terminate the program */
8220                         g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
8221                                 " This is a development error:"
8222                                 " Either the subtree item type has already been assigned or"
8223                                 " was not initialized to -1.");
8224                 }
8225                 **ptr = num_tree_types;
8226         }
8227 }
8228
8229 static inline gsize
8230 label_concat(char *label_str, gsize pos, const char *str)
8231 {
8232         if (pos < ITEM_LABEL_LENGTH)
8233                 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
8234
8235         return pos;
8236 }
8237
8238 static void
8239 label_mark_truncated(char *label_str, gsize name_pos)
8240 {
8241         static const char  trunc_str[] = " [truncated]";
8242         const size_t       trunc_len = sizeof(trunc_str)-1;
8243         gchar             *last_char;
8244
8245         /* ..... field_name: dataaaaaaaaaaaaa
8246          *                 |
8247          *                 ^^^^^ name_pos
8248          *
8249          * ..... field_name [truncated]: dataaaaaaaaaaaaa
8250          *
8251          * name_pos==0 means that we have only data or only a field_name
8252          */
8253
8254         if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
8255                 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
8256                 memcpy(label_str + name_pos, trunc_str, trunc_len);
8257
8258                 /* in general, label_str is UTF-8
8259                    we can truncate it only at the beginning of a new character
8260                    we go backwards from the byte right after our buffer and
8261                     find the next starting byte of a UTF-8 character, this is
8262                     where we cut
8263                    there's no need to use g_utf8_find_prev_char(), the search
8264                     will always succeed since we copied trunc_str into the
8265                     buffer */
8266                 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH - 1]);
8267                 *last_char = '\0';
8268
8269         } else if (name_pos < ITEM_LABEL_LENGTH)
8270                 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
8271 }
8272
8273 static gsize
8274 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
8275 {
8276         gsize name_pos;
8277
8278         /* "%s: %s", hfinfo->name, text */
8279         name_pos = pos = label_concat(label_str, pos, hfinfo->name);
8280         if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
8281                 pos = label_concat(label_str, pos, ": ");
8282                 pos = label_concat(label_str, pos, text ? text : "(null)");
8283         }
8284
8285         if (pos >= ITEM_LABEL_LENGTH) {
8286                 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8287                 label_mark_truncated(label_str, name_pos);
8288         }
8289
8290         return pos;
8291 }
8292
8293 static gsize
8294 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
8295 {
8296         gsize name_pos;
8297
8298         /* "%s: %s (%s)", hfinfo->name, text, descr */
8299         name_pos = pos = label_concat(label_str, pos, hfinfo->name);
8300         if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
8301                 pos = label_concat(label_str, pos, ": ");
8302                 if (hfinfo->display & BASE_UNIT_STRING) {
8303                         pos = label_concat(label_str, pos, descr ? descr : "(null)");
8304                         pos = label_concat(label_str, pos, text ? text : "(null)");
8305                 } else {
8306                         pos = label_concat(label_str, pos, text ? text : "(null)");
8307                         pos = label_concat(label_str, pos, " (");
8308                         pos = label_concat(label_str, pos, descr ? descr : "(null)");
8309                         pos = label_concat(label_str, pos, ")");
8310                 }
8311         }
8312
8313         if (pos >= ITEM_LABEL_LENGTH) {
8314                 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8315                 label_mark_truncated(label_str, name_pos);
8316         }
8317
8318         return pos;
8319 }
8320
8321 void
8322 proto_item_fill_label(field_info *fi, gchar *label_str)
8323 {
8324         header_field_info  *hfinfo;
8325         guint8             *bytes;
8326         guint32             integer;
8327         guint64             integer64;
8328         guint32             ipv4;
8329         e_guid_t           *guid;
8330         gchar              *name;
8331         address             addr;
8332         char               *addr_str;
8333         char               *tmp;
8334
8335         if (!fi) {
8336                 if (label_str)
8337                         label_str[0]= '\0';
8338                 /* XXX: Check validity of hfinfo->type */
8339                 return;
8340         }
8341
8342         hfinfo = fi->hfinfo;
8343
8344         switch (hfinfo->type) {
8345                 case FT_NONE:
8346                 case FT_PROTOCOL:
8347                         g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
8348                         break;
8349
8350                 case FT_BOOLEAN:
8351                         fill_label_boolean(fi, label_str);
8352                         break;
8353
8354                 case FT_BYTES:
8355                 case FT_UINT_BYTES:
8356                         bytes = (guint8 *)fvalue_get(&fi->value);
8357                         if (bytes) {
8358                                 char* str = NULL;
8359                                 switch (hfinfo->display) {
8360                                 case SEP_DOT:
8361                                         str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
8362                                         break;
8363                                 case SEP_DASH:
8364                                         str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
8365                                         break;
8366                                 case SEP_COLON:
8367                                         str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
8368                                         break;
8369                                 case SEP_SPACE:
8370                                         str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
8371                                         break;
8372                                 case BASE_NONE:
8373                                 default:
8374                                         if (prefs.display_byte_fields_with_spaces) {
8375                                                 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
8376                                         } else {
8377                                                 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
8378                                         }
8379                                         break;
8380                                 }
8381                                 label_fill(label_str, 0, hfinfo, str);
8382                                 wmem_free(NULL, str);
8383                         } else {
8384                                 if (hfinfo->display & BASE_ALLOW_ZERO) {
8385                                         label_fill(label_str, 0, hfinfo, "<none>");
8386                                 } else {
8387                                         label_fill(label_str, 0, hfinfo, "<MISSING>");
8388                                 }
8389                         }
8390                         break;
8391
8392                 case FT_CHAR:
8393                         if (hfinfo->bitmask) {
8394                                 fill_label_bitfield_char(fi, label_str);
8395                         } else {
8396                                 fill_label_char(fi, label_str);
8397                         }
8398                         break;
8399
8400                 /* Four types of integers to take care of:
8401                  *      Bitfield, with val_string
8402                  *      Bitfield, w/o val_string
8403                  *      Non-bitfield, with val_string
8404                  *      Non-bitfield, w/o val_string
8405                  */
8406                 case FT_UINT8:
8407                 case FT_UINT16:
8408                 case FT_UINT24:
8409                 case FT_UINT32:
8410                         if (hfinfo->bitmask) {
8411                                 if (fi->flags & FI_VARINT) {
8412                                         fill_label_bitfield_varint(fi, label_str, FALSE);
8413                                 } else {
8414                                         fill_label_bitfield(fi, label_str, FALSE);
8415                                 }
8416                         } else {
8417                                 fill_label_number(fi, label_str, FALSE);
8418                         }
8419                         break;
8420
8421                 case FT_FRAMENUM:
8422                         fill_label_number(fi, label_str, FALSE);
8423                         break;
8424
8425                 case FT_UINT40:
8426                 case FT_UINT48:
8427                 case FT_UINT56:
8428                 case FT_UINT64:
8429                         if (hfinfo->bitmask) {
8430                                 if (fi->flags & FI_VARINT) {
8431                                         fill_label_bitfield_varint64(fi, label_str, FALSE);
8432                                 } else {
8433                                         fill_label_bitfield64(fi, label_str, FALSE);
8434                                 }
8435                         } else {
8436                                 fill_label_number64(fi, label_str, FALSE);
8437                         }
8438                         break;
8439
8440                 case FT_INT8:
8441                 case FT_INT16:
8442                 case FT_INT24:
8443                 case FT_INT32:
8444                         if (hfinfo->bitmask) {
8445                                 if (fi->flags & FI_VARINT) {
8446                                         fill_label_bitfield_varint(fi, label_str, TRUE);
8447                                 } else {
8448                                         fill_label_bitfield(fi, label_str, TRUE);
8449                                 }
8450                         } else {
8451                                 fill_label_number(fi, label_str, TRUE);
8452                         }
8453                         break;
8454
8455                 case FT_INT40:
8456                 case FT_INT48:
8457                 case FT_INT56:
8458                 case FT_INT64:
8459                         if (hfinfo->bitmask) {
8460                                 if (fi->flags & FI_VARINT) {
8461                                         fill_label_bitfield_varint64(fi, label_str, TRUE);
8462                                 } else {
8463                                         fill_label_bitfield64(fi, label_str, TRUE);
8464                                 }
8465                         } else {
8466                                 fill_label_number64(fi, label_str, TRUE);
8467                         }
8468                         break;
8469
8470                 case FT_FLOAT:
8471                 {
8472                         double d_value = fvalue_get_floating(&fi->value);
8473                         if (hfinfo->display & BASE_UNIT_STRING) {
8474                                 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8475                                            "%s: %." G_STRINGIFY(FLT_DIG) "g%s",
8476                                            hfinfo->name, d_value,
8477                                            unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
8478                         } else {
8479                                 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8480                                            "%s: %." G_STRINGIFY(FLT_DIG) "g",
8481                                            hfinfo->name, d_value);
8482                         }
8483                         break;
8484                 }
8485
8486                 case FT_DOUBLE:
8487                 {
8488                         double d_value = fvalue_get_floating(&fi->value);
8489                         if (hfinfo->display & BASE_UNIT_STRING) {
8490                                 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8491                                            "%s: %." G_STRINGIFY(DBL_DIG) "g%s",
8492                                            hfinfo->name, d_value,
8493                                            unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
8494                         } else {
8495                                 g_snprintf(label_str, ITEM_LABEL_LENGTH,
8496                                            "%s: %." G_STRINGIFY(DBL_DIG) "g",
8497                                            hfinfo->name, d_value);
8498                         }
8499                         break;
8500                 }
8501
8502                 case FT_ABSOLUTE_TIME:
8503                         tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
8504                         label_fill(label_str, 0, hfinfo, tmp);
8505                         wmem_free(NULL, tmp);
8506                         break;
8507
8508                 case FT_RELATIVE_TIME:
8509                         tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
8510                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
8511                                    "%s: %s seconds", hfinfo->name, tmp);
8512                         wmem_free(NULL, tmp);
8513                         break;
8514
8515                 case FT_IPXNET:
8516                         integer = fvalue_get_uinteger(&fi->value);
8517                         tmp = get_ipxnet_name(NULL, integer);
8518                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
8519                                    "%s: %s (0x%08X)", hfinfo->name,
8520                                    tmp, integer);
8521                         wmem_free(NULL, tmp);
8522                         break;
8523
8524                 case FT_AX25:
8525                         addr.type = AT_AX25;
8526                         addr.len  = AX25_ADDR_LEN;
8527                         addr.data = (guint8 *)fvalue_get(&fi->value);
8528
8529                         addr_str = (char*)address_to_str(NULL, &addr);
8530                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
8531                                    "%s: %s", hfinfo->name, addr_str);
8532                         wmem_free(NULL, addr_str);
8533                         break;
8534
8535                 case FT_VINES:
8536                         addr.type = AT_VINES;
8537                         addr.len  = VINES_ADDR_LEN;
8538                         addr.data = (guint8 *)fvalue_get(&fi->value);
8539
8540                         addr_str = (char*)address_to_str(NULL, &addr);
8541                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
8542                                    "%s: %s", hfinfo->name, addr_str);
8543                         wmem_free(NULL, addr_str);
8544                         break;
8545
8546                 case FT_ETHER:
8547                         bytes = (guint8 *)fvalue_get(&fi->value);
8548
8549                         addr.type = AT_ETHER;
8550                         addr.len  = 6;
8551                         addr.data = bytes;
8552
8553                         addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8554                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
8555                                    "%s: %s", hfinfo->name, addr_str);
8556                         wmem_free(NULL, addr_str);
8557                         break;
8558
8559                 case FT_IPv4:
8560                         ipv4 = fvalue_get_uinteger(&fi->value);
8561
8562                         addr.type = AT_IPv4;
8563                         addr.len  = 4;
8564                         addr.data = &ipv4;
8565
8566                         if (hfinfo->display == BASE_NETMASK) {
8567                                 addr_str = (char*)address_to_str(NULL, &addr);
8568                         } else {
8569                                 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8570                         }
8571                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
8572                                    "%s: %s", hfinfo->name, addr_str);
8573                         wmem_free(NULL, addr_str);
8574                         break;
8575
8576                 case FT_IPv6:
8577                         bytes = (guint8 *)fvalue_get(&fi->value);
8578
8579                         addr.type = AT_IPv6;
8580                         addr.len  = 16;
8581                         addr.data = bytes;
8582
8583                         addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8584                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
8585                                    "%s: %s", hfinfo->name, addr_str);
8586                         wmem_free(NULL, addr_str);
8587                         break;
8588
8589                 case FT_FCWWN:
8590                         addr.type = AT_FCWWN;
8591                         addr.len  = FCWWN_ADDR_LEN;
8592                         addr.data = (guint8 *)fvalue_get(&fi->value);
8593
8594                         addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
8595                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
8596                                    "%s: %s", hfinfo->name, addr_str);
8597                         wmem_free(NULL, addr_str);
8598                         break;
8599
8600                 case FT_GUID:
8601                         guid = (e_guid_t *)fvalue_get(&fi->value);
8602                         tmp = guid_to_str(NULL, guid);
8603                         label_fill(label_str, 0, hfinfo, tmp);
8604                         wmem_free(NULL, tmp);
8605                         break;
8606
8607                 case FT_OID:
8608                         bytes = (guint8 *)fvalue_get(&fi->value);
8609                         name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
8610                         tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
8611                         if (name) {
8612                                 label_fill_descr(label_str, 0, hfinfo, tmp, name);
8613                                 wmem_free(NULL, name);
8614                         } else {
8615                                 label_fill(label_str, 0, hfinfo, tmp);
8616                         }
8617                         wmem_free(NULL, tmp);
8618                         break;
8619
8620                 case FT_REL_OID:
8621                         bytes = (guint8 *)fvalue_get(&fi->value);
8622                         name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
8623                         tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
8624                         if (name) {
8625                                 label_fill_descr(label_str, 0, hfinfo, tmp, name);
8626                                 wmem_free(NULL, name);
8627                         } else {
8628                                 label_fill(label_str, 0, hfinfo, tmp);
8629                         }
8630                         wmem_free(NULL, tmp);
8631                         break;
8632
8633                 case FT_SYSTEM_ID:
8634                         bytes = (guint8 *)fvalue_get(&fi->value);
8635                         tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
8636                         label_fill(label_str, 0, hfinfo, tmp);
8637                         wmem_free(NULL, tmp);
8638                         break;
8639
8640                 case FT_EUI64:
8641                         integer64 = fvalue_get_uinteger64(&fi->value);
8642                         addr_str = eui64_to_str(NULL, integer64);
8643                         tmp = (char*)eui64_to_display(NULL, integer64);
8644                         label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
8645                         wmem_free(NULL, tmp);
8646                         wmem_free(NULL, addr_str);
8647                         break;
8648                 case FT_STRING:
8649                 case FT_STRINGZ:
8650                 case FT_UINT_STRING:
8651                 case FT_STRINGZPAD:
8652                         bytes = (guint8 *)fvalue_get(&fi->value);
8653                         tmp = hfinfo_format_text(hfinfo, bytes);
8654                         label_fill(label_str, 0, hfinfo, tmp);
8655                         wmem_free(NULL, tmp);
8656                         break;
8657
8658                 case FT_IEEE_11073_SFLOAT:
8659                 case FT_IEEE_11073_FLOAT:
8660                         tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
8661                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
8662                                                 "%s: %s",
8663                                                 hfinfo->name, tmp);
8664                         wmem_free(NULL, tmp);
8665                         break;
8666
8667                 default:
8668                         g_error("hfinfo->type %d (%s) not handled\n",
8669                                 hfinfo->type, ftype_name(hfinfo->type));
8670                         DISSECTOR_ASSERT_NOT_REACHED();
8671                         break;
8672         }
8673 }
8674
8675 static void
8676 fill_label_boolean(field_info *fi, gchar *label_str)
8677 {
8678         char    *p                    = label_str;
8679         int      bitfield_byte_length = 0, bitwidth;
8680         guint64  unshifted_value;
8681         guint64  value;
8682
8683         header_field_info       *hfinfo   = fi->hfinfo;
8684         const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
8685
8686         if (hfinfo->strings) {
8687                 tfstring = (const struct true_false_string*) hfinfo->strings;
8688         }
8689
8690         value = fvalue_get_uinteger64(&fi->value);
8691         if (hfinfo->bitmask) {
8692                 /* Figure out the bit width */
8693                 bitwidth = hfinfo_container_bitwidth(hfinfo);
8694
8695                 /* Un-shift bits */
8696                 unshifted_value = value;
8697                 unshifted_value <<= hfinfo_bitshift(hfinfo);
8698
8699                 /* Create the bitfield first */
8700                 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8701                 bitfield_byte_length = (int) (p - label_str);
8702         }
8703
8704         /* Fill in the textual info */
8705         label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
8706 }
8707
8708 static const char *
8709 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
8710 {
8711         if (hfinfo->display & BASE_RANGE_STRING)
8712                 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
8713
8714         if (hfinfo->display & BASE_EXT_STRING)
8715                 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
8716
8717         if (hfinfo->display & BASE_VAL64_STRING)
8718                 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
8719
8720         if (hfinfo->display & BASE_UNIT_STRING)
8721                 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
8722
8723         return try_val_to_str(value, (const value_string *) hfinfo->strings);
8724 }
8725
8726 static const char *
8727 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
8728 {
8729         if (hfinfo->display & BASE_VAL64_STRING)
8730                 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
8731
8732         if (hfinfo->display & BASE_RANGE_STRING)
8733                 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
8734
8735         if (hfinfo->display & BASE_UNIT_STRING)
8736                 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
8737
8738         /* If this is reached somebody registered a 64-bit field with a 32-bit
8739          * value-string, which isn't right. */
8740         REPORT_DISSECTOR_BUG("field %s is a 64-bit field with a 32-bit value_string",
8741             hfinfo->abbrev);
8742
8743         /* This is necessary to squelch MSVC errors; is there
8744            any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
8745            never returns? */
8746         return NULL;
8747 }
8748
8749 static const char *
8750 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
8751 {
8752         const char *str = hf_try_val_to_str(value, hfinfo);
8753
8754         return (str) ? str : unknown_str;
8755 }
8756
8757 static const char *
8758 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
8759 {
8760         const char *str = hf_try_val64_to_str(value, hfinfo);
8761
8762         return (str) ? str : unknown_str;
8763 }
8764
8765 /* Fills data for bitfield chars with val_strings */
8766 static void
8767 fill_label_bitfield_char(field_info *fi, gchar *label_str)
8768 {
8769         char       *p;
8770         int         bitfield_byte_length, bitwidth;
8771         guint32     unshifted_value;
8772         guint32     value;
8773
8774         char        buf[32];
8775         const char *out;
8776
8777         header_field_info *hfinfo = fi->hfinfo;
8778
8779         /* Figure out the bit width */
8780         bitwidth = hfinfo_container_bitwidth(hfinfo);
8781
8782         /* Un-shift bits */
8783         value = fvalue_get_uinteger(&fi->value);
8784
8785         unshifted_value = value;
8786         if (hfinfo->bitmask) {
8787                 unshifted_value <<= hfinfo_bitshift(hfinfo);
8788         }
8789
8790         /* Create the bitfield first */
8791         p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8792         bitfield_byte_length = (int) (p - label_str);
8793
8794         /* Fill in the textual info using stored (shifted) value */
8795         if (hfinfo->display == BASE_CUSTOM) {
8796                 gchar tmp[ITEM_LABEL_LENGTH];
8797                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8798
8799                 DISSECTOR_ASSERT(fmtfunc);
8800                 fmtfunc(tmp, value);
8801                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8802         }
8803         else if (hfinfo->strings) {
8804                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8805
8806                 out = hfinfo_char_vals_format(hfinfo, buf, value);
8807                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8808                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8809                 else
8810                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8811         }
8812         else {
8813                 out = hfinfo_char_value_format(hfinfo, buf, value);
8814
8815                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8816         }
8817 }
8818
8819 /* Fills data for bitfield ints with val_strings */
8820 static void
8821 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
8822 {
8823         char       *p;
8824         int         bitfield_byte_length, bitwidth;
8825         guint32     unshifted_value;
8826         guint32     value;
8827
8828         char        buf[32];
8829         const char *out;
8830
8831         header_field_info *hfinfo = fi->hfinfo;
8832
8833         /* Figure out the bit width */
8834         bitwidth = hfinfo_container_bitwidth(hfinfo);
8835
8836         /* Un-shift bits */
8837         if (is_signed)
8838                 value = fvalue_get_sinteger(&fi->value);
8839         else
8840                 value = fvalue_get_uinteger(&fi->value);
8841
8842         unshifted_value = value;
8843         if (hfinfo->bitmask) {
8844                 unshifted_value <<= hfinfo_bitshift(hfinfo);
8845         }
8846
8847         /* Create the bitfield first */
8848         p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8849         bitfield_byte_length = (int) (p - label_str);
8850
8851         /* Fill in the textual info using stored (shifted) value */
8852         if (hfinfo->display == BASE_CUSTOM) {
8853                 gchar tmp[ITEM_LABEL_LENGTH];
8854                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8855
8856                 DISSECTOR_ASSERT(fmtfunc);
8857                 fmtfunc(tmp, value);
8858                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8859         }
8860         else if (hfinfo->strings) {
8861                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8862
8863                 out = hfinfo_number_vals_format(hfinfo, buf, value);
8864                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8865                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8866                 else
8867                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8868         }
8869         else {
8870                 out = hfinfo_number_value_format(hfinfo, buf, value);
8871
8872                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8873         }
8874 }
8875
8876 static void
8877 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
8878 {
8879         char       *p;
8880         int         bitfield_byte_length, bitwidth;
8881         guint64     unshifted_value;
8882         guint64     value;
8883
8884         char        buf[48];
8885         const char *out;
8886
8887         header_field_info *hfinfo = fi->hfinfo;
8888
8889         /* Figure out the bit width */
8890         bitwidth = hfinfo_container_bitwidth(hfinfo);
8891
8892         /* Un-shift bits */
8893         if (is_signed)
8894                 value = fvalue_get_sinteger64(&fi->value);
8895         else
8896                 value = fvalue_get_uinteger64(&fi->value);
8897
8898         unshifted_value = value;
8899         if (hfinfo->bitmask) {
8900                 unshifted_value <<= hfinfo_bitshift(hfinfo);
8901         }
8902
8903         /* Create the bitfield first */
8904         p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
8905         bitfield_byte_length = (int) (p - label_str);
8906
8907         /* Fill in the textual info using stored (shifted) value */
8908         if (hfinfo->display == BASE_CUSTOM) {
8909                 gchar tmp[ITEM_LABEL_LENGTH];
8910                 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
8911
8912                 DISSECTOR_ASSERT(fmtfunc64);
8913                 fmtfunc64(tmp, value);
8914                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8915         }
8916         else if (hfinfo->strings) {
8917                 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
8918
8919                 out = hfinfo_number_vals_format64(hfinfo, buf, value);
8920                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8921                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8922                 else
8923                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8924         }
8925         else {
8926                 out = hfinfo_number_value_format64(hfinfo, buf, value);
8927
8928                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8929         }
8930 }
8931
8932 static void
8933 fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed)
8934 {
8935         char       *p;
8936         int         bitfield_byte_length;
8937         guint32     value, unshifted_value;
8938         char        buf[48];
8939         const char *out;
8940
8941         header_field_info *hfinfo = fi->hfinfo;
8942
8943         /* Un-shift bits */
8944         if (is_signed) {
8945                 value = fvalue_get_sinteger(&fi->value);
8946         } else {
8947                 value = fvalue_get_uinteger(&fi->value);
8948         }
8949         unshifted_value = value;
8950         if (hfinfo->bitmask) {
8951                 unshifted_value <<= hfinfo_bitshift(hfinfo);
8952         }
8953
8954         /* Create the bitfield first */
8955         p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
8956         bitfield_byte_length = (int) (p - label_str);
8957
8958         /* Fill in the textual info using stored (shifted) value */
8959         if (hfinfo->display == BASE_CUSTOM) {
8960                 gchar tmp[ITEM_LABEL_LENGTH];
8961                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
8962
8963                 DISSECTOR_ASSERT(fmtfunc);
8964                 fmtfunc(tmp, value);
8965                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
8966         }
8967         else if (hfinfo->strings) {
8968                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
8969
8970                 out = hfinfo_number_vals_format(hfinfo, buf, value);
8971                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
8972                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
8973                 else
8974                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
8975         }
8976         else {
8977                 out = hfinfo_number_value_format(hfinfo, buf, value);
8978
8979                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
8980         }
8981 }
8982
8983 static void
8984 fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed)
8985 {
8986         char       *p;
8987         int         bitfield_byte_length;
8988         guint64     unshifted_value;
8989         guint64     value;
8990
8991         char        buf[48];
8992         const char *out;
8993
8994         header_field_info *hfinfo = fi->hfinfo;
8995
8996         /* Un-shift bits */
8997         if (is_signed) {
8998                 value = fvalue_get_sinteger64(&fi->value);
8999         } else {
9000                 value = fvalue_get_uinteger64(&fi->value);
9001         }
9002         unshifted_value = value;
9003         if (hfinfo->bitmask) {
9004                 unshifted_value <<= hfinfo_bitshift(hfinfo);
9005         }
9006
9007         /* Create the bitfield first */
9008         p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
9009         bitfield_byte_length = (int) (p - label_str);
9010
9011         /* Fill in the textual info using stored (shifted) value */
9012         if (hfinfo->display == BASE_CUSTOM) {
9013                 gchar tmp[ITEM_LABEL_LENGTH];
9014                 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9015
9016                 DISSECTOR_ASSERT(fmtfunc64);
9017                 fmtfunc64(tmp, value);
9018                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9019         }
9020         else if (hfinfo->strings) {
9021                 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
9022
9023                 out = hfinfo_number_vals_format64(hfinfo, buf, value);
9024                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9025                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9026                 else
9027                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9028         }
9029         else {
9030                 out = hfinfo_number_value_format64(hfinfo, buf, value);
9031
9032                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
9033         }
9034 }
9035
9036 static void
9037 fill_label_char(field_info *fi, gchar *label_str)
9038 {
9039         header_field_info *hfinfo = fi->hfinfo;
9040         guint32            value;
9041
9042         char               buf[32];
9043         const char        *out;
9044
9045         value = fvalue_get_uinteger(&fi->value);
9046
9047         /* Fill in the textual info */
9048         if (hfinfo->display == BASE_CUSTOM) {
9049                 gchar tmp[ITEM_LABEL_LENGTH];
9050                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9051
9052                 DISSECTOR_ASSERT(fmtfunc);
9053                 fmtfunc(tmp, value);
9054                 label_fill(label_str, 0, hfinfo, tmp);
9055         }
9056         else if (hfinfo->strings) {
9057                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9058
9059                 out = hfinfo_char_vals_format(hfinfo, buf, value);
9060                 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9061         }
9062         else {
9063                 out = hfinfo_char_value_format(hfinfo, buf, value);
9064
9065                 label_fill(label_str, 0, hfinfo, out);
9066         }
9067 }
9068
9069 static void
9070 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
9071 {
9072         header_field_info *hfinfo = fi->hfinfo;
9073         guint32            value;
9074
9075         char               buf[32];
9076         const char        *out;
9077
9078         if (is_signed)
9079                 value = fvalue_get_sinteger(&fi->value);
9080         else
9081                 value = fvalue_get_uinteger(&fi->value);
9082
9083         /* Fill in the textual info */
9084         if (hfinfo->display == BASE_CUSTOM) {
9085                 gchar tmp[ITEM_LABEL_LENGTH];
9086                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9087
9088                 DISSECTOR_ASSERT(fmtfunc);
9089                 fmtfunc(tmp, value);
9090                 label_fill(label_str, 0, hfinfo, tmp);
9091         }
9092         else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
9093                 /*
9094                  * It makes no sense to have a value-string table for a
9095                  * frame-number field - they're just integers giving
9096                  * the ordinal frame number.
9097                  */
9098                 const char *val_str = hf_try_val_to_str(value, hfinfo);
9099
9100                 out = hfinfo_number_vals_format(hfinfo, buf, value);
9101                 if (hfinfo->display & BASE_SPECIAL_VALS) {
9102                         /*
9103                          * Unique values only display value_string string
9104                          * if there is a match.  Otherwise it's just a number
9105                          */
9106                         if (val_str) {
9107                                 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9108                         } else {
9109                                 label_fill(label_str, 0, hfinfo, out);
9110                         }
9111                 } else {
9112                         if (val_str == NULL)
9113                                 val_str = "Unknown";
9114
9115                         if (out == NULL) /* BASE_NONE so don't put integer in descr */
9116                                 label_fill(label_str, 0, hfinfo, val_str);
9117                         else
9118                                 label_fill_descr(label_str, 0, hfinfo, val_str, out);
9119                 }
9120         }
9121         else if (IS_BASE_PORT(hfinfo->display)) {
9122                 gchar tmp[ITEM_LABEL_LENGTH];
9123
9124                 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
9125                         display_to_port_type((field_display_e)hfinfo->display), value);
9126                 label_fill(label_str, 0, hfinfo, tmp);
9127         }
9128         else {
9129                 out = hfinfo_number_value_format(hfinfo, buf, value);
9130
9131                 label_fill(label_str, 0, hfinfo, out);
9132         }
9133 }
9134
9135 static void
9136 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
9137 {
9138         header_field_info *hfinfo = fi->hfinfo;
9139         guint64            value;
9140
9141         char               buf[48];
9142         const char        *out;
9143
9144         if (is_signed)
9145                 value = fvalue_get_sinteger64(&fi->value);
9146         else
9147                 value = fvalue_get_uinteger64(&fi->value);
9148
9149         /* Fill in the textual info */
9150         if (hfinfo->display == BASE_CUSTOM) {
9151                 gchar tmp[ITEM_LABEL_LENGTH];
9152                 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9153
9154                 DISSECTOR_ASSERT(fmtfunc64);
9155                 fmtfunc64(tmp, value);
9156                 label_fill(label_str, 0, hfinfo, tmp);
9157         }
9158         else if (hfinfo->strings) {
9159                 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
9160
9161                 out = hfinfo_number_vals_format64(hfinfo, buf, value);
9162                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
9163                         label_fill(label_str, 0, hfinfo, val_str);
9164                 else
9165                         label_fill_descr(label_str, 0, hfinfo, val_str, out);
9166         }
9167         else {
9168                 out = hfinfo_number_value_format64(hfinfo, buf, value);
9169
9170                 label_fill(label_str, 0, hfinfo, out);
9171         }
9172 }
9173
9174 int
9175 hfinfo_bitshift(const header_field_info *hfinfo)
9176 {
9177         return ws_ctz(hfinfo->bitmask);
9178 }
9179
9180 static int
9181 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
9182 {
9183         if (!hfinfo->bitmask) {
9184                 return 0;
9185         }
9186
9187         /* ilog2 = first set bit, ctz = last set bit */
9188         return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
9189 }
9190
9191 static int
9192 hfinfo_type_bitwidth(enum ftenum type)
9193 {
9194         int bitwidth = 0;
9195
9196         switch (type) {
9197                 case FT_CHAR:
9198                 case FT_UINT8:
9199                 case FT_INT8:
9200                         bitwidth = 8;
9201                         break;
9202                 case FT_UINT16:
9203                 case FT_INT16:
9204                         bitwidth = 16;
9205                         break;
9206                 case FT_UINT24:
9207                 case FT_INT24:
9208                         bitwidth = 24;
9209                         break;
9210                 case FT_UINT32:
9211                 case FT_INT32:
9212                         bitwidth = 32;
9213                         break;
9214                 case FT_UINT40:
9215                 case FT_INT40:
9216                         bitwidth = 40;
9217                         break;
9218                 case FT_UINT48:
9219                 case FT_INT48:
9220                         bitwidth = 48;
9221                         break;
9222                 case FT_UINT56:
9223                 case FT_INT56:
9224                         bitwidth = 56;
9225                         break;
9226                 case FT_UINT64:
9227                 case FT_INT64:
9228                         bitwidth = 64;
9229                         break;
9230                 default:
9231                         DISSECTOR_ASSERT_NOT_REACHED();
9232                         ;
9233         }
9234         return bitwidth;
9235 }
9236
9237
9238 static int
9239 hfinfo_container_bitwidth(const header_field_info *hfinfo)
9240 {
9241         if (!hfinfo->bitmask) {
9242                 return 0;
9243         }
9244
9245         if (hfinfo->type == FT_BOOLEAN) {
9246                 return hfinfo->display; /* hacky? :) */
9247         }
9248
9249         return hfinfo_type_bitwidth(hfinfo->type);
9250 }
9251
9252 static int
9253 hfinfo_hex_digits(const header_field_info *hfinfo)
9254 {
9255         int bitwidth;
9256
9257         /* If we have a bitmask, hfinfo->type is the width of the container, so not
9258          * appropriate to determine the number of hex digits for the field.
9259          * So instead, we compute it from the bitmask.
9260          */
9261         if (hfinfo->bitmask != 0) {
9262                 bitwidth = hfinfo_mask_bitwidth(hfinfo);
9263         } else {
9264                 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
9265         }
9266
9267         /* Divide by 4, rounding up, to get number of hex digits. */
9268         return (bitwidth + 3) / 4;
9269 }
9270
9271 static const char *
9272 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
9273 {
9274         char *ptr = &buf[6];
9275         static const gchar hex_digits[16] =
9276         { '0', '1', '2', '3', '4', '5', '6', '7',
9277           '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
9278
9279         *ptr = '\0';
9280         *(--ptr) = '\'';
9281         /* Properly format value */
9282         if (g_ascii_isprint(value)) {
9283                 /*
9284                  * Printable, so just show the character, and, if it needs
9285                  * to be escaped, escape it.
9286                  */
9287                 *(--ptr) = value;
9288                 if (value == '\\' || value == '\'')
9289                         *(--ptr) = '\\';
9290         } else {
9291                 /*
9292                  * Non-printable; show it as an escape sequence.
9293                  */
9294                 switch (value) {
9295
9296                 case '\0':
9297                         /*
9298                          * Show a NUL with only one digit.
9299                          */
9300                         *(--ptr) = '0';
9301                         break;
9302
9303                 case '\a':
9304                         *(--ptr) = 'a';
9305                         break;
9306
9307                 case '\b':
9308                         *(--ptr) = 'b';
9309                         break;
9310
9311                 case '\f':
9312                         *(--ptr) = 'f';
9313                         break;
9314
9315                 case '\n':
9316                         *(--ptr) = 'n';
9317                         break;
9318
9319                 case '\r':
9320                         *(--ptr) = 'r';
9321                         break;
9322
9323                 case '\t':
9324                         *(--ptr) = 't';
9325                         break;
9326
9327                 case '\v':
9328                         *(--ptr) = 'v';
9329                         break;
9330
9331                 default:
9332                         switch (FIELD_DISPLAY(display)) {
9333
9334                         case BASE_OCT:
9335                                 *(--ptr) = (value & 0x7) + '0';
9336                                 value >>= 3;
9337                                 *(--ptr) = (value & 0x7) + '0';
9338                                 value >>= 3;
9339                                 *(--ptr) = (value & 0x7) + '0';
9340                                 break;
9341
9342                         case BASE_HEX:
9343                                 *(--ptr) = hex_digits[value & 0x0F];
9344                                 value >>= 4;
9345                                 *(--ptr) = hex_digits[value & 0x0F];
9346                                 *(--ptr) = 'x';
9347                                 break;
9348
9349                         default:
9350                                 g_assert_not_reached();
9351                         }
9352                 }
9353                 *(--ptr) = '\\';
9354         }
9355         *(--ptr) = '\'';
9356         return ptr;
9357 }
9358
9359 static const char *
9360 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
9361 {
9362         char *ptr = &buf[31];
9363         gboolean isint = IS_FT_INT(hfinfo->type);
9364
9365         *ptr = '\0';
9366         /* Properly format value */
9367         switch (FIELD_DISPLAY(display)) {
9368                 case BASE_DEC:
9369                         return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
9370
9371                 case BASE_DEC_HEX:
9372                         *(--ptr) = ')';
9373                         ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9374                         *(--ptr) = '(';
9375                         *(--ptr) = ' ';
9376                         ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
9377                         return ptr;
9378
9379                 case BASE_OCT:
9380                         return oct_to_str_back(ptr, value);
9381
9382                 case BASE_HEX:
9383                         return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9384
9385                 case BASE_HEX_DEC:
9386                         *(--ptr) = ')';
9387                         ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
9388                         *(--ptr) = '(';
9389                         *(--ptr) = ' ';
9390                         ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9391                         return ptr;
9392
9393                 case BASE_PT_UDP:
9394                 case BASE_PT_TCP:
9395                 case BASE_PT_DCCP:
9396                 case BASE_PT_SCTP:
9397                         port_with_resolution_to_str_buf(buf, 32,
9398                                         display_to_port_type((field_display_e)display), value);
9399                         return buf;
9400                 case BASE_OUI:
9401                         {
9402                         guint8 p_oui[3];
9403                         const gchar *manuf_name;
9404
9405                         p_oui[0] = value >> 16 & 0xFF;
9406                         p_oui[1] = value >> 8 & 0xFF;
9407                         p_oui[2] = value & 0xFF;
9408
9409                         /* Attempt an OUI lookup. */
9410                         manuf_name = uint_get_manuf_name_if_known(value);
9411                         if (manuf_name == NULL) {
9412                                 /* Could not find an OUI. */
9413                                 g_snprintf(buf, 32, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
9414                         }
9415                         else {
9416                                 /* Found an address string. */
9417                                 g_snprintf(buf, 32, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
9418                         }
9419                         return buf;
9420                         }
9421
9422                 default:
9423                         g_assert_not_reached();
9424         }
9425         return ptr;
9426 }
9427
9428 static const char *
9429 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
9430 {
9431         char *ptr = &buf[47];
9432         gboolean isint = IS_FT_INT(hfinfo->type);
9433
9434         *ptr = '\0';
9435         /* Properly format value */
9436         switch (FIELD_DISPLAY(display)) {
9437                 case BASE_DEC:
9438                         return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
9439
9440                 case BASE_DEC_HEX:
9441                         *(--ptr) = ')';
9442                         ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9443                         *(--ptr) = '(';
9444                         *(--ptr) = ' ';
9445                         ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
9446                         return ptr;
9447
9448                 case BASE_OCT:
9449                         return oct64_to_str_back(ptr, value);
9450
9451                 case BASE_HEX:
9452                         return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9453
9454                 case BASE_HEX_DEC:
9455                         *(--ptr) = ')';
9456                         ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
9457                         *(--ptr) = '(';
9458                         *(--ptr) = ' ';
9459                         ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
9460                         return ptr;
9461
9462                 default:
9463                         g_assert_not_reached();
9464         }
9465
9466         return ptr;
9467 }
9468
9469 static const char *
9470 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9471 {
9472         int display = hfinfo->display;
9473
9474         if (hfinfo->type == FT_FRAMENUM) {
9475                 /*
9476                  * Frame numbers are always displayed in decimal.
9477                  */
9478                 display = BASE_DEC;
9479         }
9480
9481         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
9482 }
9483
9484 static const char *
9485 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
9486 {
9487         int display = hfinfo->display;
9488
9489         if (hfinfo->type == FT_FRAMENUM) {
9490                 /*
9491                  * Frame numbers are always displayed in decimal.
9492                  */
9493                 display = BASE_DEC;
9494         }
9495
9496         return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
9497 }
9498
9499 static const char *
9500 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9501 {
9502         /* Get the underlying BASE_ value */
9503         int display = FIELD_DISPLAY(hfinfo->display);
9504
9505         return hfinfo_char_value_format_display(display, buf, value);
9506 }
9507
9508 static const char *
9509 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9510 {
9511         /* Get the underlying BASE_ value */
9512         int display = FIELD_DISPLAY(hfinfo->display);
9513
9514         if (hfinfo->type == FT_FRAMENUM) {
9515                 /*
9516                  * Frame numbers are always displayed in decimal.
9517                  */
9518                 display = BASE_DEC;
9519         }
9520
9521         if (IS_BASE_PORT(display)) {
9522                 display = BASE_DEC;
9523         } else if (display == BASE_OUI) {
9524                 display = BASE_HEX;
9525         }
9526
9527         switch (display) {
9528                 case BASE_NONE:
9529                 /* case BASE_DEC: */
9530                 case BASE_DEC_HEX:
9531                 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
9532                 case BASE_CUSTOM:
9533                         display = BASE_DEC;
9534                         break;
9535
9536                 /* case BASE_HEX: */
9537                 case BASE_HEX_DEC:
9538                         display = BASE_HEX;
9539                         break;
9540         }
9541
9542         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
9543 }
9544
9545 static const char *
9546 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
9547 {
9548         /* Get the underlying BASE_ value */
9549         int display = FIELD_DISPLAY(hfinfo->display);
9550
9551         if (hfinfo->type == FT_FRAMENUM) {
9552                 /*
9553                  * Frame numbers are always displayed in decimal.
9554                  */
9555                 display = BASE_DEC;
9556         }
9557
9558         switch (display) {
9559                 case BASE_NONE:
9560                 /* case BASE_DEC: */
9561                 case BASE_DEC_HEX:
9562                 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
9563                 case BASE_CUSTOM:
9564                         display = BASE_DEC;
9565                         break;
9566
9567                 /* case BASE_HEX: */
9568                 case BASE_HEX_DEC:
9569                         display = BASE_HEX;
9570                         break;
9571         }
9572
9573         return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
9574 }
9575
9576 static const char *
9577 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9578 {
9579         /* Get the underlying BASE_ value */
9580         int display = FIELD_DISPLAY(hfinfo->display);
9581
9582         return hfinfo_char_value_format_display(display, buf, value);
9583 }
9584
9585 static const char *
9586 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
9587 {
9588         /* Get the underlying BASE_ value */
9589         int display = FIELD_DISPLAY(hfinfo->display);
9590
9591         if (display == BASE_NONE)
9592                 return NULL;
9593
9594         if (display == BASE_DEC_HEX)
9595                 display = BASE_DEC;
9596         if (display == BASE_HEX_DEC)
9597                 display = BASE_HEX;
9598
9599         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
9600 }
9601
9602 static const char *
9603 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
9604 {
9605         /* Get the underlying BASE_ value */
9606         int display = FIELD_DISPLAY(hfinfo->display);
9607
9608         if (display == BASE_NONE)
9609                 return NULL;
9610
9611         if (display == BASE_DEC_HEX)
9612                 display = BASE_DEC;
9613         if (display == BASE_HEX_DEC)
9614                 display = BASE_HEX;
9615
9616         return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
9617 }
9618
9619 const char *
9620 proto_registrar_get_name(const int n)
9621 {
9622         header_field_info *hfinfo;
9623
9624         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9625         return hfinfo->name;
9626 }
9627
9628 const char *
9629 proto_registrar_get_abbrev(const int n)
9630 {
9631         header_field_info *hfinfo;
9632
9633         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9634         return hfinfo->abbrev;
9635 }
9636
9637 enum ftenum
9638 proto_registrar_get_ftype(const int n)
9639 {
9640         header_field_info *hfinfo;
9641
9642         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9643         return hfinfo->type;
9644 }
9645
9646 int
9647 proto_registrar_get_parent(const int n)
9648 {
9649         header_field_info *hfinfo;
9650
9651         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9652         return hfinfo->parent;
9653 }
9654
9655 gboolean
9656 proto_registrar_is_protocol(const int n)
9657 {
9658         header_field_info *hfinfo;
9659
9660         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9661         return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
9662 }
9663
9664 /* Returns length of field in packet (not necessarily the length
9665  * in our internal representation, as in the case of IPv4).
9666  * 0 means undeterminable at time of registration
9667  * -1 means the field is not registered. */
9668 gint
9669 proto_registrar_get_length(const int n)
9670 {
9671         header_field_info *hfinfo;
9672
9673         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
9674         return ftype_length(hfinfo->type);
9675 }
9676
9677 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
9678  * it exists anywhere, or FALSE if it exists nowhere. */
9679 gboolean
9680 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
9681 {
9682         GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
9683
9684         if (g_ptr_array_len(ptrs) > 0) {
9685                 return TRUE;
9686         }
9687         else {
9688                 return FALSE;
9689         }
9690 }
9691
9692 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
9693  * This only works if the hfindex was "primed" before the dissection
9694  * took place, as we just pass back the already-created GPtrArray*.
9695  * The caller should *not* free the GPtrArray*; proto_tree_free_node()
9696  * handles that. */
9697 GPtrArray *
9698 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
9699 {
9700         if (!tree)
9701                 return NULL;
9702
9703         if (PTREE_DATA(tree)->interesting_hfids != NULL)
9704                 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
9705                                            GINT_TO_POINTER(id));
9706         else
9707                 return NULL;
9708 }
9709
9710 gboolean
9711 proto_tracking_interesting_fields(const proto_tree *tree)
9712 {
9713         GHashTable *interesting_hfids;
9714
9715         if (!tree)
9716                 return FALSE;
9717
9718         interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
9719
9720         return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
9721 }
9722
9723 /* Helper struct for proto_find_info() and      proto_all_finfos() */
9724 typedef struct {
9725         GPtrArray *array;
9726         int        id;
9727 } ffdata_t;
9728
9729 /* Helper function for proto_find_info() */
9730 static gboolean
9731 find_finfo(proto_node *node, gpointer data)
9732 {
9733         field_info *fi = PNODE_FINFO(node);
9734         if (fi && fi->hfinfo) {
9735                 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
9736                         g_ptr_array_add(((ffdata_t*)data)->array, fi);
9737                 }
9738         }
9739
9740         /* Don't stop traversing. */
9741         return FALSE;
9742 }
9743
9744 /* Helper function for proto_find_first_info() */
9745 static gboolean
9746 find_first_finfo(proto_node *node, gpointer data)
9747 {
9748         field_info *fi = PNODE_FINFO(node);
9749         if (fi && fi->hfinfo) {
9750                 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
9751                         g_ptr_array_add(((ffdata_t*)data)->array, fi);
9752
9753                         /* Stop traversing. */
9754                         return TRUE;
9755                 }
9756         }
9757
9758         /* Continue traversing. */
9759         return FALSE;
9760 }
9761
9762 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
9763 * This works on any proto_tree, primed or unprimed, but actually searches
9764 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
9765 * The caller does need to free the returned GPtrArray with
9766 * g_ptr_array_free(<array>, TRUE).
9767 */
9768 GPtrArray *
9769 proto_find_finfo(proto_tree *tree, const int id)
9770 {
9771         ffdata_t ffdata;
9772
9773         ffdata.array = g_ptr_array_new();
9774         ffdata.id = id;
9775
9776         proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
9777
9778         return ffdata.array;
9779 }
9780
9781 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
9782 * This works on any proto_tree, primed or unprimed, but actually searches
9783 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
9784 * The caller does need to free the returned GPtrArray with
9785 * g_ptr_array_free(<array>, TRUE).
9786 */
9787 GPtrArray *
9788 proto_find_first_finfo(proto_tree *tree, const int id)
9789 {
9790         ffdata_t ffdata;
9791
9792         ffdata.array = g_ptr_array_new();
9793         ffdata.id = id;
9794
9795         proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
9796
9797         return ffdata.array;
9798 }
9799
9800 /* Helper function for proto_all_finfos() */
9801 static gboolean
9802 every_finfo(proto_node *node, gpointer data)
9803 {
9804         field_info *fi = PNODE_FINFO(node);
9805         if (fi && fi->hfinfo) {
9806                 g_ptr_array_add(((ffdata_t*)data)->array, fi);
9807         }
9808
9809         /* Don't stop traversing. */
9810         return FALSE;
9811 }
9812
9813 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
9814 GPtrArray *
9815 proto_all_finfos(proto_tree *tree)
9816 {
9817         ffdata_t ffdata;
9818
9819         /* Pre allocate enough space to hold all fields in most cases */
9820         ffdata.array = g_ptr_array_sized_new(512);
9821         ffdata.id = 0;
9822
9823         proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
9824
9825         return ffdata.array;
9826 }
9827
9828
9829 typedef struct {
9830         guint       offset;
9831         field_info *finfo;
9832         tvbuff_t   *tvb;
9833 } offset_search_t;
9834
9835 static gboolean
9836 check_for_offset(proto_node *node, gpointer data)
9837 {
9838         field_info      *fi        = PNODE_FINFO(node);
9839         offset_search_t *offsearch = (offset_search_t *)data;
9840
9841         /* !fi == the top most container node which holds nothing */
9842         if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
9843                 if (offsearch->offset >= (guint) fi->start &&
9844                                 offsearch->offset < (guint) (fi->start + fi->length)) {
9845
9846                         offsearch->finfo = fi;
9847                         return FALSE; /* keep traversing */
9848                 }
9849         }
9850         return FALSE; /* keep traversing */
9851 }
9852
9853 /* Search a proto_tree backwards (from leaves to root) looking for the field
9854  * whose start/length occupies 'offset' */
9855 /* XXX - I couldn't find an easy way to search backwards, so I search
9856  * forwards, w/o stopping. Therefore, the last finfo I find will the be
9857  * the one I want to return to the user. This algorithm is inefficient
9858  * and could be re-done, but I'd have to handle all the children and
9859  * siblings of each node myself. When I have more time I'll do that.
9860  * (yeah right) */
9861 field_info *
9862 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
9863 {
9864         offset_search_t offsearch;
9865
9866         offsearch.offset = offset;
9867         offsearch.finfo  = NULL;
9868         offsearch.tvb    = tvb;
9869
9870         proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
9871
9872         return offsearch.finfo;
9873 }
9874
9875 typedef struct {
9876         gint length;
9877         gchar *buf;
9878 } decoded_data_t;
9879
9880 static gboolean
9881 check_for_undecoded(proto_node *node, gpointer data)
9882 {
9883         field_info *fi = PNODE_FINFO(node);
9884         decoded_data_t* decoded = (decoded_data_t*)data;
9885         gint i;
9886         guint byte;
9887         guint bit;
9888
9889         if (fi && fi->hfinfo->type != FT_PROTOCOL) {
9890                 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
9891                         byte = i / 8;
9892                         bit = i % 8;
9893                         decoded->buf[byte] |= (1 << bit);
9894                 }
9895         }
9896
9897         return FALSE;
9898 }
9899
9900 gchar*
9901 proto_find_undecoded_data(proto_tree *tree, guint length)
9902 {
9903         decoded_data_t decoded;
9904         decoded.length = length;
9905         decoded.buf = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
9906
9907         proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
9908         return decoded.buf;
9909 }
9910
9911 /* Dumps the protocols in the registration database to stdout.  An independent
9912  * program can take this output and format it into nice tables or HTML or
9913  * whatever.
9914  *
9915  * There is one record per line. The fields are tab-delimited.
9916  *
9917  * Field 1 = protocol name
9918  * Field 2 = protocol short name
9919  * Field 3 = protocol filter name
9920  */
9921 void
9922 proto_registrar_dump_protocols(void)
9923 {
9924         protocol_t *protocol;
9925         int         i;
9926         void       *cookie = NULL;
9927
9928
9929         i = proto_get_first_protocol(&cookie);
9930         while (i != -1) {
9931                 protocol = find_protocol_by_id(i);
9932                 ws_debug_printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
9933                         protocol->filter_name);
9934                 i = proto_get_next_protocol(&cookie);
9935         }
9936 }
9937
9938 /* Dumps the value_strings, extended value string headers, range_strings
9939  * or true/false strings for fields that have them.
9940  * There is one record per line. Fields are tab-delimited.
9941  * There are four types of records: Value String, Extended Value String Header,
9942  * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
9943  * the type of record.
9944  *
9945  * Note that a record will be generated only if the value_string,... is referenced
9946  * in a registered hfinfo entry.
9947  *
9948  *
9949  * Value Strings
9950  * -------------
9951  * Field 1 = 'V'
9952  * Field 2 = Field abbreviation to which this value string corresponds
9953  * Field 3 = Integer value
9954  * Field 4 = String
9955  *
9956  * Extended Value String Headers
9957  * -----------------------------
9958  * Field 1 = 'E'
9959  * Field 2 = Field abbreviation to which this extended value string header corresponds
9960  * Field 3 = Extended Value String "Name"
9961  * Field 4 = Number of entries in the associated value_string array
9962  * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
9963  *
9964  * Range Strings
9965  * -------------
9966  * Field 1 = 'R'
9967  * Field 2 = Field abbreviation to which this range string corresponds
9968  * Field 3 = Integer value: lower bound
9969  * Field 4 = Integer value: upper bound
9970  * Field 5 = String
9971  *
9972  * True/False Strings
9973  * ------------------
9974  * Field 1 = 'T'
9975  * Field 2 = Field abbreviation to which this true/false string corresponds
9976  * Field 3 = True String
9977  * Field 4 = False String
9978  */
9979 void
9980 proto_registrar_dump_values(void)
9981 {
9982         header_field_info       *hfinfo;
9983         int                     i, len, vi;
9984         const value_string      *vals;
9985         const val64_string      *vals64;
9986         const range_string      *range;
9987         const true_false_string *tfs;
9988         const unit_name_string  *units;
9989
9990         len = gpa_hfinfo.len;
9991         for (i = 0; i < len ; i++) {
9992                 if (gpa_hfinfo.hfi[i] == NULL)
9993                         continue; /* This is a deregistered protocol or field */
9994
9995                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
9996
9997                 if (hfinfo->id == hf_text_only) {
9998                         continue;
9999                 }
10000
10001                 /* ignore protocols */
10002                 if (proto_registrar_is_protocol(i)) {
10003                         continue;
10004                 }
10005                 /* process header fields */
10006 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
10007                 /*
10008                  * If this field isn't at the head of the list of
10009                  * fields with this name, skip this field - all
10010                  * fields with the same name are really just versions
10011                  * of the same field stored in different bits, and
10012                  * should have the same type/radix/value list, and
10013                  * just differ in their bit masks.      (If a field isn't
10014                  * a bitfield, but can be, say, 1 or 2 bytes long,
10015                  * it can just be made FT_UINT16, meaning the
10016                  * *maximum* length is 2 bytes, and be used
10017                  * for all lengths.)
10018                  */
10019                 if (hfinfo->same_name_prev_id != -1)
10020                         continue;
10021 #endif
10022                 vals   = NULL;
10023                 vals64 = NULL;
10024                 range  = NULL;
10025                 tfs    = NULL;
10026                 units  = NULL;
10027
10028                 if (hfinfo->strings != NULL) {
10029                         if (FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM &&
10030                             (hfinfo->type == FT_CHAR  ||
10031                              hfinfo->type == FT_UINT8  ||
10032                              hfinfo->type == FT_UINT16 ||
10033                              hfinfo->type == FT_UINT24 ||
10034                              hfinfo->type == FT_UINT32 ||
10035                              hfinfo->type == FT_UINT40 ||
10036                              hfinfo->type == FT_UINT48 ||
10037                              hfinfo->type == FT_UINT56 ||
10038                              hfinfo->type == FT_UINT64 ||
10039                              hfinfo->type == FT_INT8   ||
10040                              hfinfo->type == FT_INT16  ||
10041                              hfinfo->type == FT_INT24  ||
10042                              hfinfo->type == FT_INT32  ||
10043                              hfinfo->type == FT_INT40  ||
10044                              hfinfo->type == FT_INT48  ||
10045                              hfinfo->type == FT_INT56  ||
10046                              hfinfo->type == FT_INT64  ||
10047                              hfinfo->type == FT_FLOAT  ||
10048                              hfinfo->type == FT_DOUBLE)) {
10049
10050                                 if (hfinfo->display & BASE_RANGE_STRING) {
10051                                         range = (const range_string *)hfinfo->strings;
10052                                 } else if (hfinfo->display & BASE_EXT_STRING) {
10053                                         vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
10054                                 } else if (hfinfo->display & BASE_VAL64_STRING) {
10055                                         vals64 = (const val64_string *)hfinfo->strings;
10056                                 } else if (hfinfo->display & BASE_UNIT_STRING) {
10057                                         units = (const unit_name_string *)hfinfo->strings;
10058                                 } else {
10059                                         vals = (const value_string *)hfinfo->strings;
10060                                 }
10061                         }
10062                         else if (hfinfo->type == FT_BOOLEAN) {
10063                                 tfs = (const struct true_false_string *)hfinfo->strings;
10064                         }
10065                 }
10066
10067                 /* Print value strings? */
10068                 if (vals) {
10069                         if (hfinfo->display & BASE_EXT_STRING) {
10070                                 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
10071                                 if (!value_string_ext_validate(vse_p)) {
10072                                         ws_g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
10073                                         continue;
10074                                 }
10075                                 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
10076                                 ws_debug_printf("E\t%s\t%u\t%s\t%s\n",
10077                                        hfinfo->abbrev,
10078                                        VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
10079                                        VALUE_STRING_EXT_VS_NAME(vse_p),
10080                                        value_string_ext_match_type_str(vse_p));
10081                         }
10082                         vi = 0;
10083                         while (vals[vi].strptr) {
10084                                 /* Print in the proper base */
10085                                 if (hfinfo->type == FT_CHAR) {
10086                                         if (g_ascii_isprint(vals[vi].value)) {
10087                                                 ws_debug_printf("V\t%s\t'%c'\t%s\n",
10088                                                        hfinfo->abbrev,
10089                                                        vals[vi].value,
10090                                                        vals[vi].strptr);
10091                                         } else {
10092                                                 if (hfinfo->display == BASE_HEX) {
10093                                                         ws_debug_printf("V\t%s\t'\\x%02x'\t%s\n",
10094                                                                hfinfo->abbrev,
10095                                                                vals[vi].value,
10096                                                                vals[vi].strptr);
10097                                                 }
10098                                                 else {
10099                                                         ws_debug_printf("V\t%s\t'\\%03o'\t%s\n",
10100                                                                hfinfo->abbrev,
10101                                                                vals[vi].value,
10102                                                                vals[vi].strptr);
10103                                                 }
10104                                         }
10105                                 } else {
10106                                         if (hfinfo->display == BASE_HEX) {
10107                                                 ws_debug_printf("V\t%s\t0x%x\t%s\n",
10108                                                        hfinfo->abbrev,
10109                                                        vals[vi].value,
10110                                                        vals[vi].strptr);
10111                                         }
10112                                         else {
10113                                                 ws_debug_printf("V\t%s\t%u\t%s\n",
10114                                                        hfinfo->abbrev,
10115                                                        vals[vi].value,
10116                                                        vals[vi].strptr);
10117                                         }
10118                                 }
10119                                 vi++;
10120                         }
10121                 }
10122                 else if (vals64) {
10123                         vi = 0;
10124                         while (vals64[vi].strptr) {
10125                                 ws_debug_printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
10126                                        hfinfo->abbrev,
10127                                        vals64[vi].value,
10128                                        vals64[vi].strptr);
10129                                 vi++;
10130                         }
10131                 }
10132
10133                 /* print range strings? */
10134                 else if (range) {
10135                         vi = 0;
10136                         while (range[vi].strptr) {
10137                                 /* Print in the proper base */
10138                                 if (FIELD_DISPLAY(hfinfo->display) == BASE_HEX) {
10139                                         ws_debug_printf("R\t%s\t0x%x\t0x%x\t%s\n",
10140                                                hfinfo->abbrev,
10141                                                range[vi].value_min,
10142                                                range[vi].value_max,
10143                                                range[vi].strptr);
10144                                 }
10145                                 else {
10146                                         ws_debug_printf("R\t%s\t%u\t%u\t%s\n",
10147                                                hfinfo->abbrev,
10148                                                range[vi].value_min,
10149                                                range[vi].value_max,
10150                                                range[vi].strptr);
10151                                 }
10152                                 vi++;
10153                         }
10154                 }
10155
10156                 /* Print true/false strings? */
10157                 else if (tfs) {
10158                         ws_debug_printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
10159                                tfs->true_string, tfs->false_string);
10160                 }
10161                 /* Print unit strings? */
10162                 else if (units) {
10163                         ws_debug_printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
10164                                units->singular, units->plural ? units->plural : "(no plural)");
10165                 }
10166         }
10167 }
10168
10169 /* Prints the number of registered fields.
10170  * Useful for determining an appropriate value for
10171  * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
10172  *
10173  * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
10174  * the number of fields, TRUE otherwise.
10175  */
10176 gboolean
10177 proto_registrar_dump_fieldcount(void)
10178 {
10179         guint32                 i;
10180         header_field_info       *hfinfo;
10181         guint32                 deregistered_count = 0;
10182         guint32                 same_name_count = 0;
10183         guint32                 protocol_count = 0;
10184
10185         for (i = 0; i < gpa_hfinfo.len; i++) {
10186                 if (gpa_hfinfo.hfi[i] == NULL) {
10187                         deregistered_count++;
10188                         continue; /* This is a deregistered protocol or header field */
10189                 }
10190
10191                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10192
10193                 if (proto_registrar_is_protocol(i))
10194                         protocol_count++;
10195
10196                 if (hfinfo->same_name_prev_id != -1)
10197                         same_name_count++;
10198         }
10199
10200         ws_debug_printf("There are %u header fields registered, of which:\n"
10201                 "\t%u are deregistered\n"
10202                 "\t%u are protocols\n"
10203                 "\t%u have the same name as another field\n\n",
10204                 gpa_hfinfo.len, deregistered_count, protocol_count,
10205                 same_name_count);
10206
10207         ws_debug_printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
10208                 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
10209                     "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
10210                     "\n");
10211
10212         ws_debug_printf("The header field table consumes %u KiB of memory.\n",
10213                 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
10214         ws_debug_printf("The fields themselves consume %u KiB of memory.\n",
10215                 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
10216
10217         return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
10218 }
10219
10220 #ifdef HAVE_JSONGLIB
10221
10222 static JsonBuilder*
10223 elastic_add_base_mapping(JsonBuilder* builder)
10224 {
10225         json_builder_set_member_name(builder, "template");
10226         json_builder_add_string_value(builder, "packets-*");
10227
10228         json_builder_set_member_name(builder, "settings");
10229         json_builder_begin_object(builder);
10230         json_builder_set_member_name(builder, "index.mapping.total_fields.limit");
10231         json_builder_add_int_value(builder, 1000000);
10232         json_builder_end_object(builder);
10233
10234         return builder;
10235 }
10236
10237 gchar* ws_type_to_elastic(guint type _U_)
10238 {
10239         switch(type) {
10240                 case FT_UINT16:
10241                 case FT_INT16:
10242                 case FT_INT32:
10243                 case FT_UINT32:
10244                 case FT_UINT24:
10245                 case FT_FRAMENUM:
10246                 case FT_UINT48:
10247                 case FT_INT48:
10248                 case FT_INT24:
10249                         return "integer";
10250                 case FT_INT8:
10251                 case FT_UINT8:
10252                         return "short";
10253                 case FT_UINT40:
10254                 case FT_UINT56:
10255                 case FT_UINT64:
10256                 case FT_INT64:
10257                         return "long";
10258                 case FT_FLOAT:
10259                 case FT_DOUBLE:
10260                         return "float";
10261                 case FT_IPv6:
10262                 case FT_IPv4:
10263                         return "ip";
10264                 case FT_ABSOLUTE_TIME:
10265                 case FT_RELATIVE_TIME:
10266                         return "date";
10267                 case FT_BYTES:
10268                 case FT_UINT_BYTES:
10269                         return "byte";
10270                 case FT_BOOLEAN:
10271                         return "boolean";
10272                 case FT_NONE:
10273                 case FT_STRING:
10274                 case FT_ETHER:
10275                 case FT_GUID:
10276                 case FT_OID:
10277                 case FT_STRINGZ:
10278                 case FT_UINT_STRING:
10279                 case FT_CHAR:
10280                 case FT_AX25:
10281                 case FT_REL_OID:
10282                 case FT_IEEE_11073_SFLOAT:
10283                 case FT_IEEE_11073_FLOAT:
10284                 case FT_STRINGZPAD:
10285                 case FT_PROTOCOL:
10286                 case FT_EUI64:
10287                 case FT_IPXNET:
10288                 case FT_SYSTEM_ID:
10289                 case FT_FCWWN:
10290                 case FT_VINES:
10291                         return "string";
10292                 default:
10293                         DISSECTOR_ASSERT_NOT_REACHED();
10294         }
10295 }
10296
10297 static gchar*
10298 dot_to_underscore(gchar* str)
10299 {
10300         unsigned i;
10301         for (i = 0; i < strlen(str); i++) {
10302                 if (str[i] == '.')
10303                         str[i] = '_';
10304         }
10305         return str;
10306 }
10307
10308 /* Dumps a mapping file for ElasticSearch
10309  */
10310 void
10311 proto_registrar_dump_elastic(const gchar* filter)
10312 {
10313         header_field_info *hfinfo;
10314         header_field_info *parent_hfinfo;
10315         JsonGenerator* generator;
10316         JsonBuilder* builder;
10317         JsonNode* root;
10318         gsize length;
10319         guint i;
10320         gboolean open_object = TRUE;
10321         const char* prev_proto = NULL;
10322         gchar* data;
10323         gchar* str;
10324         gchar** protos = NULL;
10325         gchar* proto;
10326         gboolean found;
10327         guint j;
10328
10329         /* We have filtering protocols. Extract them. */
10330         if (filter) {
10331                 protos = g_strsplit(filter, ",", -1);
10332         }
10333
10334         /*
10335          * To help tracking down the json tree, objects have been appended with a comment:
10336          * n.label -> where n is the indentation level and label the name of the object
10337          */
10338
10339         builder = json_builder_new();
10340         json_builder_begin_object(builder); // 1.root
10341         builder = elastic_add_base_mapping(builder);
10342
10343         json_builder_set_member_name(builder, "mappings");
10344         json_builder_begin_object(builder); // 2.mappings
10345         json_builder_set_member_name(builder, "pcap_file");
10346
10347         json_builder_begin_object(builder); // 3.pcap_file
10348         json_builder_set_member_name(builder, "dynamic");
10349         json_builder_add_boolean_value(builder, FALSE);
10350
10351         json_builder_set_member_name(builder, "properties");
10352         json_builder_begin_object(builder); // 4.properties
10353         json_builder_set_member_name(builder, "timestamp");
10354         json_builder_begin_object(builder); // 5.timestamp
10355         json_builder_set_member_name(builder, "type");
10356         json_builder_add_string_value(builder, "date");
10357         json_builder_end_object(builder); // 5.timestamp
10358
10359         json_builder_set_member_name(builder, "layers");
10360         json_builder_begin_object(builder); // 5.layers
10361         json_builder_set_member_name(builder, "properties");
10362         json_builder_begin_object(builder); // 6.properties
10363
10364         for (i = 0; i < gpa_hfinfo.len; i++) {
10365                 if (gpa_hfinfo.hfi[i] == NULL)
10366                         continue; /* This is a deregistered protocol or header field */
10367
10368                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10369
10370                 /*
10371                  * Skip the pseudo-field for "proto_tree_add_text()" since
10372                  * we don't want it in the list of filterable protocols.
10373                  */
10374                 if (hfinfo->id == hf_text_only)
10375                         continue;
10376
10377                 if (!proto_registrar_is_protocol(i)) {
10378                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
10379
10380                         /*
10381                          * Skip the field if filter protocols have been set and this one's
10382                          * parent is not listed.
10383                          */
10384                         if (protos) {
10385                                 found = FALSE;
10386                                 j = 0;
10387                                 proto = protos[0];
10388                                 while(proto) {
10389                                         if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
10390                                                 found = TRUE;
10391                                                 break;
10392                                         }
10393                                         j++;
10394                                         proto = protos[j];
10395                                 }
10396                                 if (!found)
10397                                         continue;
10398                         }
10399
10400                         if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
10401                                 json_builder_end_object(builder); // 8.properties
10402                                 json_builder_end_object(builder); // 7.parent_hfinfo->abbrev
10403                                 open_object = TRUE;
10404                         }
10405
10406                         prev_proto = parent_hfinfo->abbrev;
10407
10408                         if (open_object) {
10409                                 json_builder_set_member_name(builder, parent_hfinfo->abbrev);
10410                                 json_builder_begin_object(builder); // 7.parent_hfinfo->abbrev
10411                                 json_builder_set_member_name(builder, "properties");
10412                                 json_builder_begin_object(builder); // 8.properties
10413                                 open_object = FALSE;
10414                         }
10415                         str = g_strdup(hfinfo->abbrev);
10416                         json_builder_set_member_name(builder, dot_to_underscore(str));
10417                         g_free(str);
10418                         json_builder_begin_object(builder); // 9.hfinfo->abbrev
10419                         json_builder_set_member_name(builder, "type");
10420                         json_builder_add_string_value(builder, ws_type_to_elastic(hfinfo->type));
10421                         json_builder_end_object(builder); // 9.hfinfo->abbrev
10422                 }
10423         }
10424
10425         if (prev_proto) {
10426                 json_builder_end_object(builder); // 8.properties
10427                 json_builder_end_object(builder); // 7.parent_hfinfo->abbrev
10428         }
10429
10430         json_builder_end_object(builder); // 6.properties
10431         json_builder_end_object(builder); // 5.layers
10432         json_builder_end_object(builder); // 4.properties
10433         json_builder_end_object(builder); // 3.pcap_file
10434         json_builder_end_object(builder); // 2.mappings
10435         DISSECTOR_ASSERT(json_builder_end_object(builder)); // 1.root
10436
10437         generator = json_generator_new();
10438         json_generator_set_pretty(generator, TRUE);
10439         root = json_builder_get_root(builder);
10440         json_generator_set_root(generator, root);
10441         json_node_free(root);
10442         g_object_unref(builder);
10443         data = json_generator_to_data(generator, &length);
10444         g_object_unref(generator);
10445         ws_debug_printf("%s\n", data);
10446         g_free(data);
10447         g_strfreev(protos);
10448 }
10449 #endif
10450
10451 /* Dumps the contents of the registration database to stdout. An independent
10452  * program can take this output and format it into nice tables or HTML or
10453  * whatever.
10454  *
10455  * There is one record per line. Each record is either a protocol or a header
10456  * field, differentiated by the first field. The fields are tab-delimited.
10457  *
10458  * Protocols
10459  * ---------
10460  * Field 1 = 'P'
10461  * Field 2 = descriptive protocol name
10462  * Field 3 = protocol abbreviation
10463  *
10464  * Header Fields
10465  * -------------
10466  * Field 1 = 'F'
10467  * Field 2 = descriptive field name
10468  * Field 3 = field abbreviation
10469  * Field 4 = type ( textual representation of the the ftenum type )
10470  * Field 5 = parent protocol abbreviation
10471  * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
10472  * Field 7 = bitmask: format: hex: 0x....
10473  * Field 8 = blurb describing field
10474  */
10475 void
10476 proto_registrar_dump_fields(void)
10477 {
10478         header_field_info *hfinfo, *parent_hfinfo;
10479         int                i, len;
10480         const char        *enum_name;
10481         const char        *base_name;
10482         const char        *blurb;
10483         char               width[5];
10484
10485         len = gpa_hfinfo.len;
10486         for (i = 0; i < len ; i++) {
10487                 if (gpa_hfinfo.hfi[i] == NULL)
10488                         continue; /* This is a deregistered protocol or header field */
10489
10490                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10491
10492                 /*
10493                  * Skip the pseudo-field for "proto_tree_add_text()" since
10494                  * we don't want it in the list of filterable fields.
10495                  */
10496                 if (hfinfo->id == hf_text_only)
10497                         continue;
10498
10499                 /* format for protocols */
10500                 if (proto_registrar_is_protocol(i)) {
10501                         ws_debug_printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
10502                 }
10503                 /* format for header fields */
10504                 else {
10505                         /*
10506                          * If this field isn't at the head of the list of
10507                          * fields with this name, skip this field - all
10508                          * fields with the same name are really just versions
10509                          * of the same field stored in different bits, and
10510                          * should have the same type/radix/value list, and
10511                          * just differ in their bit masks.      (If a field isn't
10512                          * a bitfield, but can be, say, 1 or 2 bytes long,
10513                          * it can just be made FT_UINT16, meaning the
10514                          * *maximum* length is 2 bytes, and be used
10515                          * for all lengths.)
10516                          */
10517                         if (hfinfo->same_name_prev_id != -1)
10518                                 continue;
10519
10520                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
10521
10522                         enum_name = ftype_name(hfinfo->type);
10523                         base_name = "";
10524
10525                         if (hfinfo->type == FT_CHAR  ||
10526                             hfinfo->type == FT_UINT8  ||
10527                             hfinfo->type == FT_UINT16 ||
10528                             hfinfo->type == FT_UINT24 ||
10529                             hfinfo->type == FT_UINT32 ||
10530                             hfinfo->type == FT_UINT40 ||
10531                             hfinfo->type == FT_UINT48 ||
10532                             hfinfo->type == FT_UINT56 ||
10533                             hfinfo->type == FT_UINT64 ||
10534                             hfinfo->type == FT_INT8   ||
10535                             hfinfo->type == FT_INT16  ||
10536                             hfinfo->type == FT_INT24  ||
10537                             hfinfo->type == FT_INT32  ||
10538                             hfinfo->type == FT_INT40 ||
10539                             hfinfo->type == FT_INT48 ||
10540                             hfinfo->type == FT_INT56 ||
10541                             hfinfo->type == FT_INT64) {
10542
10543                                 switch (FIELD_DISPLAY(hfinfo->display)) {
10544                                         case BASE_NONE:
10545                                         case BASE_DEC:
10546                                         case BASE_HEX:
10547                                         case BASE_OCT:
10548                                         case BASE_DEC_HEX:
10549                                         case BASE_HEX_DEC:
10550                                         case BASE_CUSTOM:
10551                                         case BASE_PT_UDP:
10552                                         case BASE_PT_TCP:
10553                                         case BASE_PT_DCCP:
10554                                         case BASE_PT_SCTP:
10555                                         case BASE_OUI:
10556                                                 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
10557                                                 break;
10558                                         default:
10559                                                 base_name = "????";
10560                                                 break;
10561                                 }
10562                         } else if (hfinfo->type == FT_BOOLEAN) {
10563                                 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
10564                                 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
10565                                 base_name = width;
10566                         }
10567
10568                         blurb = hfinfo->blurb;
10569                         if (blurb == NULL)
10570                                 blurb = "";
10571                         else if (strlen(blurb) == 0)
10572                                 blurb = "\"\"";
10573
10574                         ws_debug_printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
10575                                 hfinfo->name, hfinfo->abbrev, enum_name,
10576                                 parent_hfinfo->abbrev, base_name,
10577                                 hfinfo->bitmask, blurb);
10578                 }
10579         }
10580 }
10581
10582 /* Dumps field types and descriptive names to stdout. An independent
10583  * program can take this output and format it into nice tables or HTML or
10584  * whatever.
10585  *
10586  * There is one record per line. The fields are tab-delimited.
10587  *
10588  * Field 1 = field type name, e.g. FT_UINT8
10589  * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
10590  */
10591 void
10592 proto_registrar_dump_ftypes(void)
10593 {
10594         int fte;
10595
10596         for (fte = 0; fte < FT_NUM_TYPES; fte++) {
10597                 ws_debug_printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
10598         }
10599 }
10600
10601 /* This function indicates whether it's possible to construct a
10602  * "match selected" display filter string for the specified field,
10603  * returns an indication of whether it's possible, and, if it's
10604  * possible and "filter" is non-null, constructs the filter and
10605  * sets "*filter" to point to it.
10606  * You do not need to [g_]free() this string since it will be automatically
10607  * freed once the next packet is dissected.
10608  */
10609 static gboolean
10610 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
10611                                 char **filter)
10612 {
10613         header_field_info *hfinfo;
10614         int                abbrev_len;
10615         char              *ptr;
10616         int                buf_len;
10617         int                dfilter_len, i;
10618         gint               start, length, length_remaining;
10619         guint8             c;
10620         gchar              is_signed_num = FALSE;
10621
10622         if (!finfo)
10623                 return FALSE;
10624
10625         hfinfo     = finfo->hfinfo;
10626         DISSECTOR_ASSERT(hfinfo);
10627         abbrev_len = (int) strlen(hfinfo->abbrev);
10628
10629         if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
10630                 const gchar *str = NULL;
10631
10632                 switch (hfinfo->type) {
10633
10634                 case FT_INT8:
10635                 case FT_INT16:
10636                 case FT_INT24:
10637                 case FT_INT32:
10638                         str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
10639                         break;
10640
10641                 case FT_CHAR:
10642                 case FT_UINT8:
10643                 case FT_UINT16:
10644                 case FT_UINT24:
10645                 case FT_UINT32:
10646                         str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
10647                         break;
10648
10649                 default:
10650                         break;
10651                 }
10652
10653                 if (str != NULL && filter != NULL) {
10654                         *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
10655                         return TRUE;
10656                 }
10657         }
10658
10659         /*
10660          * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
10661          * functions for FT_UINT and FT_INT types, as we choose the base in
10662          * the string expression based on the display base of the field.
10663          *
10664          * Note that the base does matter, as this is also used for
10665          * the protocolinfo tap.
10666          *
10667          * It might be nice to use them in "proto_item_fill_label()"
10668          * as well, although, there, you'd have to deal with the base
10669          * *and* with resolved values for addresses.
10670          *
10671          * Perhaps we need two different val_to_string routines, one
10672          * to generate items for display filters and one to generate
10673          * strings for display, and pass to both of them the
10674          * "display" and "strings" values in the header_field_info
10675          * structure for the field, so they can get the base and,
10676          * if the field is Boolean or an enumerated integer type,
10677          * the tables used to generate human-readable values.
10678          */
10679         switch (hfinfo->type) {
10680
10681                 case FT_CHAR:
10682                         if (filter != NULL) {
10683                                 guint32 number;
10684
10685                                 char buf [48];
10686                                 const char *out;
10687
10688                                 number = fvalue_get_uinteger(&finfo->value);
10689
10690                                 out = hfinfo_char_value_format(hfinfo, buf, number);
10691
10692                                 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
10693                         }
10694                         break;
10695
10696                 case FT_INT8:
10697                 case FT_INT16:
10698                 case FT_INT24:
10699                 case FT_INT32:
10700                         is_signed_num = TRUE;
10701                         /* FALLTHRU */
10702                 case FT_UINT8:
10703                 case FT_UINT16:
10704                 case FT_UINT24:
10705                 case FT_UINT32:
10706                 case FT_FRAMENUM:
10707                         if (filter != NULL) {
10708                                 guint32 number;
10709
10710                                 char buf[32];
10711                                 const char *out;
10712
10713                                 if (is_signed_num)
10714                                         number = fvalue_get_sinteger(&finfo->value);
10715                                 else
10716                                         number = fvalue_get_uinteger(&finfo->value);
10717
10718                                 out = hfinfo_numeric_value_format(hfinfo, buf, number);
10719
10720                                 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
10721                         }
10722                         break;
10723
10724                 case FT_INT40:
10725                 case FT_INT48:
10726                 case FT_INT56:
10727                 case FT_INT64:
10728                         is_signed_num = TRUE;
10729                         /* FALLTHRU */
10730                 case FT_UINT40:
10731                 case FT_UINT48:
10732                 case FT_UINT56:
10733                 case FT_UINT64:
10734                         if (filter != NULL) {
10735                                 guint64 number;
10736
10737                                 char buf [48];
10738                                 const char *out;
10739
10740                                 if (is_signed_num)
10741                                         number = fvalue_get_sinteger64(&finfo->value);
10742                                 else
10743                                         number = fvalue_get_uinteger64(&finfo->value);
10744
10745                                 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
10746
10747                                 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
10748                         }
10749                         break;
10750
10751                 case FT_PROTOCOL:
10752                         if (filter != NULL)
10753                                 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
10754                         break;
10755
10756                 case FT_NONE:
10757                         /*
10758                          * If the length is 0, just match the name of the
10759                          * field.
10760                          *
10761                          * (Also check for negative values, just in case,
10762                          * as we'll cast it to an unsigned value later.)
10763                          */
10764                         length = finfo->length;
10765                         if (length == 0) {
10766                                 if (filter != NULL)
10767                                         *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
10768                                 break;
10769                         }
10770                         if (length < 0)
10771                                 return FALSE;
10772
10773                         /*
10774                          * This doesn't have a value, so we'd match
10775                          * on the raw bytes at this address.
10776                          *
10777                          * Should we be allowed to access to the raw bytes?
10778                          * If "edt" is NULL, the answer is "no".
10779                          */
10780                         if (edt == NULL)
10781                                 return FALSE;
10782
10783                         /*
10784                          * Is this field part of the raw frame tvbuff?
10785                          * If not, we can't use "frame[N:M]" to match
10786                          * it.
10787                          *
10788                          * XXX - should this be frame-relative, or
10789                          * protocol-relative?
10790                          *
10791                          * XXX - does this fallback for non-registered
10792                          * fields even make sense?
10793                          */
10794                         if (finfo->ds_tvb != edt->tvb)
10795                                 return FALSE;   /* you lose */
10796
10797                         /*
10798                          * Don't go past the end of that tvbuff.
10799                          */
10800                         length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
10801                         if (length > length_remaining)
10802                                 length = length_remaining;
10803                         if (length <= 0)
10804                                 return FALSE;
10805
10806                         if (filter != NULL) {
10807                                 start = finfo->start;
10808                                 buf_len = 32 + length * 3;
10809                                 *filter = (char *)wmem_alloc0(NULL, buf_len);
10810                                 ptr = *filter;
10811
10812                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
10813                                         "frame[%d:%d] == ", finfo->start, length);
10814                                 for (i=0; i<length; i++) {
10815                                         c = tvb_get_guint8(finfo->ds_tvb, start);
10816                                         start++;
10817                                         if (i == 0 ) {
10818                                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
10819                                         }
10820                                         else {
10821                                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
10822                                         }
10823                                 }
10824                         }
10825                         break;
10826
10827                 case FT_PCRE:
10828                         /* FT_PCRE never appears as a type for a registered field. It is
10829                          * only used internally. */
10830                         DISSECTOR_ASSERT_NOT_REACHED();
10831                         break;
10832
10833                 /* By default, use the fvalue's "to_string_repr" method. */
10834                 default:
10835                         /* Figure out the string length needed.
10836                          *      The ft_repr length.
10837                          *      4 bytes for " == ".
10838                          *      1 byte for trailing NUL.
10839                          */
10840                         if (filter != NULL) {
10841                                 char* str;
10842                                 dfilter_len = fvalue_string_repr_len(&finfo->value,
10843                                                 FTREPR_DFILTER, finfo->hfinfo->display);
10844                                 dfilter_len += abbrev_len + 4 + 1;
10845                                 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
10846
10847                                 /* Create the string */
10848                                 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
10849                                 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
10850                                 wmem_free(NULL, str);
10851                         }
10852                         break;
10853         }
10854
10855         return TRUE;
10856 }
10857
10858 /*
10859  * Returns TRUE if we can do a "match selected" on the field, FALSE
10860  * otherwise.
10861  */
10862 gboolean
10863 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
10864 {
10865         return construct_match_selected_string(finfo, edt, NULL);
10866 }
10867
10868 /* This function attempts to construct a "match selected" display filter
10869  * string for the specified field; if it can do so, it returns a pointer
10870  * to the string, otherwise it returns NULL.
10871  *
10872  * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
10873  */
10874 char *
10875 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
10876 {
10877         char *filter = NULL;
10878
10879         if (!construct_match_selected_string(finfo, edt, &filter))
10880         {
10881                 wmem_free(NULL, filter);
10882                 return NULL;
10883         }
10884         return filter;
10885 }
10886
10887 /* This function is common code for all proto_tree_add_bitmask... functions.
10888  */
10889
10890 static gboolean
10891 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
10892                             const int len, const gint ett, const int **fields,
10893                             const int flags, gboolean first,
10894                             gboolean use_parent_tree,
10895                             proto_tree* tree, guint64 value)
10896 {
10897         guint              bitshift;
10898         guint64            available_bits = 0;
10899         guint64            tmpval;
10900         header_field_info *hf;
10901         guint32            integer32;
10902         gint               no_of_bits;
10903
10904         if (len < 0 || len > 8)
10905                 g_assert_not_reached();
10906         bitshift = (8 - (guint)len)*8;
10907         available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
10908
10909         if (use_parent_tree == FALSE)
10910                 tree = proto_item_add_subtree(item, ett);
10911
10912         while (*fields) {
10913                 guint64 present_bits;
10914                 PROTO_REGISTRAR_GET_NTH(**fields,hf);
10915                 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
10916
10917                 /* Skip fields that aren't fully present */
10918                 present_bits = available_bits & hf->bitmask;
10919                 if (present_bits != hf->bitmask) {
10920                         fields++;
10921                         continue;
10922                 }
10923
10924                 switch (hf->type) {
10925                 case FT_CHAR:
10926                 case FT_UINT8:
10927                 case FT_UINT16:
10928                 case FT_UINT24:
10929                 case FT_UINT32:
10930                         proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
10931                         break;
10932
10933                 case FT_INT8:
10934                 case FT_INT16:
10935                 case FT_INT24:
10936                 case FT_INT32:
10937                         proto_tree_add_int(tree, **fields, tvb, offset, len, (gint32)value);
10938                         break;
10939
10940                 case FT_UINT40:
10941                 case FT_UINT48:
10942                 case FT_UINT56:
10943                 case FT_UINT64:
10944                         proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
10945                         break;
10946
10947                 case FT_INT40:
10948                 case FT_INT48:
10949                 case FT_INT56:
10950                 case FT_INT64:
10951                         proto_tree_add_int64(tree, **fields, tvb, offset, len, (gint64)value);
10952                         break;
10953
10954                 case FT_BOOLEAN:
10955                         proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
10956                         break;
10957
10958                 default:
10959                         DISSECTOR_ASSERT_NOT_REACHED();
10960                         break;
10961                 }
10962                 if (flags & BMT_NO_APPEND) {
10963                         fields++;
10964                         continue;
10965                 }
10966                 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
10967
10968                 switch (hf->type) {
10969                 case FT_CHAR:
10970                         if (hf->display == BASE_CUSTOM) {
10971                                 gchar lbl[ITEM_LABEL_LENGTH];
10972                                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
10973
10974                                 DISSECTOR_ASSERT(fmtfunc);
10975                                 fmtfunc(lbl, (guint32) tmpval);
10976                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10977                                                 hf->name, lbl);
10978                                 first = FALSE;
10979                         }
10980                         else if (hf->strings) {
10981                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
10982                                                        hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
10983                                 first = FALSE;
10984                         }
10985                         else if (!(flags & BMT_NO_INT)) {
10986                                 char buf[32];
10987                                 const char *out;
10988
10989                                 if (!first) {
10990                                         proto_item_append_text(item, ", ");
10991                                 }
10992
10993                                 out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
10994                                 proto_item_append_text(item, "%s: %s", hf->name, out);
10995                                 first = FALSE;
10996                         }
10997
10998                         break;
10999
11000                 case FT_UINT8:
11001                 case FT_UINT16:
11002                 case FT_UINT24:
11003                 case FT_UINT32:
11004                         if (hf->display == BASE_CUSTOM) {
11005                                 gchar lbl[ITEM_LABEL_LENGTH];
11006                                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11007
11008                                 DISSECTOR_ASSERT(fmtfunc);
11009                                 fmtfunc(lbl, (guint32) tmpval);
11010                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11011                                                 hf->name, lbl);
11012                                 first = FALSE;
11013                         }
11014                         else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11015                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11016                                                                                 hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
11017                                 first = FALSE;
11018                         }
11019                         else if (!(flags & BMT_NO_INT)) {
11020                                 char buf[32];
11021                                 const char *out;
11022
11023                                 if (!first) {
11024                                         proto_item_append_text(item, ", ");
11025                                 }
11026
11027                                 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
11028                                 if (hf->display & BASE_UNIT_STRING) {
11029                                         proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
11030                                 } else {
11031                                         proto_item_append_text(item, "%s: %s", hf->name, out);
11032                                 }
11033                                 first = FALSE;
11034                         }
11035
11036                         break;
11037
11038                 case FT_INT8:
11039                 case FT_INT16:
11040                 case FT_INT24:
11041                 case FT_INT32:
11042                         integer32 = (guint32) tmpval;
11043                         if (hf->bitmask) {
11044                                 no_of_bits = ws_count_ones(hf->bitmask);
11045                                 integer32 = ws_sign_ext32(integer32, no_of_bits);
11046                         }
11047                         if (hf->display == BASE_CUSTOM) {
11048                                 gchar lbl[ITEM_LABEL_LENGTH];
11049                                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11050
11051                                 DISSECTOR_ASSERT(fmtfunc);
11052                                 fmtfunc(lbl, (gint32) integer32);
11053                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11054                                                 hf->name, lbl);
11055                                 first = FALSE;
11056                         }
11057                         else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11058                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11059                                                 hf->name, hf_try_val_to_str_const((gint32) integer32, hf, "Unknown"));
11060                                 first = FALSE;
11061                         }
11062                         else if (!(flags & BMT_NO_INT)) {
11063                                 char buf[32];
11064                                 const char *out;
11065
11066                                 if (!first) {
11067                                         proto_item_append_text(item, ", ");
11068                                 }
11069
11070                                 out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
11071                                 if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11072                                         proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
11073                                 } else {
11074                                         proto_item_append_text(item, "%s: %s", hf->name, out);
11075                                 }
11076                                 first = FALSE;
11077                         }
11078
11079                         break;
11080
11081                 case FT_UINT40:
11082                 case FT_UINT48:
11083                 case FT_UINT56:
11084                 case FT_UINT64:
11085                         if (hf->display == BASE_CUSTOM) {
11086                                 gchar lbl[ITEM_LABEL_LENGTH];
11087                                 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
11088
11089                                 DISSECTOR_ASSERT(fmtfunc);
11090                                 fmtfunc(lbl, tmpval);
11091                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11092                                                 hf->name, lbl);
11093                                 first = FALSE;
11094                         }
11095                         else if (hf->strings) {
11096                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11097                                                 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
11098                                 first = FALSE;
11099                         }
11100                         else if (!(flags & BMT_NO_INT)) {
11101                                 char buf[48];
11102                                 const char *out;
11103
11104                                 if (!first) {
11105                                         proto_item_append_text(item, ", ");
11106                                 }
11107
11108                                 out = hfinfo_number_value_format64(hf, buf, tmpval);
11109                                 proto_item_append_text(item, "%s: %s", hf->name, out);
11110                                 first = FALSE;
11111                         }
11112
11113                         break;
11114
11115                 case FT_INT40:
11116                 case FT_INT48:
11117                 case FT_INT56:
11118                 case FT_INT64:
11119                         if (hf->bitmask) {
11120                                 no_of_bits = ws_count_ones(hf->bitmask);
11121                                 tmpval = ws_sign_ext64(tmpval, no_of_bits);
11122                         }
11123                         if (hf->display == BASE_CUSTOM) {
11124                                 gchar lbl[ITEM_LABEL_LENGTH];
11125                                 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
11126
11127                                 DISSECTOR_ASSERT(fmtfunc);
11128                                 fmtfunc(lbl, (gint64) tmpval);
11129                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11130                                                 hf->name, lbl);
11131                                 first = FALSE;
11132                         }
11133                         else if (hf->strings) {
11134                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11135                                                 hf->name, hf_try_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
11136                                 first = FALSE;
11137                         }
11138                         else if (!(flags & BMT_NO_INT)) {
11139                                 char buf[48];
11140                                 const char *out;
11141
11142                                 if (!first) {
11143                                         proto_item_append_text(item, ", ");
11144                                 }
11145
11146                                 out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
11147                                 proto_item_append_text(item, "%s: %s", hf->name, out);
11148                                 first = FALSE;
11149                         }
11150
11151                         break;
11152
11153                 case FT_BOOLEAN:
11154                         if (hf->strings && !(flags & BMT_NO_TFS)) {
11155                                 /* If we have true/false strings, emit full - otherwise messages
11156                                    might look weird */
11157                                 const struct true_false_string *tfs =
11158                                         (const struct true_false_string *)hf->strings;
11159
11160                                 if (tmpval) {
11161                                         proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11162                                                         hf->name, tfs->true_string);
11163                                         first = FALSE;
11164                                 } else if (!(flags & BMT_NO_FALSE)) {
11165                                         proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11166                                                         hf->name, tfs->false_string);
11167                                         first = FALSE;
11168                                 }
11169                         } else if (hf->bitmask & value) {
11170                                 /* If the flag is set, show the name */
11171                                 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
11172                                 first = FALSE;
11173                         }
11174                         break;
11175                 default:
11176                         DISSECTOR_ASSERT_NOT_REACHED();
11177                         break;
11178                 }
11179
11180                 fields++;
11181         }
11182
11183         return first;
11184 }
11185
11186 /* This function will dissect a sequence of bytes that describe a
11187  * bitmask and supply the value of that sequence through a pointer.
11188  * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
11189  * to be dissected.
11190  * This field will form an expansion under which the individual fields of the
11191  * bitmask is dissected and displayed.
11192  * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
11193  *
11194  * fields is an array of pointers to int that lists all the fields of the
11195  * bitmask. These fields can be either of the type FT_BOOLEAN for flags
11196  * or another integer of the same type/size as hf_hdr with a mask specified.
11197  * This array is terminated by a NULL entry.
11198  *
11199  * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
11200  * FT_integer fields that have a value_string attached will have the
11201  * matched string displayed on the expansion line.
11202  */
11203 proto_item *
11204 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
11205                        const guint offset, const int hf_hdr,
11206                        const gint ett, const int **fields,
11207                        const guint encoding, guint64 *retval)
11208 {
11209         return proto_tree_add_bitmask_with_flags_ret_uint64(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, retval);
11210 }
11211
11212 /* This function will dissect a sequence of bytes that describe a
11213  * bitmask.
11214  * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
11215  * to be dissected.
11216  * This field will form an expansion under which the individual fields of the
11217  * bitmask is dissected and displayed.
11218  * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
11219  *
11220  * fields is an array of pointers to int that lists all the fields of the
11221  * bitmask. These fields can be either of the type FT_BOOLEAN for flags
11222  * or another integer of the same type/size as hf_hdr with a mask specified.
11223  * This array is terminated by a NULL entry.
11224  *
11225  * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
11226  * FT_integer fields that have a value_string attached will have the
11227  * matched string displayed on the expansion line.
11228  */
11229 proto_item *
11230 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
11231                        const guint offset, const int hf_hdr,
11232                        const gint ett, const int **fields,
11233                        const guint encoding)
11234 {
11235         return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
11236 }
11237
11238 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
11239  * what data is appended to the header.
11240  */
11241 proto_item *
11242 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11243                 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
11244                 guint64 *retval)
11245 {
11246         proto_item        *item = NULL;
11247         header_field_info *hf;
11248         int                len;
11249         guint64            value;
11250
11251         PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
11252         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
11253         len = ftype_length(hf->type);
11254         value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
11255
11256         if (parent_tree) {
11257                 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
11258                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
11259                     flags, FALSE, FALSE, NULL, value);
11260         }
11261
11262         *retval = value;
11263         if (hf->bitmask) {
11264                 /* Mask out irrelevant portions */
11265                 *retval &= hf->bitmask;
11266                 /* Shift bits */
11267                 *retval >>= hfinfo_bitshift(hf);
11268         }
11269
11270         return item;
11271 }
11272
11273 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
11274  * what data is appended to the header.
11275  */
11276 proto_item *
11277 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11278                 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
11279 {
11280         proto_item        *item = NULL;
11281         header_field_info *hf;
11282         int                len;
11283         guint64            value;
11284
11285         PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
11286         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
11287
11288         if (parent_tree) {
11289                 len = ftype_length(hf->type);
11290                 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
11291                 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
11292                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
11293                     flags, FALSE, FALSE, NULL, value);
11294         }
11295
11296         return item;
11297 }
11298
11299 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
11300    can't be retrieved directly from tvb) */
11301 proto_item *
11302 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11303                 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
11304 {
11305         return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
11306                                                 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
11307 }
11308
11309 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
11310 WS_DLL_PUBLIC proto_item *
11311 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
11312                 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
11313 {
11314         proto_item        *item = NULL;
11315         header_field_info *hf;
11316         int                len;
11317
11318         PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
11319         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
11320         /* the proto_tree_add_uint/_uint64() calls below
11321            will fail if tvb==NULL and len!=0 */
11322         len = tvb ? ftype_length(hf->type) : 0;
11323
11324         if (parent_tree) {
11325                 if (len <= 4)
11326                         item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
11327                 else
11328                         item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
11329
11330                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
11331                     flags, FALSE, FALSE, NULL, value);
11332         }
11333
11334         return item;
11335 }
11336
11337 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
11338 void
11339 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
11340                                                                 const int len, const int **fields, const guint encoding)
11341 {
11342         guint64 value;
11343
11344         if (tree) {
11345                 value = get_uint64_value(tree, tvb, offset, len, encoding);
11346                 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
11347                     BMT_NO_APPEND, FALSE, TRUE, tree, value);
11348         }
11349 }
11350
11351 WS_DLL_PUBLIC void
11352 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
11353                                                                 const int len, const int **fields, const guint64 value)
11354 {
11355         if (tree) {
11356                 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
11357                     BMT_NO_APPEND, FALSE, TRUE, tree, value);
11358         }
11359 }
11360
11361
11362 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
11363  * This is intended to support bitmask fields whose lengths can vary, perhaps
11364  * as the underlying standard evolves over time.
11365  * With this API there is the possibility of being called to display more or
11366  * less data than the dissector was coded to support.
11367  * In such cases, it is assumed that bitmasks are extended on the MSb end.
11368  * Thus when presented with "too much" or "too little" data, MSbits will be
11369  * ignored or MSfields sacrificed.
11370  *
11371  * Only fields for which all defined bits are available are displayed.
11372  */
11373 proto_item *
11374 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
11375                        const guint offset,  const guint len, const int hf_hdr,
11376                        const gint ett, const int **fields, struct expert_field* exp,
11377                        const guint encoding)
11378 {
11379         proto_item        *item = NULL;
11380         header_field_info *hf;
11381         guint   decodable_len;
11382         guint   decodable_offset;
11383         guint32 decodable_value;
11384         guint64 value;
11385
11386         PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
11387         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
11388
11389         decodable_offset = offset;
11390         decodable_len = MIN(len, (guint) ftype_length(hf->type));
11391
11392         /* If we are ftype_length-limited,
11393          * make sure we decode as many LSBs as possible.
11394          */
11395         if (encoding == ENC_BIG_ENDIAN) {
11396                 decodable_offset += (len - decodable_len);
11397         }
11398
11399         if (parent_tree) {
11400                 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
11401                                                  decodable_len, encoding);
11402
11403                 /* The root item covers all the bytes even if we can't decode them all */
11404                 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
11405                                            decodable_value);
11406         }
11407
11408         if (decodable_len < len) {
11409                 /* Dissector likely requires updating for new protocol revision */
11410                 expert_add_info_format(NULL, item, exp,
11411                                        "Only least-significant %d of %d bytes decoded",
11412                                        decodable_len, len);
11413         }
11414
11415         if (item) {
11416                 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
11417                 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
11418                     ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
11419         }
11420
11421         return item;
11422 }
11423
11424 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
11425 proto_item *
11426 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
11427                             const guint offset, const guint len,
11428                             const char *name, const char *fallback,
11429                             const gint ett, const int **fields,
11430                             const guint encoding, const int flags)
11431 {
11432         proto_item *item = NULL;
11433         guint64     value;
11434
11435         if (parent_tree) {
11436                 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
11437                 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
11438                 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
11439                     flags, TRUE, FALSE, NULL, value) && fallback) {
11440                         /* Still at first item - append 'fallback' text if any */
11441                         proto_item_append_text(item, "%s", fallback);
11442                 }
11443         }
11444
11445         return item;
11446 }
11447
11448 proto_item *
11449 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11450                          const guint bit_offset, const gint no_of_bits,
11451                          const guint encoding)
11452 {
11453         header_field_info *hfinfo;
11454         gint               octet_length;
11455         gint               octet_offset;
11456
11457         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
11458
11459         octet_length = (no_of_bits + 7) >> 3;
11460         octet_offset = bit_offset >> 3;
11461         test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
11462
11463         /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
11464          * but only after doing a bunch more work (which we can, in the common
11465          * case, shortcut here).
11466          */
11467         CHECK_FOR_NULL_TREE(tree);
11468         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
11469
11470         return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
11471 }
11472
11473 /*
11474  * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
11475  * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
11476  * Offset should be given in bits from the start of the tvb.
11477  */
11478
11479 static proto_item *
11480 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11481                             const guint bit_offset, const gint no_of_bits,
11482                             guint64 *return_value, const guint encoding)
11483 {
11484         gint     offset;
11485         guint    length;
11486         guint8   tot_no_bits;
11487         char    *bf_str;
11488         char     lbl_str[ITEM_LABEL_LENGTH];
11489         guint64  value = 0;
11490
11491         proto_item        *pi;
11492         header_field_info *hf_field;
11493
11494         const true_false_string *tfstring;
11495
11496         /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
11497         PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
11498
11499         if (hf_field->bitmask != 0) {
11500                 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_ret_val"
11501                                      " with field '%s' (%s) with bitmask != 0",
11502                                      hf_field->abbrev, hf_field->name);
11503         }
11504
11505         DISSECTOR_ASSERT(no_of_bits >  0);
11506
11507         /* Byte align offset */
11508         offset = bit_offset>>3;
11509
11510         /*
11511          * Calculate the number of octets used to hold the bits
11512          */
11513         tot_no_bits = ((bit_offset&0x7) + no_of_bits);
11514         length = (tot_no_bits + 7) >> 3;
11515
11516         if (no_of_bits < 65) {
11517                 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
11518         } else {
11519                 DISSECTOR_ASSERT_NOT_REACHED();
11520                 return NULL;
11521         }
11522
11523         /* Sign extend for signed types */
11524         switch (hf_field->type) {
11525                 case FT_INT8:
11526                 case FT_INT16:
11527                 case FT_INT24:
11528                 case FT_INT32:
11529                 case FT_INT40:
11530                 case FT_INT48:
11531                 case FT_INT56:
11532                 case FT_INT64:
11533                         value = ws_sign_ext64(value, no_of_bits);
11534                         break;
11535
11536                 default:
11537                         break;
11538         }
11539
11540         if (return_value) {
11541                 *return_value = value;
11542         }
11543
11544         /* Coast clear. Try and fake it */
11545         CHECK_FOR_NULL_TREE(tree);
11546         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11547
11548         bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
11549
11550         switch (hf_field->type) {
11551         case FT_BOOLEAN:
11552                 /* Boolean field */
11553                 tfstring = (const true_false_string *) &tfs_true_false;
11554                 if (hf_field->strings)
11555                         tfstring = (const true_false_string *)hf_field->strings;
11556                 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
11557                         "%s = %s: %s",
11558                         bf_str, hf_field->name,
11559                         (guint64)value ? tfstring->true_string : tfstring->false_string);
11560                 break;
11561
11562         case FT_CHAR:
11563                 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
11564                 fill_label_char(PITEM_FINFO(pi), lbl_str);
11565                 break;
11566
11567         case FT_UINT8:
11568         case FT_UINT16:
11569         case FT_UINT24:
11570         case FT_UINT32:
11571                 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
11572                 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
11573                 break;
11574
11575         case FT_INT8:
11576         case FT_INT16:
11577         case FT_INT24:
11578         case FT_INT32:
11579                 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
11580                 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
11581                 break;
11582
11583         case FT_UINT40:
11584         case FT_UINT48:
11585         case FT_UINT56:
11586         case FT_UINT64:
11587                 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
11588                 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
11589                 break;
11590
11591         case FT_INT40:
11592         case FT_INT48:
11593         case FT_INT56:
11594         case FT_INT64:
11595                 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
11596                 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
11597                 break;
11598
11599         default:
11600                 DISSECTOR_ASSERT_NOT_REACHED();
11601                 return NULL;
11602                 break;
11603         }
11604
11605         proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
11606         return pi;
11607 }
11608
11609 proto_item *
11610 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11611                                        const guint bit_offset, const crumb_spec_t *crumb_spec,
11612                                        guint64 *return_value)
11613 {
11614         proto_item *pi;
11615         gint        no_of_bits;
11616         gint        octet_offset;
11617         guint       mask_initial_bit_offset;
11618         guint       mask_greatest_bit_offset;
11619         guint       octet_length;
11620         guint8      i;
11621         char        bf_str[256];
11622         char        lbl_str[ITEM_LABEL_LENGTH];
11623         guint64     value;
11624         guint64     composite_bitmask;
11625         guint64     composite_bitmap;
11626
11627         header_field_info       *hf_field;
11628         const true_false_string *tfstring;
11629
11630         /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
11631         PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
11632
11633         if (hf_field->bitmask != 0) {
11634                 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_split_bits_item_ret_val"
11635                                      " with field '%s' (%s) with bitmask != 0",
11636                                      hf_field->abbrev, hf_field->name);
11637         }
11638
11639         mask_initial_bit_offset = bit_offset % 8;
11640
11641         no_of_bits = 0;
11642         value      = 0;
11643         i          = 0;
11644         mask_greatest_bit_offset = 0;
11645         composite_bitmask        = 0;
11646         composite_bitmap         = 0;
11647
11648         while (crumb_spec[i].crumb_bit_length != 0) {
11649                 guint64 crumb_mask, crumb_value;
11650                 guint8  crumb_end_bit_offset;
11651
11652                 crumb_value = tvb_get_bits64(tvb,
11653                                              bit_offset + crumb_spec[i].crumb_bit_offset,
11654                                              crumb_spec[i].crumb_bit_length,
11655                                              ENC_BIG_ENDIAN);
11656                 value      += crumb_value;
11657                 no_of_bits += crumb_spec[i].crumb_bit_length;
11658                 DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "a value larger than 64 bits cannot be represented");
11659
11660                 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
11661                    octet containing the initial offset.
11662                    If the mask is beyond 32 bits, then give up on bit map display.
11663                    This could be improved in future, probably showing a table
11664                    of 32 or 64 bits per row */
11665                 if (mask_greatest_bit_offset < 32) {
11666                         crumb_end_bit_offset = mask_initial_bit_offset
11667                                 + crumb_spec[i].crumb_bit_offset
11668                                 + crumb_spec[i].crumb_bit_length;
11669                         crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
11670
11671                         if (crumb_end_bit_offset > mask_greatest_bit_offset) {
11672                                 mask_greatest_bit_offset = crumb_end_bit_offset;
11673                         }
11674                         /* Currently the bitmap of the crumbs are only shown if
11675                          * smaller than 32 bits. Do not bother calculating the
11676                          * mask if it is larger than that. */
11677                         if (crumb_end_bit_offset <= 32) {
11678                                 composite_bitmask |= (crumb_mask  << (64 - crumb_end_bit_offset));
11679                                 composite_bitmap  |= (crumb_value << (64 - crumb_end_bit_offset));
11680                         }
11681                 }
11682                 /* Shift left for the next segment */
11683                 value <<= crumb_spec[++i].crumb_bit_length;
11684         }
11685
11686         /* Sign extend for signed types */
11687         switch (hf_field->type) {
11688                 case FT_INT8:
11689                 case FT_INT16:
11690                 case FT_INT24:
11691                 case FT_INT32:
11692                 case FT_INT40:
11693                 case FT_INT48:
11694                 case FT_INT56:
11695                 case FT_INT64:
11696                         value = ws_sign_ext64(value, no_of_bits);
11697                         break;
11698                 default:
11699                         break;
11700         }
11701
11702         if (return_value) {
11703                 *return_value = value;
11704         }
11705
11706         /* Coast clear. Try and fake it */
11707         CHECK_FOR_NULL_TREE(tree);
11708         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11709
11710         /* initialise the format string */
11711         bf_str[0] = '\0';
11712
11713         octet_offset = bit_offset >> 3;
11714
11715         /* Round up mask length to nearest octet */
11716         octet_length = ((mask_greatest_bit_offset + 7) >> 3);
11717         mask_greatest_bit_offset = octet_length << 3;
11718
11719         /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
11720            It would be a useful enhancement to eliminate this restriction. */
11721         if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
11722                 other_decode_bitfield_value(bf_str,
11723                                             (guint32)(composite_bitmap  >> (64 - mask_greatest_bit_offset)),
11724                                             (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
11725                                             mask_greatest_bit_offset);
11726         } else {
11727                 /* If the bitmask is too large, try to describe its contents. */
11728                 g_snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
11729         }
11730
11731         switch (hf_field->type) {
11732         case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
11733                 /* Boolean field */
11734                 tfstring = (const true_false_string *) &tfs_true_false;
11735                 if (hf_field->strings)
11736                         tfstring = (const true_false_string *) hf_field->strings;
11737                 return proto_tree_add_boolean_format(tree, hfindex,
11738                                                      tvb, octet_offset, octet_length, (guint32)value,
11739                                                      "%s = %s: %s",
11740                                                      bf_str, hf_field->name,
11741                                                      (guint64)value ? tfstring->true_string : tfstring->false_string);
11742                 break;
11743
11744         case FT_CHAR:
11745                 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
11746                 fill_label_char(PITEM_FINFO(pi), lbl_str);
11747                 break;
11748
11749         case FT_UINT8:
11750         case FT_UINT16:
11751         case FT_UINT24:
11752         case FT_UINT32:
11753                 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
11754                 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
11755                 break;
11756
11757         case FT_INT8:
11758         case FT_INT16:
11759         case FT_INT24:
11760         case FT_INT32:
11761                 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
11762                 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
11763                 break;
11764
11765         case FT_UINT40:
11766         case FT_UINT48:
11767         case FT_UINT56:
11768         case FT_UINT64:
11769                 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
11770                 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
11771                 break;
11772
11773         case FT_INT40:
11774         case FT_INT48:
11775         case FT_INT56:
11776         case FT_INT64:
11777                 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
11778                 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
11779                 break;
11780
11781         default:
11782                 DISSECTOR_ASSERT_NOT_REACHED();
11783                 return NULL;
11784                 break;
11785         }
11786         proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
11787         return pi;
11788 }
11789
11790 void
11791 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
11792                                 const crumb_spec_t *crumb_spec, guint16 crumb_index)
11793 {
11794         header_field_info *hfinfo;
11795
11796         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
11797         proto_tree_add_text_internal(tree, tvb,
11798                             bit_offset >> 3,
11799                             ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
11800                             "%s crumb %d of %s (decoded above)",
11801                             decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
11802                                                  tvb_get_bits(tvb,
11803                                                               bit_offset,
11804                                                               crumb_spec[crumb_index].crumb_bit_length,
11805                                                               ENC_BIG_ENDIAN)),
11806                             crumb_index,
11807                             hfinfo->name);
11808 }
11809
11810 proto_item *
11811 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
11812                             const guint bit_offset, const gint no_of_bits,
11813                             guint64 *return_value, const guint encoding)
11814 {
11815         proto_item *item;
11816
11817         if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
11818                                                  bit_offset, no_of_bits,
11819                                                  return_value, encoding))) {
11820                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
11821                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
11822         }
11823         return item;
11824 }
11825
11826 static proto_item *
11827 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
11828                                  tvbuff_t *tvb, const guint bit_offset,
11829                                  const gint no_of_bits, void *value_ptr,
11830                                  gchar *value_str)
11831 {
11832         gint     offset;
11833         guint    length;
11834         guint8   tot_no_bits;
11835         char    *str;
11836         guint64  value = 0;
11837         header_field_info *hf_field;
11838
11839         /* We do not have to return a value, try to fake it as soon as possible */
11840         CHECK_FOR_NULL_TREE(tree);
11841         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11842
11843         if (hf_field->bitmask != 0) {
11844                 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_format_value"
11845                                      " with field '%s' (%s) with bitmask != 0",
11846                                      hf_field->abbrev, hf_field->name);
11847         }
11848
11849         DISSECTOR_ASSERT(no_of_bits > 0);
11850
11851         /* Byte align offset */
11852         offset = bit_offset>>3;
11853
11854         /*
11855          * Calculate the number of octets used to hold the bits
11856          */
11857         tot_no_bits = ((bit_offset&0x7) + no_of_bits);
11858         length      = tot_no_bits>>3;
11859         /* If we are using part of the next octet, increase length by 1 */
11860         if (tot_no_bits & 0x07)
11861                 length++;
11862
11863         if (no_of_bits < 65) {
11864                 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
11865         } else {
11866                 DISSECTOR_ASSERT_NOT_REACHED();
11867                 return NULL;
11868         }
11869
11870         str = decode_bits_in_field(bit_offset, no_of_bits, value);
11871
11872         g_strlcat(str, " = ", 256+64);
11873         g_strlcat(str, hf_field->name, 256+64);
11874
11875         /*
11876          * This function does not receive an actual value but a dimensionless pointer to that value.
11877          * For this reason, the type of the header field is examined in order to determine
11878          * what kind of value we should read from this address.
11879          * The caller of this function must make sure that for the specific header field type the address of
11880          * a compatible value is provided.
11881          */
11882         switch (hf_field->type) {
11883         case FT_BOOLEAN:
11884                 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
11885                                                      "%s: %s", str, value_str);
11886                 break;
11887
11888         case FT_CHAR:
11889         case FT_UINT8:
11890         case FT_UINT16:
11891         case FT_UINT24:
11892         case FT_UINT32:
11893                 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
11894                                                   "%s: %s", str, value_str);
11895                 break;
11896
11897         case FT_UINT40:
11898         case FT_UINT48:
11899         case FT_UINT56:
11900         case FT_UINT64:
11901                 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
11902                                                     "%s: %s", str, value_str);
11903                 break;
11904
11905         case FT_INT8:
11906         case FT_INT16:
11907         case FT_INT24:
11908         case FT_INT32:
11909                 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
11910                                                  "%s: %s", str, value_str);
11911                 break;
11912
11913         case FT_INT40:
11914         case FT_INT48:
11915         case FT_INT56:
11916         case FT_INT64:
11917                 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
11918                                                    "%s: %s", str, value_str);
11919                 break;
11920
11921         case FT_FLOAT:
11922                 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
11923                                                    "%s: %s", str, value_str);
11924                 break;
11925
11926         default:
11927                 DISSECTOR_ASSERT_NOT_REACHED();
11928                 return NULL;
11929                 break;
11930         }
11931 }
11932
11933 static proto_item *
11934 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
11935                                  tvbuff_t *tvb, const guint bit_offset,
11936                                  const gint no_of_bits, void *value_ptr,
11937                                  gchar *value_str)
11938 {
11939         proto_item *item;
11940
11941         if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
11942                                                       tvb, bit_offset, no_of_bits,
11943                                                       value_ptr, value_str))) {
11944                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
11945                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
11946         }
11947         return item;
11948 }
11949
11950 #define CREATE_VALUE_STRING(dst,format,ap) \
11951         va_start(ap, format); \
11952         dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
11953         va_end(ap);
11954
11955 proto_item *
11956 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
11957                                       tvbuff_t *tvb, const guint bit_offset,
11958                                       const gint no_of_bits, guint32 value,
11959                                       const char *format, ...)
11960 {
11961         va_list ap;
11962         gchar  *dst;
11963         header_field_info *hf_field;
11964
11965         CHECK_FOR_NULL_TREE(tree);
11966
11967         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
11968
11969         switch (hf_field->type) {
11970                 case FT_UINT8:
11971                 case FT_UINT16:
11972                 case FT_UINT24:
11973                 case FT_UINT32:
11974                         break;
11975
11976                 default:
11977                         DISSECTOR_ASSERT_NOT_REACHED();
11978                         return NULL;
11979                         break;
11980         }
11981
11982         CREATE_VALUE_STRING(dst, format, ap);
11983
11984         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
11985 }
11986
11987 proto_item *
11988 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
11989                                       tvbuff_t *tvb, const guint bit_offset,
11990                                       const gint no_of_bits, guint64 value,
11991                                       const char *format, ...)
11992 {
11993         va_list ap;
11994         gchar  *dst;
11995         header_field_info *hf_field;
11996
11997         CHECK_FOR_NULL_TREE(tree);
11998
11999         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12000
12001         switch (hf_field->type) {
12002                 case FT_UINT40:
12003                 case FT_UINT48:
12004                 case FT_UINT56:
12005                 case FT_UINT64:
12006                         break;
12007
12008                 default:
12009                         DISSECTOR_ASSERT_NOT_REACHED();
12010                         return NULL;
12011                         break;
12012         }
12013
12014         CREATE_VALUE_STRING(dst, format, ap);
12015
12016         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12017 }
12018
12019 proto_item *
12020 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
12021                                        tvbuff_t *tvb, const guint bit_offset,
12022                                        const gint no_of_bits, float value,
12023                                        const char *format, ...)
12024 {
12025         va_list ap;
12026         gchar  *dst;
12027         header_field_info *hf_field;
12028
12029         CHECK_FOR_NULL_TREE(tree);
12030
12031         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12032
12033         DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
12034
12035         CREATE_VALUE_STRING(dst, format, ap);
12036
12037         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12038 }
12039
12040 proto_item *
12041 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
12042                                      tvbuff_t *tvb, const guint bit_offset,
12043                                      const gint no_of_bits, gint32 value,
12044                                      const char *format, ...)
12045 {
12046         va_list ap;
12047         gchar  *dst;
12048         header_field_info *hf_field;
12049
12050         CHECK_FOR_NULL_TREE(tree);
12051
12052         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12053
12054         switch (hf_field->type) {
12055                 case FT_INT8:
12056                 case FT_INT16:
12057                 case FT_INT24:
12058                 case FT_INT32:
12059                         break;
12060
12061                 default:
12062                         DISSECTOR_ASSERT_NOT_REACHED();
12063                         return NULL;
12064                         break;
12065         }
12066
12067         CREATE_VALUE_STRING(dst, format, ap);
12068
12069         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12070 }
12071
12072 proto_item *
12073 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
12074                                      tvbuff_t *tvb, const guint bit_offset,
12075                                      const gint no_of_bits, gint64 value,
12076                                      const char *format, ...)
12077 {
12078         va_list ap;
12079         gchar  *dst;
12080         header_field_info *hf_field;
12081
12082         CHECK_FOR_NULL_TREE(tree);
12083
12084         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12085
12086         switch (hf_field->type) {
12087                 case FT_INT40:
12088                 case FT_INT48:
12089                 case FT_INT56:
12090                 case FT_INT64:
12091                         break;
12092
12093                 default:
12094                         DISSECTOR_ASSERT_NOT_REACHED();
12095                         return NULL;
12096                         break;
12097         }
12098
12099         CREATE_VALUE_STRING(dst, format, ap);
12100
12101         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12102 }
12103
12104 proto_item *
12105 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
12106                                          tvbuff_t *tvb, const guint bit_offset,
12107                                          const gint no_of_bits, guint32 value,
12108                                          const char *format, ...)
12109 {
12110         va_list ap;
12111         gchar  *dst;
12112         header_field_info *hf_field;
12113
12114         CHECK_FOR_NULL_TREE(tree);
12115
12116         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12117
12118         DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
12119
12120         CREATE_VALUE_STRING(dst, format, ap);
12121
12122         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12123 }
12124
12125 proto_item *
12126 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
12127                                          tvbuff_t *tvb, const guint bit_offset,
12128                                          const gint no_of_bits, guint64 value,
12129                                          const char *format, ...)
12130 {
12131         va_list ap;
12132         gchar  *dst;
12133         header_field_info *hf_field;
12134
12135         CHECK_FOR_NULL_TREE(tree);
12136
12137         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12138
12139         DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
12140
12141         CREATE_VALUE_STRING(dst, format, ap);
12142
12143         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
12144 }
12145
12146 proto_item *
12147 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12148         const guint bit_offset, const gint no_of_chars)
12149 {
12150         proto_item        *pi;
12151         header_field_info *hfinfo;
12152         gint               byte_length;
12153         gint               byte_offset;
12154         gchar             *string;
12155
12156         CHECK_FOR_NULL_TREE(tree);
12157
12158         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12159
12160         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
12161
12162         byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
12163         byte_offset = bit_offset >> 3;
12164
12165         string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
12166
12167         if (hfinfo->display == STR_UNICODE) {
12168                 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
12169         }
12170
12171         pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
12172         DISSECTOR_ASSERT(byte_length >= 0);
12173         proto_tree_set_string(PNODE_FINFO(pi), string);
12174
12175         return pi;
12176 }
12177
12178 proto_item *
12179 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12180         const guint bit_offset, const gint no_of_chars)
12181 {
12182         proto_item        *pi;
12183         header_field_info *hfinfo;
12184         gint               byte_length;
12185         gint               byte_offset;
12186         gchar             *string;
12187
12188         CHECK_FOR_NULL_TREE(tree);
12189
12190         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12191
12192         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
12193
12194         byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
12195         byte_offset = bit_offset >> 3;
12196
12197         string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
12198
12199         if (hfinfo->display == STR_UNICODE) {
12200                 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
12201         }
12202
12203         pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
12204         DISSECTOR_ASSERT(byte_length >= 0);
12205         proto_tree_set_string(PNODE_FINFO(pi), string);
12206
12207         return pi;
12208 }
12209
12210 const value_string proto_checksum_vals[] = {
12211         { PROTO_CHECKSUM_E_BAD,        "Bad"  },
12212         { PROTO_CHECKSUM_E_GOOD,       "Good" },
12213         { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
12214         { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
12215
12216         { 0,        NULL }
12217 };
12218
12219 proto_item *
12220 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
12221                 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
12222                 packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
12223 {
12224         header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
12225         guint32 checksum;
12226         guint32 len;
12227         proto_item* ti = NULL;
12228         proto_item* ti2;
12229         gboolean incorrect_checksum = TRUE;
12230
12231         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
12232
12233         switch (hfinfo->type) {
12234         case FT_UINT8:
12235                 len = 1;
12236                 break;
12237         case FT_UINT16:
12238                 len = 2;
12239                 break;
12240         case FT_UINT24:
12241                 len = 3;
12242                 break;
12243         case FT_UINT32:
12244                 len = 4;
12245                 break;
12246         default:
12247                 DISSECTOR_ASSERT_NOT_REACHED();
12248         }
12249
12250         if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
12251                 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
12252                 PROTO_ITEM_SET_GENERATED(ti);
12253                 if (hf_checksum_status != -1) {
12254                         ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
12255                         PROTO_ITEM_SET_GENERATED(ti2);
12256                 }
12257                 return ti;
12258         }
12259
12260         if (flags & PROTO_CHECKSUM_GENERATED) {
12261                 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
12262                 PROTO_ITEM_SET_GENERATED(ti);
12263         } else {
12264                 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
12265                 if (flags & PROTO_CHECKSUM_VERIFY) {
12266                         if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
12267                                 if (computed_checksum == 0) {
12268                                         proto_item_append_text(ti, " [correct]");
12269                                         if (hf_checksum_status != -1) {
12270                                                 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
12271                                                 PROTO_ITEM_SET_GENERATED(ti2);
12272                                         }
12273                                         incorrect_checksum = FALSE;
12274                                 } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
12275                                         computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
12276                                 }
12277                         } else {
12278                                 if (checksum == computed_checksum) {
12279                                         proto_item_append_text(ti, " [correct]");
12280                                         if (hf_checksum_status != -1) {
12281                                                 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
12282                                                 PROTO_ITEM_SET_GENERATED(ti2);
12283                                         }
12284                                         incorrect_checksum = FALSE;
12285                                 }
12286                         }
12287
12288                         if (incorrect_checksum) {
12289                                 if (hf_checksum_status != -1) {
12290                                         ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
12291                                         PROTO_ITEM_SET_GENERATED(ti2);
12292                                 }
12293                                 if (flags & PROTO_CHECKSUM_ZERO) {
12294                                         proto_item_append_text(ti, " [incorrect]");
12295                                         if (bad_checksum_expert != NULL)
12296                                                 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
12297                                 } else {
12298                                         proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
12299                                         if (bad_checksum_expert != NULL)
12300                                                 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%0*x]", expert_get_summary(bad_checksum_expert), len * 2, computed_checksum);
12301                                 }
12302                         }
12303                 } else {
12304                         if (hf_checksum_status != -1) {
12305                                 proto_item_append_text(ti, " [unverified]");
12306                                 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
12307                                 PROTO_ITEM_SET_GENERATED(ti2);
12308                         }
12309                 }
12310         }
12311
12312         return ti;
12313 }
12314
12315 guchar
12316 proto_check_field_name(const gchar *field_name)
12317 {
12318         const char *p = field_name;
12319         guchar c = '.', lastc;
12320
12321         do {
12322                 lastc = c;
12323                 c = *(p++);
12324                 /* Leading '.' or substring ".." are disallowed. */
12325                 if (c == '.' && lastc == '.') {
12326                         break;
12327                 }
12328         } while (fld_abbrev_chars[c]);
12329
12330         /* Trailing '.' is disallowed. */
12331         if (lastc == '.') {
12332                 return '.';
12333         }
12334         return c;
12335 }
12336
12337 gboolean
12338 tree_expanded(int tree_type)
12339 {
12340         if (tree_type == -1) {
12341                 return FALSE;
12342         }
12343         g_assert(tree_type >= 0 && tree_type < num_tree_types);
12344         return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
12345 }
12346
12347 void
12348 tree_expanded_set(int tree_type, gboolean value)
12349 {
12350         g_assert(tree_type >= 0 && tree_type < num_tree_types);
12351
12352         if (value)
12353                 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
12354         else
12355                 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
12356 }
12357
12358 /*
12359  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
12360  *
12361  * Local variables:
12362  * c-basic-offset: 8
12363  * tab-width: 8
12364  * indent-tabs-mode: t
12365  * End:
12366  *
12367  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
12368  * :indentSize=8:tabSize=8:noTabs=false:
12369  */