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