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