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