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