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