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