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