Redo r52569 in a way that doesn't break the GUI. Add a mem_pool member to
[metze/wireshark/wip.git] / epan / proto.c
1 /* proto.c
2  * Routines for protocol tree
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23  */
24
25 #include "config.h"
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <glib.h>
31 #include <float.h>
32 #include <wsutil/swar.h>
33
34 #include "packet.h"
35 #include "ptvcursor.h"
36 #include "strutil.h"
37 #include "addr_resolv.h"
38 #include "oids.h"
39 #include "plugins.h"
40 #include "proto.h"
41 #include "epan_dissect.h"
42 #include "tvbuff.h"
43 #include "emem.h"
44 #include "wmem/wmem.h"
45 #include "charsets.h"
46 #include "asm_utils.h"
47 #include "column-utils.h"
48 #include "to_str.h"
49 #include "expert.h"
50 #include "show_exception.h"
51
52 #include "wspython/wspy_register.h"
53
54 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
55 #define SUBTREE_MAX_LEVELS 256
56 /* Throw an exception if we exceed this many tree items. */
57 /* XXX - This should probably be a preference */
58 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
59
60
61 typedef struct __subtree_lvl {
62         gint        cursor_offset;
63         proto_item *it;
64         proto_tree *tree;
65 } subtree_lvl;
66
67 struct ptvcursor {
68         subtree_lvl *pushed_tree;
69         guint8       pushed_tree_index;
70         guint8       pushed_tree_max;
71         proto_tree  *tree;
72         tvbuff_t    *tvb;
73         gint         offset;
74 };
75
76 #define cVALS(x) (const value_string*)(x)
77
78 /** See inlined comments.
79  @param tree the tree to append this item to
80  @param hfindex field index
81  @param hfinfo header_field
82  @return the header field matching 'hfinfo' */
83 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
84         /* If this item is not referenced we dont have to do much work  \
85            at all but we should still return a node so that field items \
86            below this node (think proto_item_add_subtree()) will still  \
87            have somewhere to attach to or else filtering will not work  \
88            (they would be ignored since tree would be NULL).            \
89            DONT try to fake a node where PTREE_FINFO(tree) is NULL      \
90            since dissectors that want to do proto_item_set_len() or     \
91            other operations that dereference this would crash.          \
92            We fake FT_PROTOCOL unless some clients have requested us    \
93            not to do so. \
94         */                                                              \
95         if (!tree)                                                      \
96                 return NULL;                                            \
97         PTREE_DATA(tree)->count++;                                      \
98         if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) {                 \
99                 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
100                         g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
101                 /* Let the exception handler add items to the tree */   \
102                 PTREE_DATA(tree)->count = 0;                            \
103                 THROW_MESSAGE(DissectorError,                           \
104                         ep_strdup_printf("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
105         }                                                               \
106         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);                       \
107         if (!(PTREE_DATA(tree)->visible)) {                             \
108                 if (PTREE_FINFO(tree)) {                                \
109                         if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT)    \
110                             && (hfinfo->type != FT_PROTOCOL ||          \
111                                 PTREE_DATA(tree)->fake_protocols)) {    \
112                                 /* just return tree back to the caller */\
113                                 return tree;                            \
114                         }                                               \
115                 }                                                       \
116         }
117
118 /** See inlined comments.
119  @param pi the created protocol item we're about to return */
120 #define TRY_TO_FAKE_THIS_REPR(pi) \
121         g_assert(pi);                   \
122         if (!(PTREE_DATA(pi)->visible)) { \
123                 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
124                  * items string representation */ \
125                 return pi; \
126         }
127
128 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
129
130 static void fill_label_boolean(field_info *fi, gchar *label_str);
131 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
132 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
133 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
134
135 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
136 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
137 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
138 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
139
140 static const char* hfinfo_uint64_format(const header_field_info *hfinfo);
141 static const char* hfinfo_int64_format(const header_field_info *hfinfo);
142
143 static proto_item *
144 proto_tree_add_node(proto_tree *tree, field_info *fi);
145
146 static void
147 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
148                 gint *item_length);
149
150 static field_info *
151 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
152                const gint start, const gint item_length);
153
154 static field_info *
155 alloc_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
156                  const gint start, gint *length);
157
158 static proto_item *
159 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
160                   gint start, gint *length);
161
162 static void
163 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
164 static void
165 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
166
167 static void
168 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb);
169 static void
170 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
171 static void
172 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
173 static void
174 proto_tree_set_time(field_info *fi, nstime_t *value_ptr);
175 static void
176 proto_tree_set_string(field_info *fi, const char* value);
177 static void
178 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding);
179 static void
180 proto_tree_set_ax25(field_info *fi, const guint8* value);
181 static void
182 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
183 static void
184 proto_tree_set_vines(field_info *fi, const guint8* value);
185 static void
186 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
187 static void
188 proto_tree_set_ether(field_info *fi, const guint8* value);
189 static void
190 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
191 static void
192 proto_tree_set_ipxnet(field_info *fi, guint32 value);
193 static void
194 proto_tree_set_ipv4(field_info *fi, guint32 value);
195 static void
196 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
197 static void
198 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
199 static void
200 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
201 static void
202 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
203 static void
204 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
205 static void
206 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
207 static void
208 proto_tree_set_boolean(field_info *fi, guint32 value);
209 static void
210 proto_tree_set_float(field_info *fi, float value);
211 static void
212 proto_tree_set_double(field_info *fi, double value);
213 static void
214 proto_tree_set_uint(field_info *fi, guint32 value);
215 static void
216 proto_tree_set_int(field_info *fi, gint32 value);
217 static void
218 proto_tree_set_uint64(field_info *fi, guint64 value);
219 static void
220 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, guint length, const guint encoding);
221 static void
222 proto_tree_set_eui64(field_info *fi, const guint64 value);
223 static void
224 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
225
226 /* Handle type length mismatch (now filterable) expert info */
227 static int proto_type_length_mismatch = -1;
228 static expert_field ei_type_length_mismatch_error = EI_INIT;
229 static expert_field ei_type_length_mismatch_warn = EI_INIT;
230 static void register_type_length_mismatch(void);
231
232 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
233
234 /* special-case header field used within proto.c */
235 static header_field_info hfi_text_only =
236         { "Text item",  "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
237 int hf_text_only = -1;
238
239 /* Structure for information about a protocol */
240 struct _protocol {
241         const char *name;         /* long description */
242         const char *short_name;   /* short description */
243         const char *filter_name;  /* name of this protocol in filters */
244         int         proto_id;     /* field ID for this protocol */
245         GSList     *fields;       /* fields for this protocol */
246         GSList     *last_field;   /* pointer to end of list of fields */
247         gboolean    is_enabled;   /* TRUE if protocol is enabled */
248         gboolean    can_toggle;   /* TRUE if is_enabled can be changed */
249         gboolean    is_private;   /* TRUE is protocol is private */
250 };
251
252 /* List of all protocols */
253 static GList *protocols = NULL;
254
255 static wmem_allocator_t *tree_pool_cache = NULL;
256
257 /* Contains information about a field when a dissector calls
258  * proto_tree_add_item.  */
259 #define FIELD_INFO_NEW(pool, fi)  fi = wmem_new(pool, field_info)
260 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
261
262 /* Contains the space for proto_nodes. */
263 #define PROTO_NODE_NEW(pool, node)                      \
264         node = wmem_new(pool, proto_node);              \
265         node->first_child = NULL;                       \
266         node->last_child = NULL;                        \
267         node->next = NULL;
268
269 #define PROTO_NODE_FREE(pool, node)                     \
270         wmem_free(pool, node)
271
272 /* String space for protocol and field items for the GUI */
273 #define ITEM_LABEL_NEW(pool, il)                        \
274         il = wmem_new(pool, item_label_t);
275 #define ITEM_LABEL_FREE(pool, il)                       \
276         wmem_free(pool, il);
277
278 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)                                                \
279         if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG"))      \
280                 g_error("Unregistered hf! index=%d", hfindex);                                  \
281         DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!");     \
282         hfinfo = gpa_hfinfo.hfi[hfindex];
283
284 /* List which stores protocols and fields that have been registered */
285 typedef struct _gpa_hfinfo_t {
286         guint32             len;
287         guint32             allocated_len;
288         header_field_info **hfi;
289 } gpa_hfinfo_t;
290
291 static gpa_hfinfo_t gpa_hfinfo;
292
293 /* Balanced tree of abbreviations and IDs */
294 static GTree *gpa_name_tree = NULL;
295 static header_field_info *same_name_hfinfo;
296
297 static void save_same_name_hfinfo(gpointer data)
298 {
299         same_name_hfinfo = (header_field_info*)data;
300 }
301
302 /* Points to the first element of an array of bits, indexed by
303    a subtree item type; that array element is TRUE if subtrees of
304    an item of that type are to be expanded. */
305 static guint32 *tree_is_expanded;
306
307 /* Number of elements in that array. */
308 int             num_tree_types;
309
310 /* Name hashtables for fast detection of duplicate names */
311 static GHashTable* proto_names        = NULL;
312 static GHashTable* proto_short_names  = NULL;
313 static GHashTable* proto_filter_names = NULL;
314
315 static gint
316 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
317 {
318         const protocol_t *p1 = (const protocol_t *)p1_arg;
319         const protocol_t *p2 = (const protocol_t *)p2_arg;
320
321         return g_ascii_strcasecmp(p1->short_name, p2->short_name);
322 }
323
324
325 /* initialize data structures and register protocols and fields */
326 void
327 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
328            void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
329            register_cb cb,
330            gpointer client_data)
331 {
332         proto_cleanup();
333
334         proto_names        = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
335         proto_short_names  = g_hash_table_new(wrs_str_hash, g_str_equal);
336         proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
337
338         gpa_hfinfo.len           = 0;
339         gpa_hfinfo.allocated_len = 0;
340         gpa_hfinfo.hfi           = NULL;
341         gpa_name_tree            = g_tree_new_full(wrs_strcmp_with_data, NULL, NULL, save_same_name_hfinfo);
342
343         /* Initialize the ftype subsystem */
344         ftypes_initialize();
345
346         /* Register one special-case FT_TEXT_ONLY field for use when
347            converting wireshark to new-style proto_tree. These fields
348            are merely strings on the GUI tree; they are not filterable */
349         hf_text_only = proto_register_field_init(&hfi_text_only, -1);
350
351         /* Register the pseudo-protocols used for exceptions. */
352         register_show_exception();
353         register_type_length_mismatch();
354
355         /* Have each built-in dissector register its protocols, fields,
356            dissector tables, and dissectors to be called through a
357            handle, and do whatever one-time initialization it needs to
358            do. */
359         register_all_protocols_func(cb, client_data);
360 #ifdef HAVE_PYTHON
361         /* Now scan for python protocols */
362         if (cb)
363                 (*cb)(RA_PYTHON_REGISTER, NULL, client_data);
364         register_all_py_protocols_func();
365 #endif
366
367 #ifdef HAVE_PLUGINS
368         /* Now scan for plugins and load all the ones we find, calling
369            their register routines to do the stuff described above. */
370         if (cb)
371                 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
372         init_plugins();
373         register_all_plugin_registrations();
374 #endif
375
376         /* Now call the "handoff registration" routines of all built-in
377            dissectors; those routines register the dissector in other
378            dissectors' handoff tables, and fetch any dissector handles
379            they need. */
380         register_all_handoffs_func(cb, client_data);
381
382 #ifdef HAVE_PYTHON
383         /* Now do the same with python dissectors */
384         if (cb)
385                 (*cb)(RA_PYTHON_HANDOFF, NULL, client_data);
386         register_all_py_handoffs_func();
387 #endif
388
389 #ifdef HAVE_PLUGINS
390         /* Now do the same with plugins. */
391         if (cb)
392                 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
393         register_all_plugin_handoffs();
394 #endif
395
396         /* sort the protocols by protocol name */
397         protocols = g_list_sort(protocols, proto_compare_name);
398
399         /* We've assigned all the subtree type values; allocate the array
400            for them, and zero it out. */
401         tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
402 }
403
404 void
405 proto_cleanup(void)
406 {
407         /* Free the abbrev/ID GTree */
408         if (gpa_name_tree) {
409                 g_tree_destroy(gpa_name_tree);
410                 gpa_name_tree = NULL;
411         }
412
413         while (protocols) {
414                 protocol_t        *protocol = (protocol_t *)protocols->data;
415                 header_field_info *hfinfo;
416                 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
417                 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
418
419                 g_slice_free(header_field_info, hfinfo);
420                 g_slist_free(protocol->fields);
421                 protocols = g_list_remove(protocols, protocol);
422                 g_free(protocol);
423         }
424
425         if (proto_names) {
426                 g_hash_table_destroy(proto_names);
427                 proto_names = NULL;
428         }
429
430         if (proto_short_names) {
431                 g_hash_table_destroy(proto_short_names);
432                 proto_short_names = NULL;
433         }
434
435         if (proto_filter_names) {
436                 g_hash_table_destroy(proto_filter_names);
437                 proto_filter_names = NULL;
438         }
439
440         if (gpa_hfinfo.allocated_len) {
441                 gpa_hfinfo.len           = 0;
442                 gpa_hfinfo.allocated_len = 0;
443                 g_free(gpa_hfinfo.hfi);
444                 gpa_hfinfo.hfi           = NULL;
445         }
446         g_free(tree_is_expanded);
447         tree_is_expanded = NULL;
448 }
449
450 static gboolean
451 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
452                               gpointer data)
453 {
454         proto_node *pnode = tree;
455         proto_node *child;
456         proto_node *current;
457
458         if (func(pnode, data))
459                 return TRUE;
460
461         child = pnode->first_child;
462         while (child != NULL) {
463                 /*
464                  * The routine we call might modify the child, e.g. by
465                  * freeing it, so we get the child's successor before
466                  * calling that routine.
467                  */
468                 current = child;
469                 child   = current->next;
470                 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
471                         return TRUE;
472         }
473
474         return FALSE;
475 }
476
477 gboolean
478 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
479                                gpointer data)
480 {
481         proto_node *pnode = tree;
482         proto_node *child;
483         proto_node *current;
484
485         child = pnode->first_child;
486         while (child != NULL) {
487                 /*
488                  * The routine we call might modify the child, e.g. by
489                  * freeing it, so we get the child's successor before
490                  * calling that routine.
491                  */
492                 current = child;
493                 child   = current->next;
494                 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
495                         return TRUE;
496         }
497         if (func(pnode, data))
498                 return TRUE;
499
500         return FALSE;
501 }
502
503 void
504 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
505                             gpointer data)
506 {
507         proto_node *node = tree;
508         proto_node *current;
509
510         if (!node)
511                 return;
512
513         node = node->first_child;
514         while (node != NULL) {
515                 current = node;
516                 node    = current->next;
517                 func((proto_tree *)current, data);
518         }
519 }
520
521 static void
522 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
523 {
524         GPtrArray         *ptrs = (GPtrArray *)value;
525         gint               hfid = (gint)(long)key;
526         header_field_info *hfinfo;
527
528         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
529         if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
530                 /* when a field is referenced by a filter this also
531                    affects the refcount for the parent protocol so we need
532                    to adjust the refcount for the parent as well
533                 */
534                 if (hfinfo->parent != -1) {
535                         header_field_info *parent_hfinfo;
536                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
537                         parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
538                 }
539                 hfinfo->ref_type = HF_REF_TYPE_NONE;
540         }
541
542         g_ptr_array_free(ptrs, TRUE);
543 }
544
545 static void
546 proto_tree_free_node(proto_node *node, gpointer data _U_)
547 {
548         field_info *finfo  = PNODE_FINFO(node);
549
550         proto_tree_children_foreach(node, proto_tree_free_node, NULL);
551
552         FVALUE_CLEANUP(&finfo->value);
553 }
554
555 /* frees the resources that the dissection a proto_tree uses */
556 void
557 proto_tree_free(proto_tree *tree)
558 {
559         wmem_allocator_t *pool = PNODE_POOL(tree);
560         tree_data_t *tree_data = PTREE_DATA(tree);
561
562         proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
563
564         /* free tree data */
565         if (tree_data->interesting_hfids) {
566                 /* Free all the GPtrArray's in the interesting_hfids hash. */
567                 g_hash_table_foreach(tree_data->interesting_hfids,
568                         free_GPtrArray_value, NULL);
569
570                 /* And then destroy the hash. */
571                 g_hash_table_destroy(tree_data->interesting_hfids);
572         }
573
574         if (tree_pool_cache) {
575                 /* if we already have one cached then just destroy it */
576                 wmem_destroy_allocator(pool);
577         }
578         else {
579                 wmem_free_all(pool);
580                 tree_pool_cache = pool;
581         }
582 }
583
584 /* Is the parsing being done for a visible proto_tree or an invisible one?
585  * By setting this correctly, the proto_tree creation is sped up by not
586  * having to call g_vsnprintf and copy strings around.
587  */
588 gboolean
589 proto_tree_set_visible(proto_tree *tree, gboolean visible)
590 {
591         gboolean old_visible = PTREE_DATA(tree)->visible;
592
593         PTREE_DATA(tree)->visible = visible;
594
595         return old_visible;
596 }
597
598 void
599 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
600 {
601         PTREE_DATA(tree)->fake_protocols = fake_protocols;
602 }
603
604 /* Assume dissector set only its protocol fields.
605    This function is called by dissectors and allows the speeding up of filtering
606    in wireshark; if this function returns FALSE it is safe to reset tree to NULL
607    and thus skip calling most of the expensive proto_tree_add_...()
608    functions.
609    If the tree is visible we implicitly assume the field is referenced.
610 */
611 gboolean
612 proto_field_is_referenced(proto_tree *tree, int proto_id)
613 {
614         register header_field_info *hfinfo;
615
616
617         if (!tree)
618                 return FALSE;
619
620         if (PTREE_DATA(tree)->visible)
621                 return TRUE;
622
623         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
624         if (hfinfo->ref_type != HF_REF_TYPE_NONE)
625                 return TRUE;
626
627         if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
628                 return TRUE;
629
630         return FALSE;
631 }
632
633
634 /* Finds a record in the hfinfo array by id. */
635 header_field_info *
636 proto_registrar_get_nth(guint hfindex)
637 {
638         register header_field_info *hfinfo;
639
640         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
641         return hfinfo;
642 }
643
644
645 /*      Prefix initialization
646  *        this allows for a dissector to register a display filter name prefix
647  *        so that it can delay the initialization of the hf array as long as
648  *        possible.
649  */
650
651 /* compute a hash for the part before the dot of a display filter */
652 static guint
653 prefix_hash (gconstpointer key) {
654         /* end the string at the dot and compute its hash */
655         gchar* copy = ep_strdup((const gchar *)key);
656         gchar* c    = copy;
657
658         for (; *c; c++) {
659                 if (*c == '.') {
660                         *c = 0;
661                         break;
662                 }
663         }
664
665         return g_str_hash(copy);
666 }
667
668 /* are both strings equal up to the end or the dot? */
669 static gboolean
670 prefix_equal (gconstpointer ap, gconstpointer bp) {
671         const gchar* a = (const gchar *)ap;
672         const gchar* b = (const gchar *)bp;
673
674         do {
675                 gchar ac = *a++;
676                 gchar bc = *b++;
677
678                 if ( (ac == '.' || ac == '\0') &&   (bc == '.' || bc == '\0') ) return TRUE;
679
680                 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
681                 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
682
683                 if (ac != bc) return FALSE;
684         } while (1);
685
686         return FALSE;
687 }
688
689
690 /* indexed by prefix, contains initializers */
691 static GHashTable* prefixes = NULL;
692
693
694 /* Register a new prefix for "delayed" initialization of field arrays */
695 void
696 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
697         if (! prefixes ) {
698                 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
699         }
700
701         g_hash_table_insert(prefixes, (gpointer)prefix, pi);
702 }
703
704 /* helper to call all prefix initializers */
705 static gboolean
706 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
707         ((prefix_initializer_t)v)((const char *)k);
708         return TRUE;
709 }
710
711 /** Initialize every remaining uninitialized prefix. */
712 void
713 proto_initialize_all_prefixes(void) {
714         g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
715 }
716
717 /* Finds a record in the hfinfo array by name.
718  * If it fails to find it in the already registered fields,
719  * it tries to find and call an initializer in the prefixes
720  * table and if so it looks again.
721  */
722 header_field_info *
723 proto_registrar_get_byname(const char *field_name)
724 {
725         header_field_info    *hfinfo;
726         prefix_initializer_t  pi;
727
728         if (!field_name)
729                 return NULL;
730
731         hfinfo = (header_field_info *)g_tree_lookup(gpa_name_tree, field_name);
732
733         if (hfinfo)
734                 return hfinfo;
735
736         if (!prefixes)
737                 return NULL;
738
739         if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
740                 pi(field_name);
741                 g_hash_table_remove(prefixes, field_name);
742         } else {
743                 return NULL;
744         }
745
746         return (header_field_info *)g_tree_lookup(gpa_name_tree, field_name);
747 }
748
749 int
750 proto_registrar_get_id_byname(const char *field_name)
751 {
752         header_field_info *hfinfo;
753
754         hfinfo = proto_registrar_get_byname(field_name);
755
756         if (!hfinfo)
757                 return -1;
758
759         return hfinfo->id;
760 }
761
762
763 static void
764 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
765 {
766         subtree_lvl *pushed_tree;
767
768         DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
769         ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
770
771         pushed_tree = (subtree_lvl *)ep_alloc(sizeof(subtree_lvl) * ptvc->pushed_tree_max);
772         DISSECTOR_ASSERT(pushed_tree != NULL);
773         if (ptvc->pushed_tree)
774                 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
775         ptvc->pushed_tree = pushed_tree;
776 }
777
778 static void
779 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
780 {
781         ptvc->pushed_tree       = NULL;
782         ptvc->pushed_tree_max   = 0;
783         DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
784         ptvc->pushed_tree_index = 0;
785 }
786
787 /* Allocates an initializes a ptvcursor_t with 3 variables:
788  *      proto_tree, tvbuff, and offset. */
789 ptvcursor_t *
790 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
791 {
792         ptvcursor_t *ptvc;
793
794         ptvc                    = (ptvcursor_t *)ep_alloc(sizeof(ptvcursor_t));
795         ptvc->tree              = tree;
796         ptvc->tvb               = tvb;
797         ptvc->offset            = offset;
798         ptvc->pushed_tree       = NULL;
799         ptvc->pushed_tree_max   = 0;
800         ptvc->pushed_tree_index = 0;
801         return ptvc;
802 }
803
804
805 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
806 void
807 ptvcursor_free(ptvcursor_t *ptvc)
808 {
809         ptvcursor_free_subtree_levels(ptvc);
810         /*g_free(ptvc);*/
811 }
812
813 /* Returns tvbuff. */
814 tvbuff_t *
815 ptvcursor_tvbuff(ptvcursor_t *ptvc)
816 {
817         return ptvc->tvb;
818 }
819
820 /* Returns current offset. */
821 gint
822 ptvcursor_current_offset(ptvcursor_t *ptvc)
823 {
824         return ptvc->offset;
825 }
826
827 proto_tree *
828 ptvcursor_tree(ptvcursor_t *ptvc)
829 {
830         if (!ptvc)
831                 return NULL;
832
833         return ptvc->tree;
834 }
835
836 void
837 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
838 {
839         ptvc->tree = tree;
840 }
841
842 /* creates a subtree, sets it as the working tree and pushes the old working tree */
843 proto_tree *
844 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
845 {
846         subtree_lvl *subtree;
847         if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
848                 ptvcursor_new_subtree_levels(ptvc);
849
850         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
851         subtree->tree = ptvc->tree;
852         subtree->it= NULL;
853         ptvc->pushed_tree_index++;
854         return ptvcursor_set_subtree(ptvc, it, ett_subtree);
855 }
856
857 /* pops a subtree */
858 void
859 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
860 {
861         subtree_lvl *subtree;
862
863         if (ptvc->pushed_tree_index <= 0)
864                 return;
865
866         ptvc->pushed_tree_index--;
867         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
868         if (subtree->it != NULL)
869                 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
870
871         ptvc->tree = subtree->tree;
872 }
873
874 /* saves the current tvb offset and the item in the current subtree level */
875 static void
876 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
877 {
878         subtree_lvl *subtree;
879
880         DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
881
882         subtree                = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
883         subtree->it            = it;
884         subtree->cursor_offset = ptvcursor_current_offset(ptvc);
885 }
886
887 /* Creates a subtree and adds it to the cursor as the working tree but does not
888  * save the old working tree */
889 proto_tree *
890 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
891 {
892         ptvc->tree = proto_item_add_subtree(it, ett_subtree);
893         return ptvc->tree;
894 }
895
896 static proto_tree *
897 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
898 {
899         ptvcursor_push_subtree(ptvc, it, ett_subtree);
900         if (length == SUBTREE_UNDEFINED_LENGTH)
901                 ptvcursor_subtree_set_item(ptvc, it);
902         return ptvcursor_tree(ptvc);
903 }
904
905 /* Add an item to the tree and create a subtree
906  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
907  * In this case, when the subtree will be closed, the parent item length will
908  * be equal to the advancement of the cursor since the creation of the subtree.
909  */
910 proto_tree *
911 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
912                            const guint encoding, gint ett_subtree)
913 {
914         proto_item *it;
915
916         it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
917         return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
918 }
919
920 static proto_item *
921 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
922
923 /* Add a text node to the tree and create a subtree
924  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
925  * In this case, when the subtree will be closed, the item length will be equal
926  * to the advancement of the cursor since the creation of the subtree.
927  */
928 proto_tree *
929 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
930                                 gint ett_subtree, const char *format, ...)
931 {
932         proto_item        *pi;
933         va_list            ap;
934         header_field_info *hfinfo;
935         proto_tree        *tree;
936
937         tree = ptvcursor_tree(ptvc);
938
939         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
940
941         pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
942                                       ptvcursor_current_offset(ptvc), length);
943
944         TRY_TO_FAKE_THIS_REPR(pi);
945
946         va_start(ap, format);
947         proto_tree_set_representation(pi, format, ap);
948         va_end(ap);
949
950         return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
951 }
952
953 /* Add a text-only node, leaving it to our caller to fill the text in */
954 static proto_item *
955 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
956 {
957         proto_item *pi;
958
959         if (tree == NULL)
960                 return NULL;
961
962         pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
963
964         return pi;
965 }
966
967 /* Add a text-only node to the proto_tree */
968 proto_item *
969 proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
970                     const char *format, ...)
971 {
972         proto_item        *pi;
973         va_list            ap;
974         header_field_info *hfinfo;
975
976         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
977
978         pi = proto_tree_add_text_node(tree, tvb, start, length);
979
980         TRY_TO_FAKE_THIS_REPR(pi);
981
982         va_start(ap, format);
983         proto_tree_set_representation(pi, format, ap);
984         va_end(ap);
985
986         return pi;
987 }
988
989 /* Add a text-only node to the proto_tree (va_list version) */
990 proto_item *
991 proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start,
992                            gint length, const char *format, va_list ap)
993 {
994         proto_item        *pi;
995         header_field_info *hfinfo;
996
997         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
998
999         pi = proto_tree_add_text_node(tree, tvb, start, length);
1000
1001         TRY_TO_FAKE_THIS_REPR(pi);
1002
1003         proto_tree_set_representation(pi, format, ap);
1004
1005         return pi;
1006 }
1007
1008 /* Add a text-only node for debugging purposes. The caller doesn't need
1009  * to worry about tvbuff, start, or length. Debug message gets sent to
1010  * STDOUT, too */
1011 proto_item *
1012 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1013 {
1014         proto_item *pi;
1015         va_list     ap;
1016
1017         pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1018
1019         if (pi) {
1020                 va_start(ap, format);
1021                 proto_tree_set_representation(pi, format, ap);
1022                 va_end(ap);
1023         }
1024         va_start(ap, format);
1025         vprintf(format, ap);
1026         va_end(ap);
1027         printf("\n");
1028
1029         return pi;
1030 }
1031
1032 /* We could probably get away with changing is_error to a minimum length value. */
1033 static void
1034 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1035
1036         if (is_error) {
1037                 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1038         } else {
1039                 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1040         }
1041
1042         if (is_error) {
1043                 THROW(ReportedBoundsError);
1044         }
1045 }
1046
1047 static guint32
1048 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1049 {
1050         guint32 value;
1051         gboolean length_error;
1052
1053         switch (length) {
1054
1055         case 1:
1056                 value = tvb_get_guint8(tvb, offset);
1057                 break;
1058
1059         case 2:
1060                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1061                                                        : tvb_get_ntohs(tvb, offset);
1062                 break;
1063
1064         case 3:
1065                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1066                                                        : tvb_get_ntoh24(tvb, offset);
1067                 break;
1068
1069         case 4:
1070                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1071                                                        : tvb_get_ntohl(tvb, offset);
1072                 break;
1073
1074         default:
1075                 if (length < 1) {
1076                         length_error = TRUE;
1077                         value = 0;
1078                 } else {
1079                         length_error = FALSE;
1080                         value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1081                                                                : tvb_get_ntohl(tvb, offset);
1082                 }
1083                 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1084                 break;
1085         }
1086         return value;
1087 }
1088
1089 /*
1090  * NOTE: to support code written when proto_tree_add_item() took a
1091  * gboolean as its last argument, with FALSE meaning "big-endian"
1092  * and TRUE meaning "little-endian", we treat any non-zero value of
1093  * "encoding" as meaning "little-endian".
1094  */
1095 static gint32
1096 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1097 {
1098         gint32 value;
1099         gboolean length_error;
1100
1101         switch (length) {
1102
1103         case 1:
1104                 value = (gint8)tvb_get_guint8(tvb, offset);
1105                 break;
1106
1107         case 2:
1108                 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1109                                            : tvb_get_ntohs(tvb, offset));
1110                 break;
1111
1112         case 3:
1113                 value = encoding ? tvb_get_letoh24(tvb, offset)
1114                                  : tvb_get_ntoh24(tvb, offset);
1115                 if (value & 0x00800000) {
1116                         /* Sign bit is set; sign-extend it. */
1117                         value |= 0xFF000000;
1118                 }
1119                 break;
1120
1121         case 4:
1122                 value = encoding ? tvb_get_letohl(tvb, offset)
1123                                  : tvb_get_ntohl(tvb, offset);
1124                 break;
1125
1126         default:
1127                 if (length < 1) {
1128                         length_error = TRUE;
1129                         value = 0;
1130                 } else {
1131                         length_error = FALSE;
1132                         value = encoding ? tvb_get_letohl(tvb, offset)
1133                                          : tvb_get_ntohl(tvb, offset);
1134                 }
1135                 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1136                 break;
1137         }
1138         return value;
1139 }
1140
1141 static void
1142 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
1143 {
1144         const header_field_info *hfinfo = fi->hfinfo;
1145
1146         if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
1147                 GPtrArray *ptrs = NULL;
1148
1149                 if (tree_data->interesting_hfids == NULL) {
1150                         /* Initialize the hash because we now know that it is needed */
1151                         tree_data->interesting_hfids =
1152                                 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
1153                 } else
1154                         ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
1155                                            GINT_TO_POINTER(hfinfo->id));
1156                 if (!ptrs) {
1157                         /* First element triggers the creation of pointer array */
1158                         ptrs = g_ptr_array_new();
1159                         g_hash_table_insert(tree_data->interesting_hfids,
1160                                             GINT_TO_POINTER(hfinfo->id), ptrs);
1161                 }
1162
1163                 g_ptr_array_add(ptrs, fi);
1164         }
1165 }
1166
1167 /* Add an item to a proto_tree, using the text label registered to that item;
1168    the item is extracted from the tvbuff handed to it. */
1169 static proto_item *
1170 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
1171                     tvbuff_t *tvb, gint start, gint length,
1172                     guint encoding)
1173 {
1174         proto_item *pi;
1175         guint32     value, n;
1176         float       floatval;
1177         double      doubleval;
1178         const char *string;
1179         nstime_t    time_stamp;
1180         guint32     tmpsecs;
1181         guint64     todsecs;
1182         gboolean    length_error;
1183
1184         switch (new_fi->hfinfo->type) {
1185                 case FT_NONE:
1186                         /* no value to set for FT_NONE */
1187                         break;
1188
1189                 case FT_PROTOCOL:
1190                         proto_tree_set_protocol_tvb(new_fi, tvb);
1191                         break;
1192
1193                 case FT_BYTES:
1194                         proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
1195                         break;
1196
1197                 case FT_UINT_BYTES:
1198                         /*
1199                          * Map all non-zero values to little-endian for
1200                          * backwards compatibility.
1201                          */
1202                         if (encoding)
1203                                 encoding = ENC_LITTLE_ENDIAN;
1204                         n = get_uint_value(tree, tvb, start, length, encoding);
1205                         proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
1206
1207                         /* Instead of calling proto_item_set_len(), since we don't yet
1208                          * have a proto_item, we set the field_info's length ourselves. */
1209                         new_fi->length = n + length;
1210                         break;
1211
1212                 case FT_BOOLEAN:
1213                         /*
1214                          * Map all non-zero values to little-endian for
1215                          * backwards compatibility.
1216                          */
1217                         if (encoding)
1218                                 encoding = ENC_LITTLE_ENDIAN;
1219                         proto_tree_set_boolean(new_fi,
1220                                 get_uint_value(tree, tvb, start, length, encoding));
1221                         break;
1222
1223                 /* XXX - make these just FT_UINT? */
1224                 case FT_UINT8:
1225                 case FT_UINT16:
1226                 case FT_UINT24:
1227                 case FT_UINT32:
1228                         /*
1229                          * Map all non-zero values to little-endian for
1230                          * backwards compatibility.
1231                          */
1232                         if (encoding)
1233                                 encoding = ENC_LITTLE_ENDIAN;
1234                         proto_tree_set_uint(new_fi,
1235                                 get_uint_value(tree, tvb, start, length, encoding));
1236                         break;
1237
1238                 case FT_INT64:
1239                 case FT_UINT64:
1240                         /*
1241                          * Map all non-zero values to little-endian for
1242                          * backwards compatibility.
1243                          */
1244                         if (encoding)
1245                                 encoding = ENC_LITTLE_ENDIAN;
1246                         if (length < 1 || length > 8) {
1247                                 length_error = length < 1 ? TRUE : FALSE;
1248                                 report_type_length_mismatch(tree, "a 64-bit integer", length, length_error);
1249                         }
1250                         proto_tree_set_uint64_tvb(new_fi, tvb, start, length, encoding);
1251                         break;
1252
1253                 /* XXX - make these just FT_INT? */
1254                 case FT_INT8:
1255                 case FT_INT16:
1256                 case FT_INT24:
1257                 case FT_INT32:
1258                         /*
1259                          * Map all non-zero values to little-endian for
1260                          * backwards compatibility.
1261                          */
1262                         if (encoding)
1263                                 encoding = ENC_LITTLE_ENDIAN;
1264                         proto_tree_set_int(new_fi,
1265                                 get_int_value(tree, tvb, start, length, encoding));
1266                         break;
1267
1268                 case FT_IPv4:
1269                         /*
1270                          * Map all non-zero values to little-endian for
1271                          * backwards compatibility.
1272                          */
1273                         if (encoding)
1274                                 encoding = ENC_LITTLE_ENDIAN;
1275                         if (length != FT_IPv4_LEN) {
1276                                 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
1277                                 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
1278                         }
1279                         value = tvb_get_ipv4(tvb, start);
1280                         /*
1281                          * NOTE: to support code written when
1282                          * proto_tree_add_item() took a gboolean as its
1283                          * last argument, with FALSE meaning "big-endian"
1284                          * and TRUE meaning "little-endian", we treat any
1285                          * non-zero value of "encoding" as meaning
1286                          * "little-endian".
1287                          */
1288                         proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
1289                         break;
1290
1291                 case FT_IPXNET:
1292                         if (length != FT_IPXNET_LEN) {
1293                                 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
1294                                 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
1295                         }
1296                         proto_tree_set_ipxnet(new_fi,
1297                                 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
1298                         break;
1299
1300                 case FT_IPv6:
1301                         if (length != FT_IPv6_LEN) {
1302                                 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
1303                                 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
1304                         }
1305                         proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
1306                         break;
1307
1308                 case FT_AX25:
1309                         if (length != 7) {
1310                                 length_error = length < 7 ? TRUE : FALSE;
1311                                 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
1312                         }
1313                         proto_tree_set_ax25_tvb(new_fi, tvb, start);
1314                         break;
1315
1316                 case FT_VINES:
1317                         if (length != VINES_ADDR_LEN) {
1318                                 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
1319                                 report_type_length_mismatch(tree, "a Vines address", length, length_error);
1320                         }
1321                         proto_tree_set_vines_tvb(new_fi, tvb, start);
1322                         break;
1323
1324                 case FT_ETHER:
1325                         if (length != FT_ETHER_LEN) {
1326                                 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
1327                                 report_type_length_mismatch(tree, "an Ethernet", length, length_error);
1328                         }
1329                         proto_tree_set_ether_tvb(new_fi, tvb, start);
1330                         break;
1331
1332                 case FT_EUI64:
1333                         /*
1334                          * Map all non-zero values to little-endian for
1335                          * backwards compatibility.
1336                          */
1337                         if (encoding)
1338                                 encoding = ENC_LITTLE_ENDIAN;
1339                         if (length != FT_EUI64_LEN) {
1340                                 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
1341                                 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
1342                         }
1343                         proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
1344                         break;
1345                 case FT_GUID:
1346                         /*
1347                          * Map all non-zero values to little-endian for
1348                          * backwards compatibility.
1349                          */
1350                         if (encoding)
1351                                 encoding = ENC_LITTLE_ENDIAN;
1352                         if (length != FT_GUID_LEN) {
1353                                 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
1354                                 report_type_length_mismatch(tree, "a GUID", length, length_error);
1355                         }
1356                         proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
1357                         break;
1358
1359                 case FT_OID:
1360                 case FT_REL_OID:
1361                         proto_tree_set_oid_tvb(new_fi, tvb, start, length);
1362                         break;
1363
1364                 case FT_FLOAT:
1365                         /*
1366                          * NOTE: to support code written when
1367                          * proto_tree_add_item() took a gboolean as its
1368                          * last argument, with FALSE meaning "big-endian"
1369                          * and TRUE meaning "little-endian", we treat any
1370                          * non-zero value of "encoding" as meaning
1371                          * "little-endian".
1372                          *
1373                          * At some point in the future, we might
1374                          * support non-IEEE-binary floating-point
1375                          * formats in the encoding as well
1376                          * (IEEE decimal, System/3x0, VAX).
1377                          */
1378                         if (encoding)
1379                                 encoding = ENC_LITTLE_ENDIAN;
1380                         if (length != 4) {
1381                                 length_error = length < 4 ? TRUE : FALSE;
1382                                 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
1383                         }
1384                         if (encoding)
1385                                 floatval = tvb_get_letohieee_float(tvb, start);
1386                         else
1387                                 floatval = tvb_get_ntohieee_float(tvb, start);
1388                         proto_tree_set_float(new_fi, floatval);
1389                         break;
1390
1391                 case FT_DOUBLE:
1392                         /*
1393                          * NOTE: to support code written when
1394                          * proto_tree_add_item() took a gboolean as its
1395                          * last argument, with FALSE meaning "big-endian"
1396                          * and TRUE meaning "little-endian", we treat any
1397                          * non-zero value of "encoding" as meaning
1398                          * "little-endian".
1399                          *
1400                          * At some point in the future, we might
1401                          * support non-IEEE-binary floating-point
1402                          * formats in the encoding as well
1403                          * (IEEE decimal, System/3x0, VAX).
1404                          */
1405                         if (encoding == TRUE)
1406                                 encoding = ENC_LITTLE_ENDIAN;
1407                         if (length != 8) {
1408                                 length_error = length < 8 ? TRUE : FALSE;
1409                                 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
1410                         }
1411                         if (encoding)
1412                                 doubleval = tvb_get_letohieee_double(tvb, start);
1413                         else
1414                                 doubleval = tvb_get_ntohieee_double(tvb, start);
1415                         proto_tree_set_double(new_fi, doubleval);
1416                         break;
1417
1418                 case FT_STRING:
1419                         proto_tree_set_string_tvb(new_fi, tvb, start, length,
1420                             encoding);
1421                         break;
1422
1423                 case FT_STRINGZ:
1424                         if (length < -1 ) {
1425                                 report_type_length_mismatch(tree, "a string", length, TRUE);
1426                         }
1427                         /* Instead of calling proto_item_set_len(),
1428                          * since we don't yet have a proto_item, we
1429                          * set the field_info's length ourselves.
1430                          *
1431                          * XXX - our caller can't use that length to
1432                          * advance an offset unless they arrange that
1433                          * there always be a protocol tree into which
1434                          * we're putting this item.
1435                          */
1436                         if (length == -1) {
1437                                 /* This can throw an exception */
1438                                 string = tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
1439                         } else if (length == 0) {
1440                                 string = "[Empty]";
1441                         } else {
1442                                 /* In this case, length signifies
1443                                  * the length of the string.
1444                                  *
1445                                  * This could either be a null-padded
1446                                  * string, which doesn't necessarily
1447                                  * have a '\0' at the end, or a
1448                                  * null-terminated string, with a
1449                                  * trailing '\0'.  (Yes, there are
1450                                  * cases where you have a string
1451                                  * that's both counted and null-
1452                                  * terminated.)
1453                                  *
1454                                  * In the first case, we must
1455                                  * allocate a buffer of length
1456                                  * "length+1", to make room for
1457                                  * a trailing '\0'.
1458                                  *
1459                                  * In the second case, we don't
1460                                  * assume that there is a trailing
1461                                  * '\0' there, as the packet might
1462                                  * be malformed.  (XXX - should we
1463                                  * throw an exception if there's no
1464                                  * trailing '\0'?)      Therefore, we
1465                                  * allocate a buffer of length
1466                                  * "length+1", and put in a trailing
1467                                  * '\0', just to be safe.
1468                                  *
1469                                  * (XXX - this would change if
1470                                  * we made string values counted
1471                                  * rather than null-terminated.)
1472                                  */
1473                                 string = tvb_get_string_enc(wmem_packet_scope(), tvb, start, length, encoding);
1474                         }
1475                         new_fi->length = length;
1476                         proto_tree_set_string(new_fi, string);
1477                         break;
1478
1479                 case FT_UINT_STRING:
1480                         /*
1481                          * NOTE: to support code written when
1482                          * proto_tree_add_item() took a gboolean as its
1483                          * last argument, with FALSE meaning "big-endian"
1484                          * and TRUE meaning "little-endian", if the
1485                          * encoding value is TRUE, treat that as
1486                          * ASCII with a little-endian length.
1487                          *
1488                          * This won't work for code that passes
1489                          * arbitrary non-zero values; that code
1490                          * will need to be fixed.
1491                          */
1492                         if (encoding == TRUE)
1493                                 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
1494                         n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1495                         proto_tree_set_string_tvb(new_fi, tvb, start + length, n,
1496                             encoding);
1497
1498                         /* Instead of calling proto_item_set_len(), since we
1499                          * don't yet have a proto_item, we set the
1500                          * field_info's length ourselves.
1501                          *
1502                          * XXX - our caller can't use that length to
1503                          * advance an offset unless they arrange that
1504                          * there always be a protocol tree into which
1505                          * we're putting this item.
1506                          */
1507                         new_fi->length = n + length;
1508                         break;
1509
1510                 case FT_ABSOLUTE_TIME:
1511                         /*
1512                          * Absolute times can be in any of a number of
1513                          * formats, and they can be big-endian or
1514                          * little-endian.
1515                          *
1516                          * Historically FT_TIMEs were only timespecs;
1517                          * the only question was whether they were stored
1518                          * in big- or little-endian format.
1519                          *
1520                          * For backwards compatibility, we interpret an
1521                          * encoding of 1 as meaning "little-endian timespec",
1522                          * so that passing TRUE is interpreted as that.
1523                          */
1524                         if (encoding == TRUE)
1525                                 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
1526
1527                         if (length != 8 && length != 4) {
1528                                 length_error = length < 4 ? TRUE : FALSE;
1529                                 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
1530                         }
1531
1532                         switch (encoding) {
1533
1534                         case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1535                                 /*
1536                                  * 4-byte UNIX epoch, possibly followed by
1537                                  * 4-byte fractional time in nanoseconds,
1538                                  * both big-endian.
1539                                  */
1540                                 time_stamp.secs  = tvb_get_ntohl(tvb, start);
1541                                 if (length == 8)
1542                                         time_stamp.nsecs = tvb_get_ntohl(tvb, start+4);
1543                                 else
1544                                         time_stamp.nsecs = 0;
1545                                 break;
1546
1547                         case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1548                                 /*
1549                                  * 4-byte UNIX epoch, possibly followed by
1550                                  * 4-byte fractional time in nanoseconds,
1551                                  * both little-endian.
1552                                  */
1553                                 time_stamp.secs  = tvb_get_letohl(tvb, start);
1554                                 if (length == 8)
1555                                         time_stamp.nsecs = tvb_get_letohl(tvb, start+4);
1556                                 else
1557                                         time_stamp.nsecs = 0;
1558                                 break;
1559
1560                         case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1561                                 /*
1562                                  * TOD time stamp, big-endian.
1563                                  */
1564 /* XXX - where should this go? */
1565 #define TOD_BASETIME 2208988800ul
1566
1567                                 todsecs  = tvb_get_ntoh64(tvb, start) >> 12;
1568                                 time_stamp.secs = (time_t)((todsecs  / 1000000) - TOD_BASETIME);
1569                                 time_stamp.nsecs = (int)((todsecs  % 1000000) * 1000);
1570                                 break;
1571
1572                         case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1573                                 /*
1574                                  * TOD time stamp, big-endian.
1575                                  */
1576                                 todsecs  = tvb_get_letoh64(tvb, start) >> 12 ;
1577                                 time_stamp.secs = (time_t)((todsecs  / 1000000) - TOD_BASETIME);
1578                                 time_stamp.nsecs = (int)((todsecs  % 1000000) * 1000);
1579                                 break;
1580
1581                         case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1582                                 /*
1583                                  * NTP time stamp, big-endian.
1584                                  */
1585
1586 /* XXX - where should this go? */
1587 #define NTP_BASETIME 2208988800ul
1588
1589                                 /* We need a temporary variable here so the unsigned math
1590                                  * works correctly (for years > 2036 according to RFC 2030
1591                                  * chapter 3).
1592                                  */
1593                                 tmpsecs  = tvb_get_ntohl(tvb, start);
1594                                 if (tmpsecs)
1595                                         time_stamp.secs = tmpsecs - (guint32)NTP_BASETIME;
1596                                 else
1597                                         time_stamp.secs = tmpsecs; /* 0 */
1598
1599                                 if (length == 8) {
1600                                         /*
1601                                          * We're using nanoseconds here (and we will
1602                                          * display nanoseconds), but NTP's timestamps
1603                                          * have a precision in microseconds or greater.
1604                                          * Round to 1 microsecond.
1605                                          */
1606                                         time_stamp.nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1607                                         time_stamp.nsecs *= 1000;
1608                                 } else {
1609                                         time_stamp.nsecs = 0;
1610                                 }
1611                                 break;
1612
1613                         case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1614                                 /*
1615                                  * NTP time stamp, big-endian.
1616                                  */
1617                                 tmpsecs  = tvb_get_letohl(tvb, start);
1618                                 if (tmpsecs)
1619                                         time_stamp.secs = tmpsecs - (guint32)NTP_BASETIME;
1620                                 else
1621                                         time_stamp.secs = tmpsecs; /* 0 */
1622
1623                                 if (length == 8) {
1624                                         /*
1625                                          * We're using nanoseconds here (and we will
1626                                          * display nanoseconds), but NTP's timestamps
1627                                          * have a precision in microseconds or greater.
1628                                          * Round to 1 microsecond.
1629                                          */
1630                                         time_stamp.nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1631                                         time_stamp.nsecs *= 1000;
1632                                 } else {
1633                                         time_stamp.nsecs = 0;
1634                                 }
1635                                 break;
1636
1637                         default:
1638                                 DISSECTOR_ASSERT_NOT_REACHED();
1639                                 time_stamp.secs = 0;
1640                                 time_stamp.nsecs = 0;
1641                                 break;
1642                         }
1643                         proto_tree_set_time(new_fi, &time_stamp);
1644                         break;
1645
1646                 case FT_RELATIVE_TIME:
1647                         /*
1648                          * Relative times can be in any of a number of
1649                          * formats, and they can be big-endian or
1650                          * little-endian.
1651                          *
1652                          * Historically FT_TIMEs were only timespecs;
1653                          * the only question was whether they were stored
1654                          * in big- or little-endian format.
1655                          *
1656                          * For backwards compatibility, we interpret an
1657                          * encoding of 1 as meaning "little-endian timespec",
1658                          * so that passing TRUE is interpreted as that.
1659                          */
1660                         if (encoding == TRUE)
1661                                 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
1662                         switch (encoding) {
1663
1664                         if (length != 8 && length != 4) {
1665                                 length_error = length < 4 ? TRUE : FALSE;
1666                                 report_type_length_mismatch(tree, "a relative time value", length, length_error);
1667                         }
1668
1669                         case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1670                                 /*
1671                                  * 4-byte UNIX epoch, possibly followed by
1672                                  * 4-byte fractional time in nanoseconds,
1673                                  * both big-endian.
1674                                  */
1675                                 time_stamp.secs  = tvb_get_ntohl(tvb, start);
1676                                 if (length == 8)
1677                                         time_stamp.nsecs = tvb_get_ntohl(tvb, start+4);
1678                                 else
1679                                         time_stamp.nsecs = 0;
1680                                 break;
1681
1682                         case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1683                                 /*
1684                                  * 4-byte UNIX epoch, possibly followed by
1685                                  * 4-byte fractional time in nanoseconds,
1686                                  * both little-endian.
1687                                  */
1688                                 time_stamp.secs  = tvb_get_letohl(tvb, start);
1689                                 if (length == 8)
1690                                         time_stamp.nsecs = tvb_get_letohl(tvb, start+4);
1691                                 else
1692                                         time_stamp.nsecs = 0;
1693                                 break;
1694                         }
1695                         proto_tree_set_time(new_fi, &time_stamp);
1696                         break;
1697
1698                 default:
1699                         g_error("new_fi->hfinfo->type %d (%s) not handled\n",
1700                                         new_fi->hfinfo->type,
1701                                         ftype_name(new_fi->hfinfo->type));
1702                         DISSECTOR_ASSERT_NOT_REACHED();
1703                         break;
1704         }
1705         FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
1706
1707         /* Don't add new node to proto_tree until now so that any exceptions
1708          * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
1709         /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
1710          *      to know which item caused exception? */
1711         pi = proto_tree_add_node(tree, new_fi);
1712
1713         return pi;
1714 }
1715
1716 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
1717    and returns proto_item* */
1718 proto_item *
1719 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
1720               const guint encoding)
1721 {
1722         field_info        *new_fi;
1723         header_field_info *hfinfo;
1724         gint               item_length;
1725         guint32            n;
1726         int                offset;
1727
1728         /* We can't fake it just yet. We have to advance the cursor
1729         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo); */
1730
1731         offset = ptvc->offset;
1732         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1733         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
1734         ptvc->offset += length;
1735         if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
1736                 /*
1737                  * The length of the rest of the item is in the first N
1738                  * bytes of the item.
1739                  */
1740                 n = get_uint_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
1741                 ptvc->offset += n;
1742         }
1743
1744         /* Coast clear. Try and fake it */
1745         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
1746
1747         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
1748
1749         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
1750                 offset, length, encoding);
1751 }
1752
1753 /*
1754  * Validates that field length bytes are available starting from
1755  * start (pos/neg). Throws an exception if they aren't.
1756  */
1757 static void
1758 test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb,
1759             gint start, gint length, const guint encoding)
1760 {
1761         gint size = length;
1762
1763         if (!tvb)
1764                 return;
1765
1766         if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
1767                 guint32 n;
1768
1769                 n = get_uint_value(tree, tvb, start, length, encoding);
1770                 if (n > size + n) {
1771                         /* If n > size + n then we have an integer overflow, so
1772                          * set size to -1, which will force the
1773                          * tvb_ensure_bytes_exist call below to throw a
1774                          * ReportedBoundsError
1775                          */
1776                         size = -1;
1777                 }
1778                 else {
1779                         size += n;
1780                 }
1781         } else if (hfinfo->type == FT_STRINGZ) {
1782                 /* If we're fetching until the end of the TVB, only validate
1783                  * that the offset is within range.
1784                  */
1785                 if (length == -1)
1786                         size = 0;
1787         }
1788
1789         tvb_ensure_bytes_exist(tvb, start, size);
1790 }
1791
1792 /* Add an item to a proto_tree, using the text label registered to that item;
1793    the item is extracted from the tvbuff handed to it. */
1794 proto_item *
1795 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
1796                     const gint start, gint length, const guint encoding)
1797 {
1798         field_info        *new_fi;
1799         gint              item_length;
1800
1801         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
1802
1803         get_hfi_length(hfinfo, tvb, start, &length, &item_length);
1804         test_length(hfinfo, tree, tvb, start, item_length, encoding);
1805
1806         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
1807
1808         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
1809
1810         if (new_fi == NULL)
1811                 return NULL;
1812
1813         return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
1814 }
1815
1816 proto_item *
1817 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1818                     const gint start, gint length, const guint encoding)
1819 {
1820         return proto_tree_add_item_new(tree, proto_registrar_get_nth(hfindex), tvb, start, length, encoding);
1821 }
1822
1823 /* Add a FT_NONE to a proto_tree */
1824 proto_item *
1825 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
1826                            const gint start, gint length, const char *format,
1827                            ...)
1828 {
1829         proto_item        *pi;
1830         va_list            ap;
1831         header_field_info *hfinfo;
1832
1833         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1834
1835         DISSECTOR_ASSERT(hfinfo->type == FT_NONE);
1836
1837         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
1838
1839         TRY_TO_FAKE_THIS_REPR(pi);
1840
1841         va_start(ap, format);
1842         proto_tree_set_representation(pi, format, ap);
1843         va_end(ap);
1844
1845         /* no value to set for FT_NONE */
1846         return pi;
1847 }
1848
1849 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
1850  * offset, and returns proto_item* */
1851 proto_item *
1852 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
1853                          const guint encoding)
1854 {
1855         proto_item *item;
1856
1857         item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
1858                                    length, encoding);
1859
1860         return item;
1861 }
1862
1863 /* Advance the ptvcursor's offset within its tvbuff without
1864  * adding anything to the proto_tree. */
1865 void
1866 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
1867 {
1868         ptvc->offset += length;
1869 }
1870
1871
1872 static void
1873 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
1874 {
1875         fvalue_set(&fi->value, tvb, TRUE);
1876 }
1877
1878 /* Add a FT_PROTOCOL to a proto_tree */
1879 proto_item *
1880 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1881                                gint start, gint length, const char *format, ...)
1882 {
1883         proto_item        *pi;
1884         va_list            ap;
1885         header_field_info *hfinfo;
1886
1887         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1888
1889         DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
1890
1891         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
1892
1893         proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset(tvb, start, length, length)));
1894
1895         TRY_TO_FAKE_THIS_REPR(pi);
1896
1897         va_start(ap, format);
1898         proto_tree_set_representation(pi, format, ap);
1899         va_end(ap);
1900
1901         return pi;
1902 }
1903
1904
1905 /* Add a FT_BYTES to a proto_tree */
1906 proto_item *
1907 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1908                      gint length, const guint8 *start_ptr)
1909 {
1910         proto_item        *pi;
1911         header_field_info *hfinfo;
1912
1913         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1914
1915         DISSECTOR_ASSERT(hfinfo->type == FT_BYTES);
1916
1917         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
1918         proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
1919
1920         return pi;
1921 }
1922
1923 proto_item *
1924 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1925                                   gint start, gint length,
1926                                   const guint8 *start_ptr,
1927                                   const char *format, ...)
1928 {
1929         proto_item        *pi;
1930         va_list            ap;
1931         header_field_info *hfinfo;
1932
1933         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1934
1935         if (start_ptr)
1936                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1937                                           start_ptr);
1938         else
1939                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1940                                           tvb_get_ptr(tvb, start, length));
1941
1942         va_start(ap, format);
1943         proto_tree_set_representation_value(pi, format, ap);
1944         va_end(ap);
1945
1946         return pi;
1947 }
1948
1949 proto_item *
1950 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1951                             gint start, gint length, const guint8 *start_ptr,
1952                             const char *format, ...)
1953 {
1954         proto_item        *pi;
1955         va_list            ap;
1956         header_field_info *hfinfo;
1957
1958         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1959
1960         if (start_ptr)
1961                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1962                                           start_ptr);
1963         else
1964                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1965                                           tvb_get_ptr(tvb, start, length));
1966
1967         TRY_TO_FAKE_THIS_REPR(pi);
1968
1969         va_start(ap, format);
1970         proto_tree_set_representation(pi, format, ap);
1971         va_end(ap);
1972
1973         return pi;
1974 }
1975
1976 static void
1977 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
1978 {
1979         GByteArray *bytes;
1980
1981         DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
1982
1983         bytes = g_byte_array_new();
1984         if (length > 0) {
1985                 g_byte_array_append(bytes, start_ptr, length);
1986         }
1987         fvalue_set(&fi->value, bytes, TRUE);
1988 }
1989
1990
1991 static void
1992 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
1993 {
1994         proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
1995 }
1996
1997 /* Add a FT_*TIME to a proto_tree */
1998 proto_item *
1999 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2000                     gint length, nstime_t *value_ptr)
2001 {
2002         proto_item        *pi;
2003         header_field_info *hfinfo;
2004
2005         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2006
2007         DISSECTOR_ASSERT(hfinfo->type == FT_ABSOLUTE_TIME ||
2008                          hfinfo->type == FT_RELATIVE_TIME);
2009
2010         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2011         proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
2012
2013         return pi;
2014 }
2015
2016 proto_item *
2017 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2018                                  gint start, gint length, nstime_t *value_ptr,
2019                                  const char *format, ...)
2020 {
2021         proto_item        *pi;
2022         va_list            ap;
2023
2024         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
2025         if (pi != tree) {
2026                 va_start(ap, format);
2027                 proto_tree_set_representation_value(pi, format, ap);
2028                 va_end(ap);
2029         }
2030
2031         return pi;
2032 }
2033
2034 proto_item *
2035 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2036                            gint start, gint length, nstime_t *value_ptr,
2037                            const char *format, ...)
2038 {
2039         proto_item        *pi;
2040         va_list            ap;
2041
2042         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
2043         if (pi != tree) {
2044                 TRY_TO_FAKE_THIS_REPR(pi);
2045
2046                 va_start(ap, format);
2047                 proto_tree_set_representation(pi, format, ap);
2048                 va_end(ap);
2049         }
2050
2051         return pi;
2052 }
2053
2054 /* Set the FT_*TIME value */
2055 static void
2056 proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
2057 {
2058         DISSECTOR_ASSERT(value_ptr != NULL);
2059
2060         fvalue_set(&fi->value, value_ptr, FALSE);
2061 }
2062
2063 /* Add a FT_IPXNET to a proto_tree */
2064 proto_item *
2065 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2066                       gint length, guint32 value)
2067 {
2068         proto_item        *pi;
2069         header_field_info *hfinfo;
2070
2071         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2072
2073         DISSECTOR_ASSERT(hfinfo->type == FT_IPXNET);
2074
2075         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2076         proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
2077
2078         return pi;
2079 }
2080
2081 proto_item *
2082 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2083                                    gint start, gint length, guint32 value,
2084                                    const char *format, ...)
2085 {
2086         proto_item        *pi;
2087         va_list            ap;
2088
2089         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
2090         if (pi != tree) {
2091                 va_start(ap, format);
2092                 proto_tree_set_representation_value(pi, format, ap);
2093                 va_end(ap);
2094         }
2095
2096         return pi;
2097 }
2098
2099 proto_item *
2100 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2101                              gint start, gint length, guint32 value,
2102                              const char *format, ...)
2103 {
2104         proto_item        *pi;
2105         va_list            ap;
2106
2107         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
2108         if (pi != tree) {
2109                 TRY_TO_FAKE_THIS_REPR(pi);
2110
2111                 va_start(ap, format);
2112                 proto_tree_set_representation(pi, format, ap);
2113                 va_end(ap);
2114         }
2115
2116         return pi;
2117 }
2118
2119 /* Set the FT_IPXNET value */
2120 static void
2121 proto_tree_set_ipxnet(field_info *fi, guint32 value)
2122 {
2123         fvalue_set_uinteger(&fi->value, value);
2124 }
2125
2126 /* Add a FT_IPv4 to a proto_tree */
2127 proto_item *
2128 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2129                     gint length, guint32 value)
2130 {
2131         proto_item        *pi;
2132         header_field_info *hfinfo;
2133
2134         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2135
2136         DISSECTOR_ASSERT(hfinfo->type == FT_IPv4);
2137
2138         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2139         proto_tree_set_ipv4(PNODE_FINFO(pi), value);
2140
2141         return pi;
2142 }
2143
2144 proto_item *
2145 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2146                                  gint start, gint length, guint32 value,
2147                                  const char *format, ...)
2148 {
2149         proto_item        *pi;
2150         va_list            ap;
2151
2152         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
2153         if (pi != tree) {
2154                 va_start(ap, format);
2155                 proto_tree_set_representation_value(pi, format, ap);
2156                 va_end(ap);
2157         }
2158
2159         return pi;
2160 }
2161
2162 proto_item *
2163 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2164                            gint start, gint length, guint32 value,
2165                            const char *format, ...)
2166 {
2167         proto_item        *pi;
2168         va_list            ap;
2169
2170         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
2171         if (pi != tree) {
2172                 TRY_TO_FAKE_THIS_REPR(pi);
2173
2174                 va_start(ap, format);
2175                 proto_tree_set_representation(pi, format, ap);
2176                 va_end(ap);
2177         }
2178
2179         return pi;
2180 }
2181
2182 /* Set the FT_IPv4 value */
2183 static void
2184 proto_tree_set_ipv4(field_info *fi, guint32 value)
2185 {
2186         fvalue_set_uinteger(&fi->value, value);
2187 }
2188
2189 /* Add a FT_IPv6 to a proto_tree */
2190 proto_item *
2191 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2192                     gint length, const guint8* value_ptr)
2193 {
2194         proto_item        *pi;
2195         header_field_info *hfinfo;
2196
2197         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2198
2199         DISSECTOR_ASSERT(hfinfo->type == FT_IPv6);
2200
2201         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2202         proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr);
2203
2204         return pi;
2205 }
2206
2207 proto_item *
2208 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2209                                  gint start, gint length,
2210                                  const guint8* value_ptr,
2211                                  const char *format, ...)
2212 {
2213         proto_item        *pi;
2214         va_list            ap;
2215
2216         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
2217         if (pi != tree) {
2218                 va_start(ap, format);
2219                 proto_tree_set_representation_value(pi, format, ap);
2220                 va_end(ap);
2221         }
2222
2223         return pi;
2224 }
2225
2226 proto_item *
2227 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2228                            gint start, gint length, const guint8* value_ptr,
2229                            const char *format, ...)
2230 {
2231         proto_item        *pi;
2232         va_list            ap;
2233
2234         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
2235         if (pi != tree) {
2236                 TRY_TO_FAKE_THIS_REPR(pi);
2237
2238                 va_start(ap, format);
2239                 proto_tree_set_representation(pi, format, ap);
2240                 va_end(ap);
2241         }
2242
2243         return pi;
2244 }
2245
2246 /* Set the FT_IPv6 value */
2247 static void
2248 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
2249 {
2250         DISSECTOR_ASSERT(value_ptr != NULL);
2251         fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
2252 }
2253
2254 static void
2255 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
2256 {
2257         proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
2258 }
2259
2260 /* Add a FT_GUID to a proto_tree */
2261 proto_item *
2262 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2263                     gint length, const e_guid_t *value_ptr)
2264 {
2265         proto_item        *pi;
2266         header_field_info *hfinfo;
2267
2268         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2269
2270         DISSECTOR_ASSERT(hfinfo->type == FT_GUID);
2271
2272         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2273         proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
2274
2275         return pi;
2276 }
2277
2278 proto_item *
2279 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2280                                  gint start, gint length,
2281                                  const e_guid_t *value_ptr,
2282                                  const char *format, ...)
2283 {
2284         proto_item        *pi;
2285         va_list            ap;
2286
2287         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
2288         if (pi != tree) {
2289                 va_start(ap, format);
2290                 proto_tree_set_representation_value(pi, format, ap);
2291                 va_end(ap);
2292         }
2293
2294         return pi;
2295 }
2296
2297 proto_item *
2298 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2299                            gint start, gint length, const e_guid_t *value_ptr,
2300                            const char *format, ...)
2301 {
2302         proto_item        *pi;
2303         va_list            ap;
2304
2305         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
2306         if (pi != tree) {
2307                 TRY_TO_FAKE_THIS_REPR(pi);
2308
2309                 va_start(ap, format);
2310                 proto_tree_set_representation(pi, format, ap);
2311                 va_end(ap);
2312         }
2313
2314         return pi;
2315 }
2316
2317 /* Set the FT_GUID value */
2318 static void
2319 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
2320 {
2321         DISSECTOR_ASSERT(value_ptr != NULL);
2322         fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
2323 }
2324
2325 static void
2326 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
2327                         const guint encoding)
2328 {
2329         e_guid_t guid;
2330
2331         tvb_get_guid(tvb, start, &guid, encoding);
2332         proto_tree_set_guid(fi, &guid);
2333 }
2334
2335 /* Add a FT_OID to a proto_tree */
2336 proto_item *
2337 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2338                    gint length, const guint8* value_ptr)
2339 {
2340         proto_item        *pi;
2341         header_field_info *hfinfo;
2342
2343         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2344
2345         DISSECTOR_ASSERT(hfinfo->type == FT_OID);
2346
2347         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2348         proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
2349
2350         return pi;
2351 }
2352
2353 proto_item *
2354 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2355                                 gint start, gint length,
2356                                 const guint8* value_ptr,
2357                                 const char *format, ...)
2358 {
2359         proto_item        *pi;
2360         va_list            ap;
2361
2362         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
2363         if (pi != tree) {
2364                 va_start(ap, format);
2365                 proto_tree_set_representation_value(pi, format, ap);
2366                 va_end(ap);
2367         }
2368
2369         return pi;
2370 }
2371
2372 proto_item *
2373 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2374                           gint start, gint length, const guint8* value_ptr,
2375                           const char *format, ...)
2376 {
2377         proto_item        *pi;
2378         va_list            ap;
2379
2380         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
2381         if (pi != tree) {
2382                 TRY_TO_FAKE_THIS_REPR(pi);
2383
2384                 va_start(ap, format);
2385                 proto_tree_set_representation(pi, format, ap);
2386                 va_end(ap);
2387         }
2388
2389         return pi;
2390 }
2391
2392 /* Set the FT_OID value */
2393 static void
2394 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
2395 {
2396         GByteArray *bytes;
2397
2398         DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
2399
2400         bytes = g_byte_array_new();
2401         if (length > 0) {
2402                 g_byte_array_append(bytes, value_ptr, length);
2403         }
2404         fvalue_set(&fi->value, bytes, TRUE);
2405 }
2406
2407 static void
2408 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
2409 {
2410         proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
2411 }
2412
2413 static void
2414 proto_tree_set_uint64(field_info *fi, guint64 value)
2415 {
2416         fvalue_set_integer64(&fi->value, value);
2417 }
2418
2419 /*
2420  * NOTE: to support code written when proto_tree_add_item() took a
2421  * gboolean as its last argument, with FALSE meaning "big-endian"
2422  * and TRUE meaning "little-endian", we treat any non-zero value of
2423  * "encoding" as meaning "little-endian".
2424  */
2425 static void
2426 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start,
2427                           guint length, const guint encoding)
2428 {
2429         guint64 value = 0;
2430         guint8* b = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, start, length);
2431
2432         if (encoding) {
2433                 b += length;
2434                 switch (length) {
2435                         default: DISSECTOR_ASSERT_NOT_REACHED();
2436                         case 8: value <<= 8; value += *--b;
2437                         case 7: value <<= 8; value += *--b;
2438                         case 6: value <<= 8; value += *--b;
2439                         case 5: value <<= 8; value += *--b;
2440                         case 4: value <<= 8; value += *--b;
2441                         case 3: value <<= 8; value += *--b;
2442                         case 2: value <<= 8; value += *--b;
2443                         case 1: value <<= 8; value += *--b;
2444                                 break;
2445                 }
2446         } else {
2447                 switch (length) {
2448                         default: DISSECTOR_ASSERT_NOT_REACHED();
2449                         case 8: value <<= 8; value += *b++;
2450                         case 7: value <<= 8; value += *b++;
2451                         case 6: value <<= 8; value += *b++;
2452                         case 5: value <<= 8; value += *b++;
2453                         case 4: value <<= 8; value += *b++;
2454                         case 3: value <<= 8; value += *b++;
2455                         case 2: value <<= 8; value += *b++;
2456                         case 1: value <<= 8; value += *b++;
2457                                 break;
2458                 }
2459         }
2460
2461         proto_tree_set_uint64(fi, value);
2462 }
2463
2464 /* Add a FT_STRING or FT_STRINGZ to a proto_tree. Creates own copy of string,
2465  * and frees it when the proto_tree is destroyed. */
2466 proto_item *
2467 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2468                       gint length, const char* value)
2469 {
2470         proto_item        *pi;
2471         header_field_info *hfinfo;
2472
2473         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2474
2475         DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
2476
2477         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2478         DISSECTOR_ASSERT(length >= 0);
2479         proto_tree_set_string(PNODE_FINFO(pi), value);
2480
2481         return pi;
2482 }
2483
2484 proto_item *
2485 proto_tree_add_unicode_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2486                       gint length, const char* value)
2487 {
2488         DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
2489         return proto_tree_add_string_format_value(tree, hfindex, tvb, start, length, value, "%s", value);
2490 }
2491
2492 proto_item *
2493 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2494                                    gint start, gint length, const char* value,
2495                                    const char *format,
2496                                    ...)
2497 {
2498         proto_item        *pi;
2499         va_list            ap;
2500
2501         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
2502         if (pi != tree) {
2503                 va_start(ap, format);
2504                 proto_tree_set_representation_value(pi, format, ap);
2505                 va_end(ap);
2506         }
2507
2508         return pi;
2509 }
2510
2511 proto_item *
2512 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2513                              gint start, gint length, const char* value,
2514                              const char *format, ...)
2515 {
2516         proto_item        *pi;
2517         va_list            ap;
2518
2519         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
2520         if (pi != tree) {
2521                 TRY_TO_FAKE_THIS_REPR(pi);
2522
2523                 va_start(ap, format);
2524                 proto_tree_set_representation(pi, format, ap);
2525                 va_end(ap);
2526         }
2527
2528         return pi;
2529 }
2530
2531 /* Appends string data to a FT_STRING or FT_STRINGZ, allowing progressive
2532  * field info update instead of only updating the representation as does
2533  * proto_item_append_text()
2534  */
2535 /* NOTE: this function will break with the TRY_TO_FAKE_THIS_ITEM()
2536  * speed optimization.
2537  * Currently only WSP use this function so it is not that bad but try to
2538  * avoid using this one if possible.
2539  * IF you must use this function you MUST also disable the
2540  * TRY_TO_FAKE_THIS_ITEM() optimization for your dissector/function
2541  * using proto_item_append_string().
2542  * Do that by faking that the tree is visible by calling
2543  * proto_tree_set_visible(tree, TRUE) (see packet-wsp.c)
2544  * BEFORE you create the item you are later going to use
2545  * proto_item_append_string() on.
2546  */
2547 void
2548 proto_item_append_string(proto_item *pi, const char *str)
2549 {
2550         field_info        *fi;
2551         header_field_info *hfinfo;
2552         const gchar       *old_str, *new_str;
2553
2554         if (!pi)
2555                 return;
2556         if (!*str)
2557                 return;
2558
2559         fi = PITEM_FINFO(pi);
2560         DISSECTOR_ASSERT_HINT(fi, "proto_tree_set_visible(tree, TRUE) should have been called previously");
2561
2562         hfinfo = fi->hfinfo;
2563         if (hfinfo->type == FT_PROTOCOL) {
2564                 /* TRY_TO_FAKE_THIS_ITEM() speed optimization: silently skip */
2565                 return;
2566         }
2567         DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
2568         old_str = (guint8 *)fvalue_get(&fi->value);
2569         if (old_str && old_str[0])
2570                 new_str = ep_strconcat(old_str, str, NULL);
2571         else
2572                 new_str = str;
2573         fvalue_set(&fi->value, (gpointer) new_str, FALSE);
2574 }
2575
2576 /* Set the FT_STRING value */
2577 static void
2578 proto_tree_set_string(field_info *fi, const char* value)
2579 {
2580         if (value) {
2581                 fvalue_set(&fi->value, (gpointer) value, FALSE);
2582         } else {
2583                 fvalue_set(&fi->value, (gpointer) "[ Null ]", FALSE);
2584         }
2585 }
2586
2587 static void
2588 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding)
2589 {
2590         gchar   *string;
2591
2592         if (length == -1) {
2593                 length = tvb_ensure_length_remaining(tvb, start);
2594         }
2595
2596         string = tvb_get_string_enc(wmem_packet_scope(), tvb, start, length, encoding);
2597         proto_tree_set_string(fi, string);
2598 }
2599
2600
2601 /* Add a FT_AX25 to a proto_tree */
2602 proto_item *
2603 proto_tree_add_ax25(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2604                 const guint8* value)
2605 {
2606         proto_item              *pi;
2607         header_field_info       *hfinfo;
2608
2609         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2610
2611         DISSECTOR_ASSERT(hfinfo->type == FT_AX25);
2612
2613         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2614         proto_tree_set_ax25(PNODE_FINFO(pi), value);
2615
2616         return pi;
2617 }
2618
2619 /* Set the FT_AX25 value */
2620 static void
2621 proto_tree_set_ax25(field_info *fi, const guint8* value)
2622 {
2623         fvalue_set(&fi->value, (gpointer) value, FALSE);
2624 }
2625
2626 static void
2627 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
2628 {
2629         proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
2630 }
2631
2632 /* Set the FT_VINES value */
2633 static void
2634 proto_tree_set_vines(field_info *fi, const guint8* value)
2635 {
2636         fvalue_set(&fi->value, (gpointer) value, FALSE);
2637 }
2638
2639 static void
2640 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
2641 {
2642         proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
2643 }
2644
2645 /* Add a FT_ETHER to a proto_tree */
2646 proto_item *
2647 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2648                      gint length, const guint8* value)
2649 {
2650         proto_item        *pi;
2651         header_field_info *hfinfo;
2652
2653         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2654
2655         DISSECTOR_ASSERT(hfinfo->type == FT_ETHER);
2656
2657         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2658         proto_tree_set_ether(PNODE_FINFO(pi), value);
2659
2660         return pi;
2661 }
2662
2663 proto_item *
2664 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2665                                   gint start, gint length, const guint8* value,
2666                                   const char *format, ...)
2667 {
2668         proto_item        *pi;
2669         va_list            ap;
2670
2671         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
2672         if (pi != tree) {
2673                 va_start(ap, format);
2674                 proto_tree_set_representation_value(pi, format, ap);
2675                 va_end(ap);
2676         }
2677
2678         return pi;
2679 }
2680
2681 proto_item *
2682 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2683                             gint start, gint length, const guint8* value,
2684                             const char *format, ...)
2685 {
2686         proto_item        *pi;
2687         va_list            ap;
2688
2689         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
2690         if (pi != tree) {
2691                 TRY_TO_FAKE_THIS_REPR(pi);
2692
2693                 va_start(ap, format);
2694                 proto_tree_set_representation(pi, format, ap);
2695                 va_end(ap);
2696         }
2697
2698         return pi;
2699 }
2700
2701 /* Set the FT_ETHER value */
2702 static void
2703 proto_tree_set_ether(field_info *fi, const guint8* value)
2704 {
2705         fvalue_set(&fi->value, (gpointer) value, FALSE);
2706 }
2707
2708 static void
2709 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
2710 {
2711         proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
2712 }
2713
2714 /* Add a FT_BOOLEAN to a proto_tree */
2715 proto_item *
2716 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2717                        gint length, guint32 value)
2718 {
2719         proto_item        *pi;
2720         header_field_info *hfinfo;
2721
2722         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2723
2724         DISSECTOR_ASSERT(hfinfo->type == FT_BOOLEAN);
2725
2726         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2727         proto_tree_set_boolean(PNODE_FINFO(pi), value);
2728
2729         return pi;
2730 }
2731
2732 proto_item *
2733 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
2734                                     tvbuff_t *tvb, gint start, gint length,
2735                                     guint32 value, const char *format, ...)
2736 {
2737         proto_item        *pi;
2738         va_list            ap;
2739
2740         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
2741         if (pi != tree) {
2742                 va_start(ap, format);
2743                 proto_tree_set_representation_value(pi, format, ap);
2744                 va_end(ap);
2745         }
2746
2747         return pi;
2748 }
2749
2750 proto_item *
2751 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2752                               gint start, gint length, guint32 value,
2753                               const char *format, ...)
2754 {
2755         proto_item        *pi;
2756         va_list            ap;
2757
2758         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
2759         if (pi != tree) {
2760                 TRY_TO_FAKE_THIS_REPR(pi);
2761
2762                 va_start(ap, format);
2763                 proto_tree_set_representation(pi, format, ap);
2764                 va_end(ap);
2765         }
2766
2767         return pi;
2768 }
2769
2770 /* Set the FT_BOOLEAN value */
2771 static void
2772 proto_tree_set_boolean(field_info *fi, guint32 value)
2773 {
2774         proto_tree_set_uint(fi, value);
2775 }
2776
2777 /* Add a FT_FLOAT to a proto_tree */
2778 proto_item *
2779 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2780                      gint length, float value)
2781 {
2782         proto_item        *pi;
2783         header_field_info *hfinfo;
2784
2785         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2786
2787         DISSECTOR_ASSERT(hfinfo->type == FT_FLOAT);
2788
2789         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2790         proto_tree_set_float(PNODE_FINFO(pi), value);
2791
2792         return pi;
2793 }
2794
2795 proto_item *
2796 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2797                                   gint start, gint length, float value,
2798                                   const char *format, ...)
2799 {
2800         proto_item        *pi;
2801         va_list            ap;
2802
2803         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
2804         if (pi != tree) {
2805                 va_start(ap, format);
2806                 proto_tree_set_representation_value(pi, format, ap);
2807                 va_end(ap);
2808         }
2809
2810         return pi;
2811 }
2812
2813 proto_item *
2814 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2815                             gint start, gint length, float value,
2816                             const char *format, ...)
2817 {
2818         proto_item        *pi;
2819         va_list            ap;
2820
2821         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
2822         if (pi != tree) {
2823                 TRY_TO_FAKE_THIS_REPR(pi);
2824
2825                 va_start(ap, format);
2826                 proto_tree_set_representation(pi, format, ap);
2827                 va_end(ap);
2828         }
2829
2830         return pi;
2831 }
2832
2833 /* Set the FT_FLOAT value */
2834 static void
2835 proto_tree_set_float(field_info *fi, float value)
2836 {
2837         fvalue_set_floating(&fi->value, value);
2838 }
2839
2840 /* Add a FT_DOUBLE to a proto_tree */
2841 proto_item *
2842 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2843                       gint length, double value)
2844 {
2845         proto_item        *pi;
2846         header_field_info *hfinfo;
2847
2848         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2849
2850         DISSECTOR_ASSERT(hfinfo->type == FT_DOUBLE);
2851
2852         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2853         proto_tree_set_double(PNODE_FINFO(pi), value);
2854
2855         return pi;
2856 }
2857
2858 proto_item *
2859 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2860                                    gint start, gint length, double value,
2861                                    const char *format, ...)
2862 {
2863         proto_item        *pi;
2864         va_list            ap;
2865
2866         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
2867         if (pi != tree) {
2868                 va_start(ap, format);
2869                 proto_tree_set_representation_value(pi, format, ap);
2870                 va_end(ap);
2871         }
2872
2873         return pi;
2874 }
2875
2876 proto_item *
2877 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2878                              gint start, gint length, double value,
2879                              const char *format, ...)
2880 {
2881         proto_item        *pi;
2882         va_list            ap;
2883
2884         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
2885         if (pi != tree) {
2886                 TRY_TO_FAKE_THIS_REPR(pi);
2887
2888                 va_start(ap, format);
2889                 proto_tree_set_representation(pi, format, ap);
2890                 va_end(ap);
2891         }
2892
2893         return pi;
2894 }
2895
2896 /* Set the FT_DOUBLE value */
2897 static void
2898 proto_tree_set_double(field_info *fi, double value)
2899 {
2900         fvalue_set_floating(&fi->value, value);
2901 }
2902
2903 /* Add FT_UINT{8,16,24,32} to a proto_tree */
2904 proto_item *
2905 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2906                     gint length, guint32 value)
2907 {
2908         proto_item        *pi = NULL;
2909         header_field_info *hfinfo;
2910
2911         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2912
2913         switch (hfinfo->type) {
2914                 case FT_UINT8:
2915                 case FT_UINT16:
2916                 case FT_UINT24:
2917                 case FT_UINT32:
2918                 case FT_FRAMENUM:
2919                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2920                         proto_tree_set_uint(PNODE_FINFO(pi), value);
2921                         break;
2922
2923                 default:
2924                         DISSECTOR_ASSERT_NOT_REACHED();
2925         }
2926
2927         return pi;
2928 }
2929
2930 proto_item *
2931 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2932                                  gint start, gint length, guint32 value,
2933                                  const char *format, ...)
2934 {
2935         proto_item        *pi;
2936         va_list            ap;
2937
2938         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
2939         if (pi != tree) {
2940                 va_start(ap, format);
2941                 proto_tree_set_representation_value(pi, format, ap);
2942                 va_end(ap);
2943         }
2944
2945         return pi;
2946 }
2947
2948 proto_item *
2949 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2950                            gint start, gint length, guint32 value,
2951                            const char *format, ...)
2952 {
2953         proto_item        *pi;
2954         va_list            ap;
2955
2956         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
2957         if (pi != tree) {
2958                 TRY_TO_FAKE_THIS_REPR(pi);
2959
2960                 va_start(ap, format);
2961                 proto_tree_set_representation(pi, format, ap);
2962                 va_end(ap);
2963         }
2964
2965         return pi;
2966 }
2967
2968 /* Set the FT_UINT{8,16,24,32} value */
2969 static void
2970 proto_tree_set_uint(field_info *fi, guint32 value)
2971 {
2972         header_field_info *hfinfo;
2973         guint32            integer;
2974
2975         hfinfo = fi->hfinfo;
2976         integer = value;
2977
2978         if (hfinfo->bitmask) {
2979                 /* Mask out irrelevant portions */
2980                 integer &= hfinfo->bitmask;
2981
2982                 /* Shift bits */
2983                 integer >>= hfinfo_bitshift(hfinfo);
2984         }
2985
2986         fvalue_set_uinteger(&fi->value, integer);
2987 }
2988
2989 /* Add FT_UINT64 to a proto_tree */
2990 proto_item *
2991 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2992                       gint length, guint64 value)
2993 {
2994         proto_item        *pi;
2995         header_field_info *hfinfo;
2996
2997         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2998
2999         DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
3000
3001         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3002         proto_tree_set_uint64(PNODE_FINFO(pi), value);
3003
3004         return pi;
3005 }
3006
3007 proto_item *
3008 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3009                                    gint start, gint length, guint64 value,
3010                                    const char *format, ...)
3011 {
3012         proto_item        *pi;
3013         va_list            ap;
3014
3015         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
3016         if (pi != tree) {
3017                 va_start(ap, format);
3018                 proto_tree_set_representation_value(pi, format, ap);
3019                 va_end(ap);
3020         }
3021
3022         return pi;
3023 }
3024
3025 proto_item *
3026 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3027                              gint start, gint length, guint64 value,
3028                              const char *format, ...)
3029 {
3030         proto_item        *pi;
3031         va_list            ap;
3032
3033         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
3034         if (pi != tree) {
3035                 TRY_TO_FAKE_THIS_REPR(pi);
3036
3037                 va_start(ap, format);
3038                 proto_tree_set_representation(pi, format, ap);
3039                 va_end(ap);
3040         }
3041
3042         return pi;
3043 }
3044
3045 /* Add FT_INT{8,16,24,32} to a proto_tree */
3046 proto_item *
3047 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3048                    gint length, gint32 value)
3049 {
3050         proto_item        *pi = NULL;
3051         header_field_info *hfinfo;
3052
3053         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3054
3055         switch (hfinfo->type) {
3056                 case FT_INT8:
3057                 case FT_INT16:
3058                 case FT_INT24:
3059                 case FT_INT32:
3060                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3061                         proto_tree_set_int(PNODE_FINFO(pi), value);
3062                         break;
3063
3064                 default:
3065                         DISSECTOR_ASSERT_NOT_REACHED();
3066         }
3067
3068         return pi;
3069 }
3070
3071 proto_item *
3072 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3073                                 gint start, gint length, gint32 value,
3074                                 const char *format, ...)
3075 {
3076         proto_item  *pi;
3077         va_list      ap;
3078
3079         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
3080         if (pi != tree) {
3081                 va_start(ap, format);
3082                 proto_tree_set_representation_value(pi, format, ap);
3083                 va_end(ap);
3084         }
3085
3086         return pi;
3087 }
3088
3089 proto_item *
3090 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3091                           gint start, gint length, gint32 value,
3092                           const char *format, ...)
3093 {
3094         proto_item *pi;
3095         va_list     ap;
3096
3097         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
3098         if (pi != tree) {
3099                 TRY_TO_FAKE_THIS_REPR(pi);
3100
3101                 va_start(ap, format);
3102                 proto_tree_set_representation(pi, format, ap);
3103                 va_end(ap);
3104         }
3105
3106         return pi;
3107 }
3108
3109 /* Set the FT_INT{8,16,24,32} value */
3110 static void
3111 proto_tree_set_int(field_info *fi, gint32 value)
3112 {
3113         header_field_info *hfinfo;
3114         guint32            integer;
3115         gint               no_of_bits;
3116
3117         hfinfo = fi->hfinfo;
3118         integer = (guint32) value;
3119
3120         if (hfinfo->bitmask) {
3121                 /* Mask out irrelevant portions */
3122                 integer &= hfinfo->bitmask;
3123
3124                 /* Shift bits */
3125                 integer >>= hfinfo_bitshift(hfinfo);
3126
3127                 no_of_bits = swar_count_bits(hfinfo->bitmask);
3128                 if (integer & (1 << (no_of_bits-1)))
3129                         integer |= (-1 << no_of_bits);
3130         }
3131
3132         fvalue_set_sinteger(&fi->value, integer);
3133 }
3134
3135 /* Add FT_INT64 to a proto_tree */
3136 proto_item *
3137 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3138                      gint length, gint64 value)
3139 {
3140         proto_item        *pi;
3141         header_field_info *hfinfo;
3142
3143         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3144
3145         DISSECTOR_ASSERT(hfinfo->type == FT_INT64);
3146
3147         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3148         proto_tree_set_uint64(PNODE_FINFO(pi), (guint64)value);
3149
3150         return pi;
3151 }
3152
3153 proto_item *
3154 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3155                                   gint start, gint length, gint64 value,
3156                                   const char *format, ...)
3157 {
3158         proto_item        *pi;
3159         va_list            ap;
3160
3161         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
3162         if (pi != tree) {
3163                 va_start(ap, format);
3164                 proto_tree_set_representation_value(pi, format, ap);
3165                 va_end(ap);
3166         }
3167
3168         return pi;
3169 }
3170
3171 proto_item *
3172 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3173                            gint start, gint length, gint64 value,
3174                            const char *format, ...)
3175 {
3176         proto_item        *pi;
3177         va_list            ap;
3178
3179         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
3180         if (pi != tree) {
3181                 TRY_TO_FAKE_THIS_REPR(pi);
3182
3183                 va_start(ap, format);
3184                 proto_tree_set_representation(pi, format, ap);
3185                 va_end(ap);
3186         }
3187
3188         return pi;
3189 }
3190 /* Add a FT_EUI64 to a proto_tree */
3191 proto_item *
3192 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3193                      gint length, const guint64 value)
3194 {
3195         proto_item        *pi;
3196         header_field_info *hfinfo;
3197
3198         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3199
3200         DISSECTOR_ASSERT(hfinfo->type == FT_EUI64);
3201
3202         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3203         proto_tree_set_eui64(PNODE_FINFO(pi), value);
3204
3205         return pi;
3206 }
3207
3208 proto_item *
3209 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3210                                   gint start, gint length, const guint64 value,
3211                                   const char *format, ...)
3212 {
3213         proto_item        *pi;
3214         va_list            ap;
3215
3216         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
3217         if (pi != tree) {
3218                 va_start(ap, format);
3219                 proto_tree_set_representation_value(pi, format, ap);
3220                 va_end(ap);
3221         }
3222
3223         return pi;
3224 }
3225
3226 proto_item *
3227 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3228                             gint start, gint length, const guint64 value,
3229                             const char *format, ...)
3230 {
3231         proto_item        *pi;
3232         va_list            ap;
3233
3234         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
3235         if (pi != tree) {
3236                 TRY_TO_FAKE_THIS_REPR(pi);
3237
3238                 va_start(ap, format);
3239                 proto_tree_set_representation(pi, format, ap);
3240                 va_end(ap);
3241         }
3242
3243         return pi;
3244 }
3245
3246 /* Set the FT_EUI64 value */
3247 static void
3248 proto_tree_set_eui64(field_info *fi, const guint64 value)
3249 {
3250         fvalue_set_integer64(&fi->value, value);
3251 }
3252 static void
3253 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
3254 {
3255         if (encoding)
3256         {
3257                 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
3258         } else {
3259                 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
3260         }
3261 }
3262
3263 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
3264 static proto_item *
3265 proto_tree_add_node(proto_tree *tree, field_info *fi)
3266 {
3267         proto_node *pnode, *tnode, *sibling;
3268         field_info *tfi;
3269
3270         /*
3271          * Make sure "tree" is ready to have subtrees under it, by
3272          * checking whether it's been given an ett_ value.
3273          *
3274          * "PNODE_FINFO(tnode)" may be null; that's the case for the root
3275          * node of the protocol tree.  That node is not displayed,
3276          * so it doesn't need an ett_ value to remember whether it
3277          * was expanded.
3278          */
3279         tnode = tree;
3280         tfi = PNODE_FINFO(tnode);
3281         if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
3282                 REPORT_DISSECTOR_BUG(ep_strdup_printf("\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
3283                                      fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
3284                 /* XXX - is it safe to continue here? */
3285         }
3286
3287         PROTO_NODE_NEW(PNODE_POOL(tree), pnode);
3288         pnode->parent = tnode;
3289         PNODE_FINFO(pnode) = fi;
3290         pnode->tree_data = PTREE_DATA(tree);
3291
3292         if (tnode->last_child != NULL) {
3293                 sibling = tnode->last_child;
3294                 DISSECTOR_ASSERT(sibling->next == NULL);
3295                 sibling->next = pnode;
3296         } else
3297                 tnode->first_child = pnode;
3298         tnode->last_child = pnode;
3299
3300         tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
3301
3302         return (proto_item *)pnode;
3303 }
3304
3305
3306 /* Generic way to allocate field_info and add to proto_tree.
3307  * Sets *pfi to address of newly-allocated field_info struct */
3308 static proto_item *
3309 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
3310                   gint *length)
3311 {
3312         proto_item *pi;
3313         field_info *fi;
3314
3315         fi = alloc_field_info(tree, hfinfo, tvb, start, length);
3316         pi = proto_tree_add_node(tree, fi);
3317
3318         return pi;
3319 }
3320
3321
3322 static void
3323 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
3324                    gint *item_length)
3325 {
3326         gint length_remaining;
3327
3328         /*
3329          * We only allow a null tvbuff if the item has a zero length,
3330          * i.e. if there's no data backing it.
3331          */
3332         DISSECTOR_ASSERT(tvb != NULL || *length == 0);
3333
3334         /*
3335          * XXX - in some protocols, there are 32-bit unsigned length
3336          * fields, so lengths in protocol tree and tvbuff routines
3337          * should really be unsigned.  We should have, for those
3338          * field types for which "to the end of the tvbuff" makes sense,
3339          * additional routines that take no length argument and
3340          * add fields that run to the end of the tvbuff.
3341          */
3342         if (*length == -1) {
3343                 /*
3344                  * For FT_NONE, FT_PROTOCOL, FT_BYTES, and FT_STRING fields,
3345                  * a length of -1 means "set the length to what remains in
3346                  * the tvbuff".
3347                  *
3348                  * The assumption is either that
3349                  *
3350                  *      1) the length of the item can only be determined
3351                  *         by dissection (typically true of items with
3352                  *         subitems, which are probably FT_NONE or
3353                  *         FT_PROTOCOL)
3354                  *
3355                  * or
3356                  *
3357                  *      2) if the tvbuff is "short" (either due to a short
3358                  *         snapshot length or due to lack of reassembly of
3359                  *         fragments/segments/whatever), we want to display
3360                  *         what's available in the field (probably FT_BYTES
3361                  *         or FT_STRING) and then throw an exception later
3362                  *
3363                  * or
3364                  *
3365                  *      3) the field is defined to be "what's left in the
3366                  *         packet"
3367                  *
3368                  * so we set the length to what remains in the tvbuff so
3369                  * that, if we throw an exception while dissecting, it
3370                  * has what is probably the right value.
3371                  *
3372                  * For FT_STRINGZ, it means "the string is null-terminated,
3373                  * not null-padded; set the length to the actual length
3374                  * of the string", and if the tvbuff if short, we just
3375                  * throw an exception.
3376                  *
3377                  * It's not valid for any other type of field.
3378                  */
3379                 switch (hfinfo->type) {
3380
3381                 case FT_PROTOCOL:
3382                         /*
3383                          * We allow this to be zero-length - for
3384                          * example, an ONC RPC NULL procedure has
3385                          * neither arguments nor reply, so the
3386                          * payload for that protocol is empty.
3387                          *
3388                          * However, if the length is negative, the
3389                          * start offset is *past* the byte past the
3390                          * end of the tvbuff, so we throw an
3391                          * exception.
3392                          */
3393                         *length = tvb_length_remaining(tvb, start);
3394                         if (*length < 0) {
3395                                 /*
3396                                  * Use "tvb_ensure_bytes_exist()"
3397                                  * to force the appropriate exception
3398                                  * to be thrown.
3399                                  */
3400                                 tvb_ensure_bytes_exist(tvb, start, 0);
3401                         }
3402                         DISSECTOR_ASSERT(*length >= 0);
3403                         break;
3404
3405                 case FT_NONE:
3406                 case FT_BYTES:
3407                 case FT_STRING:
3408                         *length = tvb_ensure_length_remaining(tvb, start);
3409                         DISSECTOR_ASSERT(*length >= 0);
3410                         break;
3411
3412                 case FT_STRINGZ:
3413                         /*
3414                          * Leave the length as -1, so our caller knows
3415                          * it was -1.
3416                          */
3417                         break;
3418
3419                 default:
3420                         DISSECTOR_ASSERT_NOT_REACHED();
3421                 }
3422                 *item_length = *length;
3423         } else {
3424                 *item_length = *length;
3425                 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
3426                         /*
3427                          * These types are for interior nodes of the
3428                          * tree, and don't have data associated with
3429                          * them; if the length is negative (XXX - see
3430                          * above) or goes past the end of the tvbuff,
3431                          * cut it short at the end of the tvbuff.
3432                          * That way, if this field is selected in
3433                          * Wireshark, we don't highlight stuff past
3434                          * the end of the data.
3435                          */
3436                         /* XXX - what to do, if we don't have a tvb? */
3437                         if (tvb) {
3438                                 length_remaining = tvb_length_remaining(tvb, start);
3439                                 if (*item_length < 0 ||
3440                                         (*item_length > 0 &&
3441                                           (length_remaining < *item_length)))
3442                                         *item_length = length_remaining;
3443                         }
3444                 }
3445                 if (*item_length < 0) {
3446                         THROW(ReportedBoundsError);
3447                 }
3448         }
3449 }
3450
3451 static field_info *
3452 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
3453                const gint start, const gint item_length)
3454 {
3455         field_info *fi;
3456
3457         FIELD_INFO_NEW(PNODE_POOL(tree), fi);
3458
3459         fi->hfinfo     = hfinfo;
3460         fi->start      = start;
3461         fi->start     += (tvb)?tvb_raw_offset(tvb):0;
3462         fi->length     = item_length;
3463         fi->tree_type  = -1;
3464         fi->flags      = 0;
3465         if (!PTREE_DATA(tree)->visible)
3466                 FI_SET_FLAG(fi, FI_HIDDEN);
3467         fvalue_init(&fi->value, fi->hfinfo->type);
3468         fi->rep        = NULL;
3469
3470         /* add the data source tvbuff */
3471         fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
3472
3473         fi->appendix_start  = 0;
3474         fi->appendix_length = 0;
3475
3476         return fi;
3477 }
3478
3479 static field_info *
3480 alloc_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
3481                  gint *length)
3482 {
3483         gint               item_length;
3484
3485         get_hfi_length(hfinfo, tvb, start, length, &item_length);
3486         return new_field_info(tree, hfinfo, tvb, start, item_length);
3487 }
3488
3489 static void
3490 label_mark_truncated_start(char *label_str)
3491 {
3492         static const char trunc_str[] = "[truncated] ";
3493         const size_t trunc_len = sizeof(trunc_str)-1;
3494
3495         memmove(label_str + trunc_len, label_str, ITEM_LABEL_LENGTH - trunc_len);
3496         memcpy(label_str, trunc_str, trunc_len);
3497         label_str[ITEM_LABEL_LENGTH-1] = '\0';
3498 }
3499
3500 /* If the protocol tree is to be visible, set the representation of a
3501    proto_tree entry with the name of the field for the item and with
3502    the value formatted with the supplied printf-style format and
3503    argument list. */
3504 static void
3505 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
3506 {
3507         g_assert(pi);
3508
3509         /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
3510          * items string representation */
3511         if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
3512                 int               ret = 0;
3513                 field_info        *fi = PITEM_FINFO(pi);
3514                 header_field_info *hf;
3515
3516                 DISSECTOR_ASSERT(fi);
3517
3518                 hf = fi->hfinfo;
3519
3520                 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
3521                 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
3522                         guint32 val;
3523                         char *p;
3524
3525                         val = fvalue_get_uinteger(&fi->value);
3526                         val <<= hfinfo_bitshift(hf);
3527
3528                         p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_bitwidth(hf));
3529                         ret = (int) (p - fi->rep->representation);
3530                 }
3531
3532                 /* put in the hf name */
3533                 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
3534
3535                 /* If possible, Put in the value of the string */
3536                 if (ret < ITEM_LABEL_LENGTH) {
3537                         ret += g_vsnprintf(fi->rep->representation + ret,
3538                                           ITEM_LABEL_LENGTH - ret, format, ap);
3539                 }
3540                 if (ret >= ITEM_LABEL_LENGTH) {
3541                         /* Uh oh, we don't have enough room.  Tell the user
3542                          * that the field is truncated.
3543                          */
3544                         /* XXX, label_mark_truncated() ? */
3545                         label_mark_truncated_start(fi->rep->representation);
3546                 }
3547         }
3548 }
3549
3550 /* If the protocol tree is to be visible, set the representation of a
3551    proto_tree entry with the representation formatted with the supplied
3552    printf-style format and argument list. */
3553 static void
3554 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
3555 {
3556         int         ret;        /*tmp return value */
3557         field_info *fi = PITEM_FINFO(pi);
3558
3559         DISSECTOR_ASSERT(fi);
3560
3561         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
3562                 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
3563                 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
3564                                   format, ap);
3565                 if (ret >= ITEM_LABEL_LENGTH) {
3566                         /* Uh oh, we don't have enough room.  Tell the user
3567                          * that the field is truncated.
3568                          */
3569                         label_mark_truncated_start(fi->rep->representation);
3570                 }
3571         }
3572 }
3573
3574 static int
3575 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
3576 {
3577         gsize res = g_strlcpy(dest, src, dest_size);
3578
3579         if (res > dest_size)
3580                 res = dest_size;
3581         return (int) res;
3582 }
3583
3584 static header_field_info *
3585 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
3586 {
3587         if (hfinfo->same_name_prev_id == -1)
3588                 return NULL;
3589         return proto_registrar_get_nth(hfinfo->same_name_prev_id);
3590 }
3591
3592 /* -------------------------- */
3593 const gchar *
3594 proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
3595                  gchar *result, gchar *expr, const int size)
3596 {
3597         guint32            number;
3598         guint8            *bytes;
3599         ipv4_addr         *ipv4;
3600         struct e_in6_addr *ipv6;
3601         address            addr;
3602         guint32            n_addr; /* network-order IPv4 address */
3603
3604         const true_false_string  *tfstring;
3605
3606         int                 len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
3607         GPtrArray          *finfos;
3608         field_info         *finfo         = NULL;
3609         header_field_info*  hfinfo;
3610         const gchar        *abbrev        = NULL;
3611
3612         const char *hf_str_val;
3613         char number_buf[32];
3614         const char *number_out;
3615
3616         g_assert(field_id >= 0);
3617
3618         hfinfo = proto_registrar_get_nth((guint)field_id);
3619
3620         /* do we need to rewind ? */
3621         if (!hfinfo)
3622                 return "";
3623
3624         if (occurrence < 0) {
3625                 /* Search other direction */
3626                 while (hfinfo->same_name_prev_id != -1) {
3627                         hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id);
3628                 }
3629         }
3630
3631         while (hfinfo) {
3632                 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
3633
3634                 if (!finfos || !(len = g_ptr_array_len(finfos))) {
3635                         if (occurrence < 0) {
3636                                 hfinfo = hfinfo->same_name_next;
3637                         } else {
3638                                 hfinfo = hfinfo_same_name_get_prev(hfinfo);
3639                         }
3640                         continue;
3641                 }
3642
3643                 /* Are there enough occurrences of the field? */
3644                 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
3645                         if (occurrence < 0) {
3646                                 hfinfo = hfinfo->same_name_next;
3647                         } else {
3648                                 hfinfo = hfinfo_same_name_get_prev(hfinfo);
3649                         }
3650                         prev_len += len;
3651                         continue;
3652                 }
3653
3654                 /* Calculate single index or set outer bounderies */
3655                 if (occurrence < 0) {
3656                         i = occurrence + len + prev_len;
3657                         last = i;
3658                 } else if (occurrence > 0) {
3659                         i = occurrence - 1 - prev_len;
3660                         last = i;
3661                 } else {
3662                         i = 0;
3663                         last = len - 1;
3664                 }
3665
3666                 prev_len += len; /* Count handled occurrences */
3667
3668                 while (i <= last) {
3669                         finfo = (field_info *)g_ptr_array_index(finfos, i);
3670
3671                         if (offset_r && (offset_r < (size - 2)))
3672                                 result[offset_r++] = ',';
3673
3674                         if (offset_e && (offset_e < (size - 2)))
3675                                 expr[offset_e++] = ',';
3676
3677                         switch (hfinfo->type) {
3678
3679                         case FT_NONE: /* Nothing to add */
3680                                 if (offset_r == 0) {
3681                                         result[0] = '\0';
3682                                 } else if (result[offset_r-1] == ',') {
3683                                         result[offset_r-1] = '\0';
3684                                 }
3685                                 break;
3686
3687                         case FT_PROTOCOL:
3688                                 /* prevent multiple "yes" entries by setting result directly */
3689                                 g_strlcpy(result, "Yes", size);
3690                                 break;
3691
3692                         case FT_UINT_BYTES:
3693                         case FT_BYTES:
3694                                 bytes = (guint8 *)fvalue_get(&finfo->value);
3695                                 offset_r += protoo_strlcpy(result+offset_r,
3696                                                            bytes_to_str(bytes,
3697                                                                         fvalue_length(&finfo->value)),
3698                                                            size-offset_r);
3699                                 break;
3700
3701                         case FT_ABSOLUTE_TIME:
3702                                 offset_r += protoo_strlcpy(result+offset_r,
3703                                                            abs_time_to_str((const nstime_t *)fvalue_get(&finfo->value),
3704                                                                            (absolute_time_display_e)hfinfo->display, TRUE),
3705                                                            size-offset_r);
3706                                 break;
3707
3708                         case FT_RELATIVE_TIME:
3709                                 offset_r += protoo_strlcpy(result+offset_r,
3710                                                            rel_time_to_secs_str((const nstime_t *)fvalue_get(&finfo->value)),
3711                                                            size-offset_r);
3712                                 break;
3713
3714                         case FT_BOOLEAN:
3715                                 number = fvalue_get_uinteger(&finfo->value);
3716                                 tfstring = (const true_false_string *)&tfs_true_false;
3717                                 if (hfinfo->strings) {
3718                                         tfstring = (const struct true_false_string*) hfinfo->strings;
3719                                 }
3720                                 offset_r += protoo_strlcpy(result+offset_r,
3721                                                            number ?
3722                                                              tfstring->true_string :
3723                                                              tfstring->false_string, size-offset_r);
3724
3725                                 offset_e += protoo_strlcpy(expr+offset_e,
3726                                                            number ? "1" : "0", size-offset_e);
3727                                 break;
3728
3729                         /* XXX - make these just FT_NUMBER? */
3730                         case FT_INT8:
3731                         case FT_INT16:
3732                         case FT_INT24:
3733                         case FT_INT32:
3734                         case FT_UINT8:
3735                         case FT_UINT16:
3736                         case FT_UINT24:
3737                         case FT_UINT32:
3738                         case FT_FRAMENUM:
3739                                 hf_str_val = NULL;
3740                                 number = IS_FT_INT(hfinfo->type) ? 
3741                                                 (guint32) fvalue_get_sinteger(&finfo->value) :
3742                                                 fvalue_get_uinteger(&finfo->value);
3743
3744                                 if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_CUSTOM) {
3745                                         gchar tmp[ITEM_LABEL_LENGTH];
3746                                         custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
3747
3748                                         DISSECTOR_ASSERT(fmtfunc);
3749                                         fmtfunc(tmp, number);
3750
3751                                         offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
3752
3753                                 } else if (hfinfo->strings) {
3754                                         number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
3755
3756                                         if (!number_out)
3757                                                 number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
3758
3759                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
3760
3761                                 } else {
3762                                         number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
3763
3764                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
3765                                 }
3766
3767                                 if (hf_str_val && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
3768                                         g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
3769                                 } else {
3770                                         number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
3771
3772                                         g_strlcpy(expr+offset_e, number_out, size-offset_e);
3773                                 }
3774
3775                                 offset_e = (int)strlen(expr);
3776                                 break;
3777
3778                         case FT_INT64:
3779                                 /* XXX: Should handle BASE_CUSTOM ? */
3780                                 g_snprintf(result+offset_r, size-offset_r,
3781                                            "%" G_GINT64_MODIFIER "d",
3782                                            fvalue_get_integer64(&finfo->value));
3783                                 offset_r = (int)strlen(result);
3784                                 break;
3785                         case FT_UINT64:
3786                                 g_snprintf(result+offset_r, size-offset_r,
3787                                 /* XXX: Should handle BASE_CUSTOM ? */
3788                                            "%" G_GINT64_MODIFIER "u",
3789                                            fvalue_get_integer64(&finfo->value));
3790                                 offset_r = (int)strlen(result);
3791                                 break;
3792                         case FT_EUI64:
3793                                 offset_r += protoo_strlcpy(result+offset_r,
3794                                                            eui64_to_str(fvalue_get_integer64(&finfo->value)),
3795                                                            size-offset_r);
3796                                 break;
3797
3798                         case FT_IPv4:
3799                                 ipv4 = (ipv4_addr *)fvalue_get(&finfo->value);
3800                                 n_addr = ipv4_get_net_order_addr(ipv4);
3801                                 offset_r += protoo_strlcpy(result+offset_r,
3802                                                            ip_to_str((guint8 *)&n_addr),
3803                                                            size-offset_r);
3804                                 break;
3805
3806                         case FT_IPv6:
3807                                 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
3808                                 SET_ADDRESS (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
3809                                 address_to_str_buf(&addr, result+offset_r, size-offset_r);
3810                                 offset_r = (int)strlen(result);
3811                                 break;
3812
3813                         case FT_ETHER:
3814                                 offset_r += protoo_strlcpy(result+offset_r,
3815                                                            bytes_to_str_punct((const guint8 *)fvalue_get(&finfo->value),
3816                                                                               FT_ETHER_LEN, ':'),
3817                                                            size-offset_r);
3818                                 break;
3819
3820                         case FT_GUID:
3821                                 offset_r += protoo_strlcpy(result+offset_r,
3822                                                            guid_to_str((e_guid_t *)fvalue_get(&finfo->value)),
3823                                                            size-offset_r);
3824                                 break;
3825
3826                         case FT_REL_OID:
3827                                 bytes = (guint8 *)fvalue_get(&finfo->value);
3828                                 offset_r += protoo_strlcpy(result+offset_r,
3829                                                            rel_oid_resolved_from_encoded(bytes,
3830                                                                                      fvalue_length(&finfo->value)),
3831                                                            size-offset_r);
3832                                 offset_e += protoo_strlcpy(expr+offset_e,
3833                                                            rel_oid_encoded2string(bytes, fvalue_length(&finfo->value)),
3834                                                            size-offset_e);
3835                                 break;
3836
3837                         case FT_OID:
3838                                 bytes = (guint8 *)fvalue_get(&finfo->value);
3839                                 offset_r += protoo_strlcpy(result+offset_r,
3840                                                            oid_resolved_from_encoded(bytes,
3841                                                                                      fvalue_length(&finfo->value)),
3842                                                            size-offset_r);
3843                                 offset_e += protoo_strlcpy(expr+offset_e,
3844                                                            oid_encoded2string(bytes, fvalue_length(&finfo->value)),
3845                                                            size-offset_e);
3846                                 break;
3847
3848                         case FT_FLOAT:
3849                                 g_snprintf(result+offset_r, size-offset_r,
3850                                            "%." STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
3851                                 offset_r = (int)strlen(result);
3852                                 break;
3853
3854                         case FT_DOUBLE:
3855                                 g_snprintf(result+offset_r, size-offset_r,
3856                                            "%." STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
3857                                 offset_r = (int)strlen(result);
3858                                 break;
3859
3860                         case FT_STRING:
3861                         case FT_STRINGZ:
3862                         case FT_UINT_STRING:
3863                                 bytes = (guint8 *)fvalue_get(&finfo->value);
3864                                 offset_r += protoo_strlcpy(result+offset_r,
3865                                                            format_text(bytes, strlen(bytes)),
3866                                                            size-offset_r);
3867                                 break;
3868
3869                         case FT_IPXNET: /*XXX really No column custom ?*/
3870                         case FT_PCRE:
3871                         default:
3872                                 g_error("hfinfo->type %d (%s) not handled\n",
3873                                                 hfinfo->type,
3874                                                 ftype_name(hfinfo->type));
3875                                 DISSECTOR_ASSERT_NOT_REACHED();
3876                                 break;
3877                         }
3878                         i++;
3879                 }
3880
3881                 switch (hfinfo->type) {
3882
3883                 case FT_BOOLEAN:
3884                 case FT_UINT8:
3885                 case FT_UINT16:
3886                 case FT_UINT24:
3887                 case FT_UINT32:
3888                 case FT_FRAMENUM:
3889                 case FT_INT8:
3890                 case FT_INT16:
3891                 case FT_INT24:
3892                 case FT_INT32:
3893                 case FT_OID:
3894                 case FT_REL_OID:
3895                         /* for these types, "expr" is filled in the loop above */
3896                         break;
3897
3898                 default:
3899                         /* for all others, just copy "result" to "expr" */
3900                         g_strlcpy(expr, result, size);
3901                         break;
3902                 }
3903
3904                 if (!abbrev) {
3905                         /* Store abbrev for return value */
3906                         abbrev = hfinfo->abbrev;
3907                 }
3908
3909                 if (occurrence == 0) {
3910                         /* Fetch next hfinfo with same name (abbrev) */
3911                         hfinfo = hfinfo_same_name_get_prev(hfinfo);
3912                 } else {
3913                         hfinfo = NULL;
3914                 }
3915         }
3916
3917         return abbrev ? abbrev : "";
3918 }
3919
3920
3921 /* Set text of proto_item after having already been created. */
3922 void
3923 proto_item_set_text(proto_item *pi, const char *format, ...)
3924 {
3925         field_info *fi = NULL;
3926         va_list     ap;
3927
3928         if (pi == NULL) {
3929                 return;
3930         }
3931
3932         fi = PITEM_FINFO(pi);
3933         if (fi == NULL)
3934                 return;
3935
3936         if (fi->rep) {
3937                 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
3938                 fi->rep = NULL;
3939         }
3940
3941         va_start(ap, format);
3942         proto_tree_set_representation(pi, format, ap);
3943         va_end(ap);
3944 }
3945
3946 /* Append to text of proto_item after having already been created. */
3947 void
3948 proto_item_append_text(proto_item *pi, const char *format, ...)
3949 {
3950         field_info *fi = NULL;
3951         size_t      curlen;
3952         va_list     ap;
3953
3954         if (pi == NULL) {
3955                 return;
3956         }
3957
3958         fi = PITEM_FINFO(pi);
3959         if (fi == NULL) {
3960                 return;
3961         }
3962
3963         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
3964                 /*
3965                  * If we don't already have a representation,
3966                  * generate the default representation.
3967                  */
3968                 if (fi->rep == NULL) {
3969                         ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
3970                         proto_item_fill_label(fi, fi->rep->representation);
3971                 }
3972
3973                 curlen = strlen(fi->rep->representation);
3974                 if (ITEM_LABEL_LENGTH > curlen) {
3975                         va_start(ap, format);
3976                         g_vsnprintf(fi->rep->representation + curlen,
3977                                 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
3978                         va_end(ap);
3979                 }
3980         }
3981 }
3982
3983 /* Prepend to text of proto_item after having already been created. */
3984 void
3985 proto_item_prepend_text(proto_item *pi, const char *format, ...)
3986 {
3987         field_info *fi = NULL;
3988         char        representation[ITEM_LABEL_LENGTH];
3989         va_list     ap;
3990
3991         if (pi == NULL) {
3992                 return;
3993         }
3994
3995         fi = PITEM_FINFO(pi);
3996         if (fi == NULL) {
3997                 return;
3998         }
3999
4000         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4001                 /*
4002                  * If we don't already have a representation,
4003                  * generate the default representation.
4004                  */
4005                 if (fi->rep == NULL) {
4006                         ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4007                         proto_item_fill_label(fi, representation);
4008                 } else
4009                         g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
4010
4011                 va_start(ap, format);
4012                 g_vsnprintf(fi->rep->representation,
4013                         ITEM_LABEL_LENGTH, format, ap);
4014                 va_end(ap);
4015                 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
4016         }
4017 }
4018
4019 void
4020 proto_item_set_len(proto_item *pi, const gint length)
4021 {
4022         field_info *fi;
4023
4024         if (pi == NULL)
4025                 return;
4026
4027         fi = PITEM_FINFO(pi);
4028         if (fi == NULL)
4029                 return;
4030
4031         DISSECTOR_ASSERT(length >= 0);
4032         fi->length = length;
4033
4034         /*
4035          * You cannot just make the "len" field of a GByteArray
4036          * larger, if there's no data to back that length;
4037          * you can only make it smaller.
4038          */
4039         if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
4040                 fi->value.value.bytes->len = length;
4041 }
4042
4043 /*
4044  * Sets the length of the item based on its start and on the specified
4045  * offset, which is the offset past the end of the item; as the start
4046  * in the item is relative to the beginning of the data source tvbuff,
4047  * we need to pass in a tvbuff - the end offset is relative to the beginning
4048  * of that tvbuff.
4049  */
4050 void
4051 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
4052 {
4053         field_info *fi;
4054
4055         if (pi == NULL)
4056                 return;
4057
4058         fi = PITEM_FINFO(pi);
4059         if (fi == NULL)
4060                 return;
4061
4062         end += tvb_raw_offset(tvb);
4063         DISSECTOR_ASSERT(end >= fi->start);
4064         fi->length = end - fi->start;
4065 }
4066
4067 int
4068 proto_item_get_len(const proto_item *pi)
4069 {
4070         field_info *fi = PITEM_FINFO(pi);
4071         return fi ? fi->length : -1;
4072 }
4073
4074 proto_tree *
4075 proto_tree_create_root(packet_info *pinfo)
4076 {
4077         wmem_allocator_t *pool;
4078         proto_node *pnode;
4079
4080         if (tree_pool_cache) {
4081                 pool = tree_pool_cache;
4082                 tree_pool_cache = NULL;
4083         }
4084         else {
4085                 pool = wmem_allocator_new(WMEM_ALLOCATOR_BLOCK);
4086         }
4087
4088         /* Initialize the proto_node */
4089         PROTO_NODE_NEW(pool, pnode);
4090         pnode->parent = NULL;
4091         PNODE_FINFO(pnode) = NULL;
4092         pnode->tree_data = wmem_new(pool, tree_data_t);
4093
4094         /* Make sure we can access pinfo everywhere */
4095         pnode->tree_data->pinfo = pinfo;
4096
4097         pnode->tree_data->mem_pool = pool;
4098
4099         /* Don't initialize the tree_data_t. Wait until we know we need it */
4100         pnode->tree_data->interesting_hfids = NULL;
4101
4102         /* Set the default to FALSE so it's easier to
4103          * find errors; if we expect to see the protocol tree
4104          * but for some reason the default 'visible' is not
4105          * changed, then we'll find out very quickly. */
4106         pnode->tree_data->visible = FALSE;
4107
4108         /* Make sure that we fake protocols (if possible) */
4109         pnode->tree_data->fake_protocols = TRUE;
4110
4111         /* Keep track of the number of children */
4112         pnode->tree_data->count = 0;
4113
4114         return (proto_tree *)pnode;
4115 }
4116
4117
4118 /* "prime" a proto_tree with a single hfid that a dfilter
4119  * is interested in. */
4120 void
4121 proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
4122 {
4123         header_field_info *hfinfo;
4124
4125         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
4126         /* this field is referenced by a filter so increase the refcount.
4127            also increase the refcount for the parent, i.e the protocol.
4128         */
4129         hfinfo->ref_type = HF_REF_TYPE_DIRECT;
4130         /* only increase the refcount if there is a parent.
4131            if this is a protocol and not a field then parent will be -1
4132            and there is no parent to add any refcounting for.
4133         */
4134         if (hfinfo->parent != -1) {
4135                 header_field_info *parent_hfinfo;
4136                 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
4137
4138                 /* Mark parent as indirectly referenced unless it is already directly
4139                  * referenced, i.e. the user has specified the parent in a filter.
4140                  */
4141                 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
4142                         parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
4143         }
4144 }
4145
4146 proto_tree *
4147 proto_item_add_subtree(proto_item *pi,  const gint idx) {
4148         field_info *fi;
4149
4150         if (!pi)
4151                 return NULL;
4152
4153         DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
4154
4155         fi = PITEM_FINFO(pi);
4156         if (!fi)
4157                 return (proto_tree *)pi;
4158
4159         fi->tree_type = idx;
4160
4161         return (proto_tree *)pi;
4162 }
4163
4164 proto_tree *
4165 proto_item_get_subtree(const proto_item *pi) {
4166         field_info *fi;
4167
4168         if (!pi)
4169                 return NULL;
4170         fi = PITEM_FINFO(pi);
4171         if ( (!fi) || (fi->tree_type == -1) )
4172                 return NULL;
4173         return (proto_tree *)pi;
4174 }
4175
4176 proto_item *
4177 proto_item_get_parent(const proto_item *ti) {
4178         if (!ti)
4179                 return NULL;
4180         return ti->parent;
4181 }
4182
4183 proto_item *
4184 proto_item_get_parent_nth(proto_item *ti, int gen) {
4185         if (!ti)
4186                 return NULL;
4187         while (gen--) {
4188                 ti = ti->parent;
4189                 if (!ti)
4190                         return NULL;
4191         }
4192         return ti;
4193 }
4194
4195
4196 proto_item *
4197 proto_tree_get_parent(const proto_tree *tree) {
4198         if (!tree)
4199                 return NULL;
4200         return (proto_item *)tree;
4201 }
4202
4203 proto_tree *
4204 proto_tree_get_root(proto_tree *tree) {
4205         if (!tree)
4206                 return NULL;
4207         while (tree->parent) {
4208                 tree = tree->parent;
4209         }
4210         return tree;
4211 }
4212
4213 void
4214 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
4215                      proto_item *item_to_move)
4216 {
4217
4218         /* Revert part of: http://anonsvn.wireshark.org/viewvc?view=rev&revision=32443
4219          * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
4220          */
4221         /* This function doesn't generate any values. It only reorganizes the prococol tree
4222          * so we can bail out immediately if it isn't visible. */
4223         if (!tree || !PTREE_DATA(tree)->visible)
4224                 return;
4225
4226         DISSECTOR_ASSERT(item_to_move->parent == tree);
4227         DISSECTOR_ASSERT(fixed_item->parent == tree);
4228
4229         /*** cut item_to_move out ***/
4230
4231         /* is item_to_move the first? */
4232         if (tree->first_child == item_to_move) {
4233                 /* simply change first child to next */
4234                 tree->first_child = item_to_move->next;
4235
4236                 DISSECTOR_ASSERT(tree->last_child != item_to_move);
4237         } else {
4238                 proto_item *curr_item;
4239                 /* find previous and change it's next */
4240                 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
4241                         if (curr_item->next == item_to_move) {
4242                                 break;
4243                         }
4244                 }
4245
4246                 DISSECTOR_ASSERT(curr_item);
4247
4248                 curr_item->next = item_to_move->next;
4249
4250                 /* fix last_child if required */
4251                 if (tree->last_child == item_to_move) {
4252                         tree->last_child = curr_item;
4253                 }
4254         }
4255
4256         /*** insert to_move after fixed ***/
4257         item_to_move->next = fixed_item->next;
4258         fixed_item->next = item_to_move;
4259         if (tree->last_child == fixed_item) {
4260                 tree->last_child = item_to_move;
4261         }
4262 }
4263
4264 void
4265 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
4266                         const gint length)
4267 {
4268         field_info *fi;
4269
4270         if (tree == NULL)
4271                 return;
4272
4273         fi = PTREE_FINFO(tree);
4274         if (fi == NULL)
4275                 return;
4276
4277         start += tvb_raw_offset(tvb);
4278         DISSECTOR_ASSERT(start >= 0);
4279         DISSECTOR_ASSERT(length >= 0);
4280
4281         fi->appendix_start = start;
4282         fi->appendix_length = length;
4283 }
4284
4285 int
4286 proto_register_protocol(const char *name, const char *short_name,
4287                         const char *filter_name)
4288 {
4289         protocol_t *protocol;
4290         header_field_info *hfinfo;
4291         int proto_id;
4292         char *existing_name;
4293         gint *key;
4294         guint i;
4295         guchar c;
4296         gboolean found_invalid;
4297
4298         /*
4299          * Make sure there's not already a protocol with any of those
4300          * names.  Crash if there is, as that's an error in the code
4301          * or an inappropriate plugin.
4302          * This situation has to be fixed to not register more than one
4303          * protocol with the same name.
4304          *
4305          * This is done by reducing the number of strcmp (and alike) calls
4306          * as much as possible, as this significally slows down startup time.
4307          *
4308          * Drawback: As a hash value is used to reduce insert time,
4309          * this might lead to a hash collision.
4310          * However, although we have somewhat over 1000 protocols, we're using
4311          * a 32 bit int so this is very, very unlikely.
4312          */
4313
4314         key  = (gint *)g_malloc (sizeof(gint));
4315         *key = wrs_str_hash(name);
4316
4317         existing_name = (char *)g_hash_table_lookup(proto_names, key);
4318         if (existing_name != NULL) {
4319                 /* g_error will terminate the program */
4320                 g_error("Duplicate protocol name \"%s\"!"
4321                         " This might be caused by an inappropriate plugin or a development error.", name);
4322         }
4323         g_hash_table_insert(proto_names, key, (gpointer)name);
4324
4325         existing_name = (char *)g_hash_table_lookup(proto_short_names, (gpointer)short_name);
4326         if (existing_name != NULL) {
4327                 g_error("Duplicate protocol short_name \"%s\"!"
4328                         " This might be caused by an inappropriate plugin or a development error.", short_name);
4329         }
4330         g_hash_table_insert(proto_short_names, (gpointer)short_name, (gpointer)short_name);
4331
4332         found_invalid = FALSE;
4333         for (i = 0; filter_name[i]; i++) {
4334                 c = filter_name[i];
4335                 if (!(islower(c) || isdigit(c) || c == '-' || c == '_' || c == '.')) {
4336                         found_invalid = TRUE;
4337                 }
4338         }
4339         if (found_invalid) {
4340                 g_error("Protocol filter name \"%s\" has one or more invalid characters."
4341                         " Allowed are lower characters, digits, '-', '_' and '.'."
4342                         " This might be caused by an inappropriate plugin or a development error.", filter_name);
4343         }
4344         existing_name = (char *)g_hash_table_lookup(proto_filter_names, (gpointer)filter_name);
4345         if (existing_name != NULL) {
4346                 g_error("Duplicate protocol filter_name \"%s\"!"
4347                         " This might be caused by an inappropriate plugin or a development error.", filter_name);
4348         }
4349         g_hash_table_insert(proto_filter_names, (gpointer)filter_name, (gpointer)filter_name);
4350
4351         /* Add this protocol to the list of known protocols; the list
4352            is sorted by protocol short name. */
4353         protocol = g_new(protocol_t, 1);
4354         protocol->name = name;
4355         protocol->short_name = short_name;
4356         protocol->filter_name = filter_name;
4357         protocol->fields = NULL;
4358         protocol->is_enabled = TRUE; /* protocol is enabled by default */
4359         protocol->can_toggle = TRUE;
4360         protocol->is_private = FALSE;
4361         /* list will be sorted later by name, when all protocols completed registering */
4362         protocols = g_list_prepend(protocols, protocol);
4363
4364         /* Here we allocate a new header_field_info struct */
4365         hfinfo = g_slice_new(header_field_info);
4366         hfinfo->name = name;
4367         hfinfo->abbrev = filter_name;
4368         hfinfo->type = FT_PROTOCOL;
4369         hfinfo->display = BASE_NONE;
4370         hfinfo->strings = protocol;
4371         hfinfo->bitmask = 0;
4372         hfinfo->ref_type = HF_REF_TYPE_NONE;
4373         hfinfo->blurb = NULL;
4374         hfinfo->parent = -1; /* this field differentiates protos and fields */
4375
4376         proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
4377         protocol->proto_id = proto_id;
4378         return proto_id;
4379 }
4380
4381 void
4382 proto_mark_private(const int proto_id)
4383 {
4384         protocol_t *protocol = find_protocol_by_id(proto_id);
4385         if (protocol)
4386                 protocol->is_private = TRUE;
4387 }
4388
4389 gboolean
4390 proto_is_private(const int proto_id)
4391 {
4392         protocol_t *protocol = find_protocol_by_id(proto_id);
4393         if (protocol)
4394                 return protocol->is_private;
4395         else
4396                 return FALSE;
4397 }
4398
4399 /*
4400  * Routines to use to iterate over the protocols.
4401  * The argument passed to the iterator routines is an opaque cookie to
4402  * their callers; it's the GList pointer for the current element in
4403  * the list.
4404  * The ID of the protocol is returned, or -1 if there is no protocol.
4405  */
4406 int
4407 proto_get_first_protocol(void **cookie)
4408 {
4409         protocol_t *protocol;
4410
4411         if (protocols == NULL)
4412                 return -1;
4413         *cookie = protocols;
4414         protocol = (protocol_t *)protocols->data;
4415         return protocol->proto_id;
4416 }
4417
4418 int
4419 proto_get_data_protocol(void *cookie)
4420 {
4421         GList *list_item = (GList *)cookie;
4422
4423         protocol_t *protocol = (protocol_t *)list_item->data;
4424         return protocol->proto_id;
4425 }
4426
4427 int
4428 proto_get_next_protocol(void **cookie)
4429 {
4430         GList      *list_item = (GList *)*cookie;
4431         protocol_t *protocol;
4432
4433         list_item = g_list_next(list_item);
4434         if (list_item == NULL)
4435                 return -1;
4436         *cookie = list_item;
4437         protocol = (protocol_t *)list_item->data;
4438         return protocol->proto_id;
4439 }
4440
4441 header_field_info *
4442 proto_get_first_protocol_field(const int proto_id, void **cookie)
4443 {
4444         protocol_t       *protocol = find_protocol_by_id(proto_id);
4445
4446         if ((protocol == NULL) || (protocol->fields == NULL))
4447                 return NULL;
4448
4449         *cookie = protocol->fields;
4450         return (header_field_info *)protocol->fields->data;
4451 }
4452
4453 header_field_info *
4454 proto_get_next_protocol_field(void **cookie)
4455 {
4456         GSList           *list_item = (GSList *)*cookie;
4457
4458         list_item = g_slist_next(list_item);
4459         if (list_item == NULL)
4460                 return NULL;
4461
4462         *cookie = list_item;
4463         return (header_field_info *)list_item->data;
4464 }
4465
4466 protocol_t *
4467 find_protocol_by_id(const int proto_id)
4468 {
4469         header_field_info *hfinfo;
4470
4471         if (proto_id < 0)
4472                 return NULL;
4473
4474         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
4475         DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
4476         return (protocol_t *)hfinfo->strings;
4477 }
4478
4479 static gint compare_filter_name(gconstpointer proto_arg,
4480                                 gconstpointer filter_name)
4481 {
4482         const protocol_t *protocol = (const protocol_t *)proto_arg;
4483         const gchar      *f_name   = (const gchar *)filter_name;
4484
4485         return (strcmp(protocol->filter_name, f_name));
4486 }
4487
4488 int
4489 proto_get_id(const protocol_t *protocol)
4490 {
4491         return protocol->proto_id;
4492 }
4493
4494 int proto_get_id_by_filter_name(const gchar* filter_name)
4495 {
4496         GList      *list_entry;
4497         protocol_t *protocol;
4498
4499         if(!filter_name){
4500                 fprintf(stderr, "No filter name present");
4501                 DISSECTOR_ASSERT(filter_name);
4502         }
4503
4504         list_entry = g_list_find_custom(protocols, filter_name,
4505                 compare_filter_name);
4506
4507         if (list_entry == NULL)
4508                 return -1;
4509         protocol = (protocol_t *)list_entry->data;
4510         return protocol->proto_id;
4511 }
4512
4513 const char *
4514 proto_get_protocol_name(const int proto_id)
4515 {
4516         protocol_t *protocol;
4517
4518         protocol = find_protocol_by_id(proto_id);
4519
4520         if (protocol == NULL)
4521                 return NULL;
4522         return protocol->name;
4523 }
4524
4525 const char *
4526 proto_get_protocol_short_name(const protocol_t *protocol)
4527 {
4528         if (protocol == NULL)
4529                 return "(none)";
4530         return protocol->short_name;
4531 }
4532
4533 const char *
4534 proto_get_protocol_long_name(const protocol_t *protocol)
4535 {
4536         if (protocol == NULL)
4537                 return "(none)";
4538         return protocol->name;
4539 }
4540
4541 const char *
4542 proto_get_protocol_filter_name(const int proto_id)
4543 {
4544         protocol_t *protocol;
4545
4546         protocol = find_protocol_by_id(proto_id);
4547         if (protocol == NULL)
4548                 return "(none)";
4549         return protocol->filter_name;
4550 }
4551
4552 gboolean
4553 proto_is_protocol_enabled(const protocol_t *protocol)
4554 {
4555         return protocol->is_enabled;
4556 }
4557
4558 gboolean
4559 proto_can_toggle_protocol(const int proto_id)
4560 {
4561         protocol_t *protocol;
4562
4563         protocol = find_protocol_by_id(proto_id);
4564         return protocol->can_toggle;
4565 }
4566
4567 void
4568 proto_set_decoding(const int proto_id, const gboolean enabled)
4569 {
4570         protocol_t *protocol;
4571
4572         protocol = find_protocol_by_id(proto_id);
4573         DISSECTOR_ASSERT(protocol->can_toggle);
4574         protocol->is_enabled = enabled;
4575 }
4576
4577 void
4578 proto_enable_all(void)
4579 {
4580         protocol_t *protocol;
4581         GList      *list_item = protocols;
4582
4583         if (protocols == NULL)
4584                 return;
4585
4586         while (list_item) {
4587                 protocol = (protocol_t *)list_item->data;
4588                 if (protocol->can_toggle)
4589                         protocol->is_enabled = TRUE;
4590                 list_item = g_list_next(list_item);
4591         }
4592 }
4593
4594 void
4595 proto_set_cant_toggle(const int proto_id)
4596 {
4597         protocol_t *protocol;
4598
4599         protocol = find_protocol_by_id(proto_id);
4600         protocol->can_toggle = FALSE;
4601 }
4602
4603 /* for use with static arrays only, since we don't allocate our own copies
4604 of the header_field_info struct contained within the hf_register_info struct */
4605 void
4606 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
4607 {
4608         int               field_id, i;
4609         hf_register_info *ptr = hf;
4610         protocol_t       *proto;
4611
4612         proto = find_protocol_by_id(parent);
4613         for (i = 0; i < num_records; i++, ptr++) {
4614                 /*
4615                  * Make sure we haven't registered this yet.
4616                  * Most fields have variables associated with them
4617                  * that are initialized to -1; some have array elements,
4618                  * or possibly uninitialized variables, so we also allow
4619                  * 0 (which is unlikely to be the field ID we get back
4620                  * from "proto_register_field_init()").
4621                  */
4622                 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
4623                         fprintf(stderr,
4624                                 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
4625                                 ptr->hfinfo.abbrev);
4626                         return;
4627                 }
4628
4629                 if (proto != NULL) {
4630                         if (proto->fields == NULL) {
4631                                 proto->fields = g_slist_append(NULL, &ptr->hfinfo);
4632                                 proto->last_field = proto->fields;
4633                         } else {
4634                                 proto->last_field =
4635                                         g_slist_append(proto->last_field, &ptr->hfinfo)->next;
4636                         }
4637                 }
4638                 field_id = proto_register_field_init(&ptr->hfinfo, parent);
4639                 *ptr->p_id = field_id;
4640         }
4641 }
4642
4643 void
4644 proto_register_fields(const int parent, header_field_info **hfi, const int num_records)
4645 {
4646         int               i;
4647         protocol_t       *proto;
4648
4649         proto = find_protocol_by_id(parent);
4650         for (i = 0; i < num_records; i++) {
4651                 /*
4652                  * Make sure we haven't registered this yet.
4653                  */
4654                 if (hfi[i]->id != -1) {
4655                         fprintf(stderr,
4656                                 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
4657                                 hfi[i]->abbrev);
4658                         return;
4659                 }
4660
4661                 if (proto != NULL) {
4662                         if (proto->fields == NULL) {
4663                                 proto->fields = g_slist_append(NULL, hfi[i]);
4664                                 proto->last_field = proto->fields;
4665                         } else {
4666                                 proto->last_field =
4667                                         g_slist_append(proto->last_field, hfi[i])->next;
4668                         }
4669                 }
4670                 proto_register_field_init(hfi[i], parent);
4671         }
4672 }
4673
4674 /* unregister already registered fields */
4675 void
4676 proto_unregister_field (const int parent, gint hf_id)
4677 {
4678         hf_register_info *hf;
4679         protocol_t       *proto;
4680         GSList           *field;
4681
4682         if (hf_id == -1 || hf_id == 0)
4683                 return;
4684
4685         proto = find_protocol_by_id (parent);
4686         if (!proto || !proto->fields) {
4687                 return;
4688         }
4689
4690         for (field = proto->fields; field; field = field->next) {
4691                 hf = (hf_register_info *)field->data;
4692                 if (*hf->p_id == hf_id) {
4693                         /* Found the hf_id in this protocol */
4694                         g_tree_steal (gpa_name_tree, hf->hfinfo.abbrev);
4695                         /* XXX, memleak? g_slist_delete_link() */
4696                         proto->fields = g_slist_remove_link (proto->fields, field);
4697                         proto->last_field = g_slist_last (proto->fields);
4698                         break;
4699                 }
4700         }
4701 }
4702
4703 /* chars allowed in field abbrev */
4704 static
4705 const guchar fld_abbrev_chars[256] = {
4706         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
4707         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
4708         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.'      */
4709         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9'       */
4710         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O'       */
4711         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
4712         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o'       */
4713         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z'       */
4714         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
4715         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
4716         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
4717         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
4718         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
4719         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
4720         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
4721         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
4722 };
4723
4724 static const value_string hf_types[] = {
4725         { FT_NONE,          "FT_NONE"          },
4726         { FT_PROTOCOL,      "FT_PROTOCOL"      },
4727         { FT_BOOLEAN,       "FT_BOOLEAN"       },
4728         { FT_UINT8,         "FT_UINT8"         },
4729         { FT_UINT16,        "FT_UINT16"        },
4730         { FT_UINT24,        "FT_UINT24"        },
4731         { FT_UINT32,        "FT_UINT32"        },
4732         { FT_UINT64,        "FT_UINT64"        },
4733         { FT_INT8,          "FT_INT8"          },
4734         { FT_INT16,         "FT_INT16"         },
4735         { FT_INT24,         "FT_INT24"         },
4736         { FT_INT32,         "FT_INT32"         },
4737         { FT_INT64,         "FT_INT64"         },
4738         { FT_EUI64,         "FT_EUI64"         },
4739         { FT_FLOAT,         "FT_FLOAT"         },
4740         { FT_DOUBLE,        "FT_DOUBLE"        },
4741         { FT_ABSOLUTE_TIME, "FT_ABSOLUTE_TIME" },
4742         { FT_RELATIVE_TIME, "FT_RELATIVE_TIME" },
4743         { FT_STRING,        "FT_STRING"        },
4744         { FT_STRINGZ,       "FT_STRINGZ"       },
4745         { FT_UINT_STRING,   "FT_UINT_STRING"   },
4746         { FT_ETHER,         "FT_ETHER"         },
4747         { FT_BYTES,         "FT_BYTES"         },
4748         { FT_UINT_BYTES,    "FT_UINT_BYTES"    },
4749         { FT_IPv4,          "FT_IPv4"          },
4750         { FT_IPv6,          "FT_IPv6"          },
4751         { FT_IPXNET,        "FT_IPXNET"        },
4752         { FT_FRAMENUM,      "FT_FRAMENUM"      },
4753         { FT_PCRE,          "FT_PCR"           },
4754         { FT_GUID,          "FT_GUID"          },
4755         { FT_OID,           "FT_OID"           },
4756         { FT_REL_OID,       "FT_REL_OID"       },
4757         { 0,                NULL } };
4758
4759 static const value_string hf_display[] = {
4760         { BASE_NONE,                      "BASE_NONE"                      },
4761         { BASE_DEC,                       "BASE_DEC"                       },
4762         { BASE_HEX,                       "BASE_HEX"                       },
4763         { BASE_OCT,                       "BASE_OCT"                       },
4764         { BASE_DEC_HEX,                   "BASE_DEC_HEX"                   },
4765         { BASE_HEX_DEC,                   "BASE_HEX_DEC"                   },
4766         { BASE_CUSTOM,                    "BASE_CUSTOM"                    },
4767         { BASE_NONE|BASE_RANGE_STRING,    "BASE_NONE|BASE_RANGE_STRING"    },
4768         { BASE_DEC|BASE_RANGE_STRING,     "BASE_DEC|BASE_RANGE_STRING"     },
4769         { BASE_HEX|BASE_RANGE_STRING,     "BASE_HEX|BASE_RANGE_STRING"     },
4770         { BASE_OCT|BASE_RANGE_STRING,     "BASE_OCT|BASE_RANGE_STRING"     },
4771         { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
4772         { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
4773         { BASE_CUSTOM|BASE_RANGE_STRING,  "BASE_CUSTOM|BASE_RANGE_STRING"  },
4774         { BASE_NONE|BASE_VAL64_STRING,    "BASE_NONE|BASE_VAL64_STRING"    },
4775         { BASE_DEC|BASE_VAL64_STRING,     "BASE_DEC|BASE_VAL64_STRING"     },
4776         { BASE_HEX|BASE_VAL64_STRING,     "BASE_HEX|BASE_VAL64_STRING"     },
4777         { BASE_OCT|BASE_VAL64_STRING,     "BASE_OCT|BASE_VAL64_STRING"     },
4778         { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
4779         { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
4780         { BASE_CUSTOM|BASE_VAL64_STRING,  "BASE_CUSTOM|BASE_VAL64_STRING"  },
4781         { ABSOLUTE_TIME_LOCAL,            "ABSOLUTE_TIME_LOCAL"            },
4782         { ABSOLUTE_TIME_UTC,              "ABSOLUTE_TIME_UTC"              },
4783         { ABSOLUTE_TIME_DOY_UTC,          "ABSOLUTE_TIME_DOY_UTC"          },
4784         { 0,                              NULL } };
4785
4786 /* temporary function containing assert part for easier profiling */
4787 static void
4788 tmp_fld_check_assert(header_field_info *hfinfo)
4789 {
4790
4791         /* The field must have a name (with length > 0) */
4792         if (!hfinfo->name || !hfinfo->name[0]) {
4793                 if (hfinfo->abbrev)
4794                         /* Try to identify the field */
4795                         g_error("Field (abbrev='%s') does not have a name\n",
4796                                 hfinfo->abbrev);
4797                 else
4798                         /* Hum, no luck */
4799                         g_error("Field does not have a name (nor an abbreviation)\n");
4800         }
4801
4802         /* fields with an empty string for an abbreviation aren't filterable */
4803         if (!hfinfo->abbrev || !hfinfo->abbrev[0])
4804                 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
4805
4806         /*  These types of fields are allowed to have value_strings,
4807          *  true_false_strings or a protocol_t struct
4808          */
4809         if (hfinfo->strings != NULL && !(
4810                     (hfinfo->type == FT_UINT8)    ||
4811                     (hfinfo->type == FT_UINT16)   ||
4812                     (hfinfo->type == FT_UINT24)   ||
4813                     (hfinfo->type == FT_UINT32)   ||
4814                     (hfinfo->type == FT_UINT64)   ||
4815                     (hfinfo->type == FT_INT8)     ||
4816                     (hfinfo->type == FT_INT16)    ||
4817                     (hfinfo->type == FT_INT24)    ||
4818                     (hfinfo->type == FT_INT32)    ||
4819                     (hfinfo->type == FT_INT64)    ||
4820                     (hfinfo->type == FT_BOOLEAN)  ||
4821                     (hfinfo->type == FT_PROTOCOL) ))
4822                 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
4823                         " (which is not allowed to have strings)\n",
4824                         hfinfo->name, hfinfo->abbrev,
4825                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
4826
4827         /* TODO: This check may slow down startup, and output quite a few warnings.
4828            It would be good to be able to enable this (and possibly other checks?)
4829            in non-release builds.   */
4830 #if 0
4831         /* Check for duplicate value_string values.
4832            There are lots that have the same value *and* string, so for now only
4833            report those that have same value but different string. */
4834         if ((hfinfo->strings != NULL) &&
4835             !(hfinfo->display & BASE_RANGE_STRING) &&
4836             !((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_CUSTOM) &&
4837             (
4838                     (hfinfo->type == FT_UINT8)  ||
4839                     (hfinfo->type == FT_UINT16) ||
4840                     (hfinfo->type == FT_UINT24) ||
4841                     (hfinfo->type == FT_UINT32) ||
4842                     (hfinfo->type == FT_INT8)   ||
4843                     (hfinfo->type == FT_INT16)  ||
4844                     (hfinfo->type == FT_INT24)  ||
4845                     (hfinfo->type == FT_INT32)  ||
4846                     (hfinfo->type == FT_FRAMENUM) )) {
4847
4848                 int n, m;
4849                 const value_string *start_values;
4850                 const value_string *current;
4851
4852             if (hfinfo->display & BASE_EXT_STRING)
4853                         start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
4854                 else
4855                         start_values = (const value_string*)hfinfo->strings;
4856                 current = start_values;
4857
4858                 for (n=0; current; n++, current++) {
4859                         /* Drop out if we reached the end. */
4860                         if ((current->value == 0) && (current->strptr == NULL)) {
4861                                 break;
4862                         }
4863
4864                         /* Check value against all previous */
4865                         for (m=0; m < n; m++) {
4866                                 /* There are lots of duplicates with the same string,
4867                                    so only report if different... */
4868                                 if ((start_values[m].value == current->value) &&
4869                                     (strcmp(start_values[m].strptr, current->strptr) != 0)) {
4870                                         g_warning("Field '%s' (%s) has a conflicting entry in its"
4871                                                   " value_string: %u is at indices %u (%s) and %u (%s))\n",
4872                                                   hfinfo->name, hfinfo->abbrev,
4873                                                   current->value, m, start_values[m].strptr, n, current->strptr);
4874                                 }
4875                         }
4876                 }
4877         }
4878 #endif
4879
4880
4881         switch (hfinfo->type) {
4882
4883                 case FT_INT8:
4884                 case FT_INT16:
4885                 case FT_INT24:
4886                 case FT_INT32:
4887                 case FT_INT64:
4888                         /*      Hexadecimal and octal are, in printf() and everywhere
4889                          *      else, unsigned so don't allow dissectors to register a
4890                          *      signed field to be displayed unsigned.  (Else how would
4891                          *      we display negative values?)
4892                          */
4893                         switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
4894                                 case BASE_HEX:
4895                                 case BASE_OCT:
4896                                 case BASE_DEC_HEX:
4897                                 case BASE_HEX_DEC:
4898                                         g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
4899                                                 hfinfo->name, hfinfo->abbrev,
4900                                                 val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
4901                                                 val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
4902                         }
4903                         /* FALL THROUGH */
4904                 case FT_UINT8:
4905                 case FT_UINT16:
4906                 case FT_UINT24:
4907                 case FT_UINT32:
4908                 case FT_UINT64:
4909                         /*  Require integral types (other than frame number,
4910                          *  which is always displayed in decimal) to have a
4911                          *  number base.
4912                          *  If there is a strings value then this base is not
4913                          *  normally used except when constructing a display
4914                          *  filter for a value not found in the strings lookup.
4915                          */
4916                         switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
4917                                 case BASE_DEC:
4918                                 case BASE_HEX:
4919                                 case BASE_OCT:
4920                                 case BASE_DEC_HEX:
4921                                 case BASE_HEX_DEC:
4922                                 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
4923                                         break;
4924                                 default:
4925                                         g_error("Field '%s' (%s) is an integral value (%s)"
4926                                                 " but is being displayed as %s\n",
4927                                                 hfinfo->name, hfinfo->abbrev,
4928                                                 val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
4929                                                 val_to_str(hfinfo->display, hf_display, "(Unknown: 0x%x)"));
4930                         }
4931                         break;
4932
4933                 case FT_PROTOCOL:
4934                 case FT_FRAMENUM:
4935                         if (hfinfo->display != BASE_NONE)
4936                                 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
4937                                         hfinfo->name, hfinfo->abbrev,
4938                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
4939                                         val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
4940                         if (hfinfo->bitmask != 0)
4941                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
4942                                         hfinfo->name, hfinfo->abbrev,
4943                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
4944                         break;
4945
4946                 case FT_BOOLEAN:
4947                         break;
4948
4949                 case FT_ABSOLUTE_TIME:
4950                         if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
4951                               hfinfo->display == ABSOLUTE_TIME_UTC   ||
4952                               hfinfo->display == ABSOLUTE_TIME_DOY_UTC))
4953                                 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
4954                                         hfinfo->name, hfinfo->abbrev,
4955                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
4956                                         val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
4957                         if (hfinfo->bitmask != 0)
4958                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
4959                                         hfinfo->name, hfinfo->abbrev,
4960                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
4961                         break;
4962
4963                 default:
4964                         if (hfinfo->display != BASE_NONE)
4965                                 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
4966                                         hfinfo->name, hfinfo->abbrev,
4967                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
4968                                         val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
4969                         if (hfinfo->bitmask != 0)
4970                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
4971                                         hfinfo->name, hfinfo->abbrev,
4972                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
4973                         if (hfinfo->strings != NULL)
4974                                 g_error("Field '%s' (%s) is an %s but has a strings value\n",
4975                                         hfinfo->name, hfinfo->abbrev,
4976                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
4977                         break;
4978         }
4979 }
4980
4981 static void
4982 register_type_length_mismatch(void)
4983 {
4984         static ei_register_info ei[] = {
4985                 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
4986                 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
4987         };
4988
4989         expert_module_t* expert_type_length_mismatch;
4990
4991         proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
4992
4993         expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
4994         expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
4995
4996         /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
4997            disabling them makes no sense. */
4998         proto_set_cant_toggle(proto_type_length_mismatch);
4999 }
5000
5001 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (120000+PRE_ALLOC_EXPERT_FIELDS_MEM)
5002 static int
5003 proto_register_field_init(header_field_info *hfinfo, const int parent)
5004 {
5005
5006         tmp_fld_check_assert(hfinfo);
5007
5008         hfinfo->parent         = parent;
5009         hfinfo->same_name_next = NULL;
5010         hfinfo->same_name_prev_id = -1;
5011
5012         /* if we always add and never delete, then id == len - 1 is correct */
5013         if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
5014                 if (!gpa_hfinfo.hfi) {
5015                         gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
5016                         gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
5017                 } else {
5018                         gpa_hfinfo.allocated_len += 1000;
5019                         gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
5020                                                    sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
5021                         /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
5022                 }
5023         }
5024         gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
5025         gpa_hfinfo.len++;
5026         hfinfo->id = gpa_hfinfo.len - 1;
5027
5028         /* if we have real names, enter this field in the name tree */
5029         if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
5030
5031                 header_field_info *same_name_next_hfinfo;
5032                 guchar c;
5033
5034                 /* Check that the filter name (abbreviation) is legal;
5035                  * it must contain only alphanumerics, '-', "_", and ".". */
5036                 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
5037                 if (c) {
5038                         fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
5039                         DISSECTOR_ASSERT(!c);
5040                 }
5041
5042                 /* We allow multiple hfinfo's to be registered under the same
5043                  * abbreviation. This was done for X.25, as, depending
5044                  * on whether it's modulo-8 or modulo-128 operation,
5045                  * some bitfield fields may be in different bits of
5046                  * a byte, and we want to be able to refer to that field
5047                  * with one name regardless of whether the packets
5048                  * are modulo-8 or modulo-128 packets. */
5049
5050                 same_name_hfinfo = NULL;
5051
5052                 g_tree_insert(gpa_name_tree, (gpointer) (hfinfo->abbrev), hfinfo);
5053                 /* GLIB 2.x - if it is already present
5054                  * the previous hfinfo with the same name is saved
5055                  * to same_name_hfinfo by value destroy callback */
5056                 if (same_name_hfinfo) {
5057                         /* There's already a field with this name.
5058                          * Put it after that field in the list of
5059                          * fields with this name, then allow the code
5060                          * after this if{} block to replace the old
5061                          * hfinfo with the new hfinfo in the GTree. Thus,
5062                          * we end up with a linked-list of same-named hfinfo's,
5063                          * with the root of the list being the hfinfo in the GTree */
5064                         same_name_next_hfinfo =
5065                                 same_name_hfinfo->same_name_next;
5066
5067                         hfinfo->same_name_next = same_name_next_hfinfo;
5068                         if (same_name_next_hfinfo)
5069                                 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
5070
5071                         same_name_hfinfo->same_name_next = hfinfo;
5072                         hfinfo->same_name_prev_id = same_name_hfinfo->id;
5073                 }
5074         }
5075
5076         return hfinfo->id;
5077 }
5078
5079 void
5080 proto_register_subtree_array(gint *const *indices, const int num_indices)
5081 {
5082         int     i;
5083         gint    *const *ptr = indices;
5084
5085         /*
5086          * If we've already allocated the array of tree types, expand
5087          * it; this lets plugins such as mate add tree types after
5088          * the initial startup.  (If we haven't already allocated it,
5089          * we don't allocate it; on the first pass, we just assign
5090          * ett values and keep track of how many we've assigned, and
5091          * when we're finished registering all dissectors we allocate
5092          * the array, so that we do only one allocation rather than
5093          * wasting CPU time and memory by growing the array for each
5094          * dissector that registers ett values.)
5095          */
5096         if (tree_is_expanded != NULL) {
5097                 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
5098
5099                 /* set new items to 0 */
5100                 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
5101                 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
5102                         tree_is_expanded[i >> 5] &= ~(1 << (i & 31));
5103         }
5104
5105         /*
5106          * Assign "num_indices" subtree numbers starting at "num_tree_types",
5107          * returning the indices through the pointers in the array whose
5108          * first element is pointed to by "indices", and update
5109          * "num_tree_types" appropriately.
5110          */
5111         for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
5112                 if (**ptr != -1) {
5113                         /* g_error will terminate the program */
5114                         g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
5115                                 " This is a development error:"
5116                                 " Either the subtree item type has already been assigned or"
5117                                 " was not initialized to -1.");
5118                 }
5119                 **ptr = num_tree_types;
5120         }
5121 }
5122
5123 static inline gsize
5124 label_concat(char *label_str, gsize pos, const char *str)
5125 {
5126         if (pos < ITEM_LABEL_LENGTH)
5127                 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
5128
5129         return pos;
5130 }
5131
5132 static void
5133 label_mark_truncated(char *label_str, gsize name_pos)
5134 {
5135         static const char trunc_str[] = " [truncated]";
5136         const size_t trunc_len = sizeof(trunc_str)-1;
5137
5138         /* ..... field_name: dataaaaaaaaaaaaa
5139          *                 |
5140          *                 ^^^^^ name_pos
5141          *
5142          * ..... field_name [truncated]: dataaaaaaaaaaaaa */
5143
5144         if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
5145                 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
5146                 memcpy(label_str + name_pos, trunc_str, trunc_len);
5147                 label_str[ITEM_LABEL_LENGTH-1] = '\0';
5148
5149         } else if (name_pos < ITEM_LABEL_LENGTH)
5150                 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
5151 }
5152
5153 static gsize
5154 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
5155 {
5156         gsize name_pos;
5157
5158         /* "%s: %s", hfinfo->name, text */
5159         name_pos = pos = label_concat(label_str, pos, hfinfo->name);
5160         pos = label_concat(label_str, pos, ": ");
5161         pos = label_concat(label_str, pos, text ? text : "(null)");
5162
5163         if (pos >= ITEM_LABEL_LENGTH) {
5164                 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
5165                 label_mark_truncated(label_str, name_pos);
5166         }
5167
5168         return pos;
5169 }
5170
5171 static gsize
5172 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
5173 {
5174         gsize name_pos;
5175
5176         /* "%s: %s (%s)", hfinfo->name, text, descr */
5177         name_pos = pos = label_concat(label_str, pos, hfinfo->name);
5178         pos = label_concat(label_str, pos, ": ");
5179         pos = label_concat(label_str, pos, text ? text : "(null)");
5180         pos = label_concat(label_str, pos, " (");
5181         pos = label_concat(label_str, pos, descr ? descr : "(null)");
5182         pos = label_concat(label_str, pos, ")");
5183
5184         if (pos >= ITEM_LABEL_LENGTH) {
5185                 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
5186                 label_mark_truncated(label_str, name_pos);
5187         }
5188
5189         return pos;
5190 }
5191
5192 void
5193 proto_item_fill_label(field_info *fi, gchar *label_str)
5194 {
5195         header_field_info *hfinfo;
5196         guint8            *bytes;
5197         guint32            integer;
5198         guint64            integer64;
5199         ipv4_addr         *ipv4;
5200         e_guid_t          *guid;
5201         guint32            n_addr; /* network-order IPv4 address */
5202         const gchar       *name;
5203         address            addr;
5204
5205         if (!fi) {
5206                 if (label_str)
5207                         label_str[0]= '\0';
5208                 /* XXX: Check validity of hfinfo->type */
5209                 return;
5210         }
5211
5212         hfinfo = fi->hfinfo;
5213
5214         switch (hfinfo->type) {
5215                 case FT_NONE:
5216                 case FT_PROTOCOL:
5217                         g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
5218                         break;
5219
5220                 case FT_BOOLEAN:
5221                         fill_label_boolean(fi, label_str);
5222                         break;
5223
5224                 case FT_BYTES:
5225                 case FT_UINT_BYTES:
5226                         bytes = (guint8 *)fvalue_get(&fi->value);
5227                         label_fill(label_str, 0, hfinfo,
5228                                         (bytes) ? bytes_to_str(bytes, fvalue_length(&fi->value)) : "<MISSING>");
5229                         break;
5230
5231                 /* Four types of integers to take care of:
5232                  *      Bitfield, with val_string
5233                  *      Bitfield, w/o val_string
5234                  *      Non-bitfield, with val_string
5235                  *      Non-bitfield, w/o val_string
5236                  */
5237                 case FT_UINT8:
5238                 case FT_UINT16:
5239                 case FT_UINT24:
5240                 case FT_UINT32:
5241                         if (hfinfo->bitmask) {
5242                                 fill_label_bitfield(fi, label_str, FALSE);
5243                         } else {
5244                                 fill_label_number(fi, label_str, FALSE);
5245                         }
5246                         break;
5247
5248                 case FT_FRAMENUM:
5249                         fill_label_number(fi, label_str, FALSE);
5250                         break;
5251
5252                 case FT_UINT64:
5253                         fill_label_number64(fi, label_str, FALSE);
5254                         break;
5255
5256                 case FT_INT8:
5257                 case FT_INT16:
5258                 case FT_INT24:
5259                 case FT_INT32:
5260                         if (hfinfo->bitmask) {
5261                                 fill_label_bitfield(fi, label_str, TRUE);
5262                         } else {
5263                                 fill_label_number(fi, label_str, TRUE);
5264                         }
5265                         break;
5266
5267                 case FT_INT64:
5268                         fill_label_number64(fi, label_str, TRUE);
5269                         break;
5270
5271                 case FT_FLOAT:
5272                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
5273                                    "%s: %." STRINGIFY(FLT_DIG) "g",
5274                                    hfinfo->name, fvalue_get_floating(&fi->value));
5275                         break;
5276
5277                 case FT_DOUBLE:
5278                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
5279                                    "%s: %." STRINGIFY(DBL_DIG) "g",
5280                                    hfinfo->name, fvalue_get_floating(&fi->value));
5281                         break;
5282
5283                 case FT_ABSOLUTE_TIME:
5284                         label_fill(label_str, 0, hfinfo,
5285                                    abs_time_to_str((const nstime_t *)fvalue_get(&fi->value),
5286                                                 (absolute_time_display_e)hfinfo->display, TRUE));
5287                         break;
5288
5289                 case FT_RELATIVE_TIME:
5290                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
5291                                    "%s: %s seconds", hfinfo->name,
5292                                    rel_time_to_secs_str((const nstime_t *)fvalue_get(&fi->value)));
5293                         break;
5294
5295                 case FT_IPXNET:
5296                         integer = fvalue_get_uinteger(&fi->value);
5297                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
5298                                    "%s: %s (0x%08X)", hfinfo->name,
5299                                    get_ipxnet_name(integer), integer);
5300                         break;
5301
5302                 case FT_AX25:
5303                         bytes = (guint8 *)fvalue_get(&fi->value);
5304                         label_fill_descr(label_str, 0, hfinfo,
5305                                    get_ax25_name(bytes),
5306                                    ax25_to_str(bytes));
5307                         break;
5308
5309                 case FT_VINES:
5310                         addr.type = AT_VINES;
5311                         addr.len  = VINES_ADDR_LEN;
5312                         addr.data = (guint8 *)fvalue_get(&fi->value);
5313
5314                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
5315                                    "%s: %s", hfinfo->name,
5316                                    address_to_str( &addr ));
5317                         break;
5318
5319                 case FT_ETHER:
5320                         bytes = (guint8 *)fvalue_get(&fi->value);
5321                         label_fill_descr(label_str, 0, hfinfo,
5322                                    get_ether_name(bytes),
5323                                    ether_to_str(bytes));
5324                         break;
5325
5326                 case FT_IPv4:
5327                         ipv4 = (ipv4_addr *)fvalue_get(&fi->value);
5328                         n_addr = ipv4_get_net_order_addr(ipv4);
5329                         label_fill_descr(label_str, 0, hfinfo,
5330                                    get_hostname(n_addr),
5331                                    ip_to_str((guint8*)&n_addr));
5332                         break;
5333
5334                 case FT_IPv6:
5335                         bytes = (guint8 *)fvalue_get(&fi->value);
5336                         label_fill_descr(label_str, 0, hfinfo,
5337                                    get_hostname6((struct e_in6_addr *)bytes),
5338                                    ip6_to_str((struct e_in6_addr*)bytes));
5339                         break;
5340
5341                 case FT_GUID:
5342                         guid = (e_guid_t *)fvalue_get(&fi->value);
5343                         label_fill(label_str, 0, hfinfo, guid_to_str(guid));
5344                         break;
5345
5346                 case FT_OID:
5347                         bytes = (guint8 *)fvalue_get(&fi->value);
5348                         name = oid_resolved_from_encoded(bytes, fvalue_length(&fi->value));
5349                         if (name) {
5350                                 label_fill_descr(label_str, 0, hfinfo,
5351                                          oid_encoded2string(bytes, fvalue_length(&fi->value)), name);
5352                         } else {
5353                                 label_fill(label_str, 0, hfinfo,
5354                                          oid_encoded2string(bytes, fvalue_length(&fi->value)));
5355                         }
5356                         break;
5357
5358                 case FT_REL_OID:
5359                         bytes = (guint8 *)fvalue_get(&fi->value);
5360                         name = rel_oid_resolved_from_encoded(bytes, fvalue_length(&fi->value));
5361                         if (name) {
5362                                 label_fill_descr(label_str, 0, hfinfo,
5363                                          rel_oid_encoded2string(bytes, fvalue_length(&fi->value)), name);
5364                         } else {
5365                                 label_fill(label_str, 0, hfinfo,
5366                                          rel_oid_encoded2string(bytes, fvalue_length(&fi->value)));
5367                         }
5368                         break;
5369
5370                 case FT_EUI64:
5371                         integer64 = fvalue_get_integer64(&fi->value);
5372                         label_fill_descr(label_str, 0, hfinfo,
5373                                    get_eui64_name(integer64),
5374                                    eui64_to_str(integer64));
5375                         break;
5376                 case FT_STRING:
5377                 case FT_STRINGZ:
5378                 case FT_UINT_STRING:
5379                         bytes = (guint8 *)fvalue_get(&fi->value);
5380                         label_fill(label_str, 0, hfinfo, format_text(bytes, strlen(bytes)));
5381                         break;
5382
5383                 default:
5384                         g_error("hfinfo->type %d (%s) not handled\n",
5385                                 hfinfo->type, ftype_name(hfinfo->type));
5386                         DISSECTOR_ASSERT_NOT_REACHED();
5387                         break;
5388         }
5389 }
5390
5391 static void
5392 fill_label_boolean(field_info *fi, gchar *label_str)
5393 {
5394         char    *p                    = label_str;
5395         int      bitfield_byte_length = 0, bitwidth;
5396         guint32  unshifted_value;
5397         guint32  value;
5398
5399         header_field_info       *hfinfo   = fi->hfinfo;
5400         const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
5401
5402         if (hfinfo->strings) {
5403                 tfstring = (const struct true_false_string*) hfinfo->strings;
5404         }
5405
5406         value = fvalue_get_uinteger(&fi->value);
5407         if (hfinfo->bitmask) {
5408                 /* Figure out the bit width */
5409                 bitwidth = hfinfo_bitwidth(hfinfo);
5410
5411                 /* Un-shift bits */
5412                 unshifted_value = value;
5413                 unshifted_value <<= hfinfo_bitshift(hfinfo);
5414
5415                 /* Create the bitfield first */
5416                 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
5417                 bitfield_byte_length = (int) (p - label_str);
5418         }
5419
5420         /* Fill in the textual info */
5421         label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
5422 }
5423
5424 static const char *
5425 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
5426 {
5427         if (hfinfo->display & BASE_RANGE_STRING)
5428                 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
5429
5430         if (hfinfo->display & BASE_EXT_STRING)
5431                 return try_val_to_str_ext(value, (const value_string_ext *) hfinfo->strings);
5432
5433         if (hfinfo->display & BASE_VAL64_STRING)
5434                 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
5435
5436         return try_val_to_str(value, (const value_string *) hfinfo->strings);
5437 }
5438
5439 static const char *
5440 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
5441 {
5442         if (hfinfo->display & BASE_VAL64_STRING)
5443                 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
5444
5445         /* If this is reached somebody registered a 64-bit field with a 32-bit
5446          * value-string, which isn't right. */
5447         DISSECTOR_ASSERT_NOT_REACHED();
5448
5449         /* This is necessary to squelch MSVC errors; is there
5450            any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
5451            never returns? */
5452         return NULL;
5453 }
5454
5455 static const char *
5456 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
5457 {
5458         const char *str = hf_try_val_to_str(value, hfinfo);
5459
5460         return (str) ? str : unknown_str;
5461 }
5462
5463 static const char *
5464 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
5465 {
5466         const char *str = hf_try_val64_to_str(value, hfinfo);
5467
5468         return (str) ? str : unknown_str;
5469 }
5470
5471 /* Fills data for bitfield ints with val_strings */
5472 static void
5473 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
5474 {
5475         char       *p;
5476         int         bitfield_byte_length, bitwidth;
5477         guint32     unshifted_value;
5478         guint32     value;
5479
5480         char        buf[32];
5481         const char *out;
5482
5483         header_field_info *hfinfo = fi->hfinfo;
5484
5485         /* Figure out the bit width */
5486         bitwidth = hfinfo_bitwidth(hfinfo);
5487
5488         /* Un-shift bits */
5489         if (is_signed)
5490                 unshifted_value = fvalue_get_sinteger(&fi->value);
5491         else
5492                 unshifted_value = fvalue_get_uinteger(&fi->value);
5493
5494         value = unshifted_value;
5495         if (hfinfo->bitmask) {
5496                 unshifted_value <<= hfinfo_bitshift(hfinfo);
5497         }
5498
5499         /* Create the bitfield first */
5500         p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
5501         bitfield_byte_length = (int) (p - label_str);
5502
5503         /* Fill in the textual info using stored (shifted) value */
5504         if (hfinfo->display == BASE_CUSTOM) {
5505                 gchar tmp[ITEM_LABEL_LENGTH];
5506                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
5507
5508                 DISSECTOR_ASSERT(fmtfunc);
5509                 fmtfunc(tmp, value);
5510                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
5511         }
5512         else if (hfinfo->strings) {
5513                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
5514
5515                 out = hfinfo_number_vals_format(hfinfo, buf, value);
5516                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
5517                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
5518                 else
5519                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
5520         }
5521         else {
5522                 out = hfinfo_number_value_format(hfinfo, buf, value);
5523
5524                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
5525         }
5526 }
5527
5528 static void
5529 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
5530 {
5531         header_field_info *hfinfo = fi->hfinfo;
5532         guint32            value;
5533
5534         char               buf[32];
5535         const char        *out;
5536
5537         if (is_signed)
5538                 value = fvalue_get_sinteger(&fi->value);
5539         else
5540                 value = fvalue_get_uinteger(&fi->value);
5541
5542         /* Fill in the textual info */
5543         if (hfinfo->display == BASE_CUSTOM) {
5544                 gchar tmp[ITEM_LABEL_LENGTH];
5545                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
5546
5547                 DISSECTOR_ASSERT(fmtfunc);
5548                 fmtfunc(tmp, value);
5549                 label_fill(label_str, 0, hfinfo, tmp);
5550         }
5551         else if (hfinfo->strings) {
5552                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
5553
5554                 out = hfinfo_number_vals_format(hfinfo, buf, value);
5555                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
5556                         label_fill(label_str, 0, hfinfo, val_str);
5557                 else
5558                         label_fill_descr(label_str, 0, hfinfo, val_str, out);
5559         }
5560         else {
5561                 out = hfinfo_number_value_format(hfinfo, buf, value);
5562
5563                 label_fill(label_str, 0, hfinfo, out);
5564         }
5565 }
5566
5567 static void
5568 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
5569 {
5570         const char        *format = NULL;
5571         header_field_info *hfinfo = fi->hfinfo;
5572         guint64            value;
5573         char               tmp[ITEM_LABEL_LENGTH+1];
5574
5575         /* Pick the proper format string */
5576         if (is_signed)
5577                 format = hfinfo_int64_format(hfinfo);
5578         else
5579                 format = hfinfo_uint64_format(hfinfo);
5580
5581         value = fvalue_get_integer64(&fi->value);
5582
5583         /* Format the temporary string */
5584         if (IS_BASE_DUAL(hfinfo->display))
5585                 g_snprintf(tmp, ITEM_LABEL_LENGTH, format, value, value);
5586         else
5587                 g_snprintf(tmp, ITEM_LABEL_LENGTH, format, value);
5588
5589         if (hfinfo->strings) {
5590                 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
5591
5592                 if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
5593                         label_fill(label_str, 0, hfinfo, val_str);
5594                 }
5595                 else {
5596                         label_fill_descr(label_str, 0, hfinfo, val_str, tmp);
5597                 }
5598         }
5599         else {
5600                 label_fill(label_str, 0, hfinfo, tmp);
5601         }
5602 }
5603
5604 int
5605 hfinfo_bitshift(const header_field_info *hfinfo)
5606 {
5607         const guint32 bitmask = hfinfo->bitmask;
5608
5609 #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5610         g_assert(bitmask != 0);
5611
5612         return __builtin_ctz(bitmask);
5613 #else
5614         /* From http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup */
5615         static const int table[32] = {
5616                 0,   1, 28,  2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17,  4, 8,
5617                 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18,  6, 11,  5, 10, 9
5618         };
5619
5620         return table[((guint32)((bitmask & -(gint32)bitmask) * 0x077CB531U)) >> 27];
5621 #endif
5622 }
5623
5624 int
5625 hfinfo_bitwidth(const header_field_info *hfinfo)
5626 {
5627         int bitwidth = 0;
5628
5629         if (!hfinfo->bitmask) {
5630                 return 0;
5631         }
5632
5633         switch (hfinfo->type) {
5634                 case FT_UINT8:
5635                 case FT_INT8:
5636                         bitwidth = 8;
5637                         break;
5638                 case FT_UINT16:
5639                 case FT_INT16:
5640                         bitwidth = 16;
5641                         break;
5642                 case FT_UINT24:
5643                 case FT_INT24:
5644                         bitwidth = 24;
5645                         break;
5646                 case FT_UINT32:
5647                 case FT_INT32:
5648                         bitwidth = 32;
5649                         break;
5650                 case FT_BOOLEAN:
5651                         bitwidth = hfinfo->display; /* hacky? :) */
5652                         break;
5653                 default:
5654                         DISSECTOR_ASSERT_NOT_REACHED();
5655                         ;
5656         }
5657         return bitwidth;
5658 }
5659
5660 static int
5661 _hfinfo_type_hex_octet(int type)
5662 {
5663         switch (type) {
5664                 case FT_INT8:
5665                 case FT_UINT8:
5666                         return 2;
5667
5668                 case FT_UINT16:
5669                 case FT_INT16:
5670                         return 4;
5671
5672                 case FT_UINT24:
5673                 case FT_INT24:
5674                         return 6;
5675
5676                 case FT_UINT32:
5677                 case FT_INT32:
5678                         return 8;
5679
5680                 default:
5681                         DISSECTOR_ASSERT_NOT_REACHED();
5682                         ;
5683         }
5684         return -1;
5685 }
5686
5687 /* private to_str.c API don't export to .h! */
5688 char *oct_to_str_back(char *ptr, guint32 value);
5689 char *hex_to_str_back(char *ptr, int pad, guint32 value);
5690 char *uint_to_str_back(char *ptr, guint32 value);
5691 char *int_to_str_back(char *ptr, gint32 value);
5692
5693 static const char *
5694 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
5695 {
5696         char *ptr = &buf[31];
5697         gboolean isint = IS_FT_INT(hfinfo->type);
5698
5699         *ptr = '\0';
5700         /* Properly format value */
5701                 switch (display) {
5702                         case BASE_DEC:
5703                                 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
5704
5705                         case BASE_DEC_HEX:
5706                                 *(--ptr) = ')';
5707                                 ptr = hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
5708                                 *(--ptr) = '(';
5709                                 *(--ptr) = ' ';
5710                                 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
5711                                 return ptr;
5712
5713                         case BASE_OCT:
5714                                 return oct_to_str_back(ptr, value);
5715
5716                         case BASE_HEX:
5717                                 return hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
5718
5719                         case BASE_HEX_DEC:
5720                                 *(--ptr) = ')';
5721                                 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
5722                                 *(--ptr) = '(';
5723                                 *(--ptr) = ' ';
5724                                 ptr = hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
5725                                 return ptr;
5726
5727                         default:
5728                                 DISSECTOR_ASSERT_NOT_REACHED();
5729                                 ;
5730                 }
5731         return ptr;
5732 }
5733
5734 static const char *
5735 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
5736 {
5737         int display = hfinfo->display;
5738
5739         if (hfinfo->type == FT_FRAMENUM) {
5740                 /*
5741                  * Frame numbers are always displayed in decimal.
5742                  */
5743                 display = BASE_DEC;
5744         }
5745
5746         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
5747 }
5748
5749 static const char *
5750 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
5751 {
5752         /* Get the underlying BASE_ value */
5753         int display = hfinfo->display & BASE_DISPLAY_E_MASK;
5754
5755         if (hfinfo->type == FT_FRAMENUM) {
5756                 /*
5757                  * Frame numbers are always displayed in decimal.
5758                  */
5759                 display = BASE_DEC;
5760         }
5761
5762         switch (display) {
5763                 case BASE_NONE:
5764                 /* case BASE_DEC: */
5765                 case BASE_DEC_HEX:
5766                 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
5767                 case BASE_CUSTOM:
5768                         display = BASE_DEC;
5769                         break;
5770
5771                 /* case BASE_HEX: */
5772                 case BASE_HEX_DEC:
5773                         display = BASE_HEX;
5774                         break;
5775         }
5776
5777         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
5778 }
5779
5780 static const char *
5781 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
5782 {
5783         /* Get the underlying BASE_ value */
5784         int display = hfinfo->display & BASE_DISPLAY_E_MASK;
5785
5786         if (display == BASE_NONE)
5787                 return NULL;
5788
5789         if (display == BASE_DEC_HEX)
5790                 display = BASE_DEC;
5791         if (display == BASE_HEX_DEC)
5792                 display = BASE_HEX;
5793
5794         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
5795 }
5796
5797 static const char *
5798 hfinfo_uint64_format(const header_field_info *hfinfo)
5799 {
5800         const char *format = NULL;
5801
5802         /* Pick the proper format string */
5803         switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
5804                 case BASE_DEC:
5805                         format = "%" G_GINT64_MODIFIER "u";
5806                         break;
5807                 case BASE_DEC_HEX:
5808                         format = "%" G_GINT64_MODIFIER "u (0x%016" G_GINT64_MODIFIER "x)";
5809                         break;
5810                 case BASE_OCT: /* I'm lazy */
5811                         format = "%#" G_GINT64_MODIFIER "o";
5812                         break;
5813                 case BASE_HEX:
5814                         format = "0x%016" G_GINT64_MODIFIER "x";
5815                         break;
5816                 case BASE_HEX_DEC:
5817                         format = "0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "u)";
5818                         break;
5819                 default:
5820                         DISSECTOR_ASSERT_NOT_REACHED();
5821                         ;
5822         }
5823         return format;
5824 }
5825
5826 static const char *
5827 hfinfo_int64_format(const header_field_info *hfinfo)
5828 {
5829         const char *format = NULL;
5830
5831         /* Pick the proper format string */
5832         switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
5833                 case BASE_DEC:
5834                         format = "%" G_GINT64_MODIFIER "d";
5835                         break;
5836                 case BASE_DEC_HEX:
5837                         format = "%" G_GINT64_MODIFIER "d (0x%016" G_GINT64_MODIFIER "x)";
5838                         break;
5839                 case BASE_OCT: /* I'm lazy */
5840                         format = "%#" G_GINT64_MODIFIER "o";
5841                         break;
5842                 case BASE_HEX:
5843                         format = "0x%016" G_GINT64_MODIFIER "x";
5844                         break;
5845                 case BASE_HEX_DEC:
5846                         format = "0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)";
5847                         break;
5848                 default:
5849                         DISSECTOR_ASSERT_NOT_REACHED();
5850                         ;
5851         }
5852         return format;
5853 }
5854
5855 int
5856 proto_registrar_n(void)
5857 {
5858         return gpa_hfinfo.len;
5859 }
5860
5861 const char *
5862 proto_registrar_get_name(const int n)
5863 {
5864         header_field_info *hfinfo;
5865
5866         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5867         return hfinfo->name;
5868 }
5869
5870 const char *
5871 proto_registrar_get_abbrev(const int n)
5872 {
5873         header_field_info *hfinfo;
5874
5875         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5876         return hfinfo->abbrev;
5877 }
5878
5879 enum ftenum
5880 proto_registrar_get_ftype(const int n)
5881 {
5882         header_field_info *hfinfo;
5883
5884         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5885         return hfinfo->type;
5886 }
5887
5888 int
5889 proto_registrar_get_parent(const int n)
5890 {
5891         header_field_info *hfinfo;
5892
5893         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5894         return hfinfo->parent;
5895 }
5896
5897 gboolean
5898 proto_registrar_is_protocol(const int n)
5899 {
5900         header_field_info *hfinfo;
5901
5902         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5903         return (hfinfo->parent == -1 ? TRUE : FALSE);
5904 }
5905
5906 /* Returns length of field in packet (not necessarily the length
5907  * in our internal representation, as in the case of IPv4).
5908  * 0 means undeterminable at time of registration
5909  * -1 means the field is not registered. */
5910 gint
5911 proto_registrar_get_length(const int n)
5912 {
5913         header_field_info *hfinfo;
5914
5915         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5916         return ftype_length(hfinfo->type);
5917 }
5918
5919 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
5920  * it exists anywhere, or FALSE if it exists nowhere. */
5921 gboolean
5922 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
5923 {
5924         GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
5925
5926         if (!ptrs) {
5927                 return FALSE;
5928         }
5929         else if (g_ptr_array_len(ptrs) > 0) {
5930                 return TRUE;
5931         }
5932         else {
5933                 return FALSE;
5934         }
5935 }
5936
5937 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
5938  * This only works if the hfindex was "primed" before the dissection
5939  * took place, as we just pass back the already-created GPtrArray*.
5940  * The caller should *not* free the GPtrArray*; proto_tree_free_node()
5941  * handles that. */
5942 GPtrArray *
5943 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
5944 {
5945         if (!tree)
5946                 return NULL;
5947
5948         if (PTREE_DATA(tree)->interesting_hfids != NULL)
5949                 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
5950                                            GINT_TO_POINTER(id));
5951         else
5952                 return NULL;
5953 }
5954
5955 gboolean
5956 proto_tracking_interesting_fields(const proto_tree *tree)
5957 {
5958         if (!tree)
5959                 return FALSE;
5960
5961         return (PTREE_DATA(tree)->interesting_hfids != NULL);
5962 }
5963
5964 /* Helper struct for proto_find_info() and      proto_all_finfos() */
5965 typedef struct {
5966         GPtrArray *array;
5967         int        id;
5968 } ffdata_t;
5969
5970 /* Helper function for proto_find_info() */
5971 static gboolean
5972 find_finfo(proto_node *node, gpointer data)
5973 {
5974         field_info *fi = PNODE_FINFO(node);
5975         if (fi && fi->hfinfo) {
5976                 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
5977                         g_ptr_array_add(((ffdata_t*)data)->array, fi);
5978                 }
5979         }
5980
5981         /* Don't stop traversing. */
5982         return FALSE;
5983 }
5984
5985 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
5986 * This works on any proto_tree, primed or unprimed, but actually searches
5987 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
5988 * The caller does need to free the returned GPtrArray with
5989 * g_ptr_array_free(<array>, TRUE).
5990 */
5991 GPtrArray *
5992 proto_find_finfo(proto_tree *tree, const int id)
5993 {
5994         ffdata_t ffdata;
5995
5996         ffdata.array = g_ptr_array_new();
5997         ffdata.id = id;
5998
5999         proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
6000
6001         return ffdata.array;
6002 }
6003
6004 /* Helper function for proto_all_finfos() */
6005 static gboolean
6006 every_finfo(proto_node *node, gpointer data)
6007 {
6008         field_info *fi = PNODE_FINFO(node);
6009         if (fi && fi->hfinfo) {
6010                 g_ptr_array_add(((ffdata_t*)data)->array, fi);
6011         }
6012
6013         /* Don't stop traversing. */
6014         return FALSE;
6015 }
6016
6017 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
6018 GPtrArray *
6019 proto_all_finfos(proto_tree *tree)
6020 {
6021         ffdata_t ffdata;
6022
6023         ffdata.array = g_ptr_array_new();
6024         ffdata.id = 0;
6025
6026         proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
6027
6028         return ffdata.array;
6029 }
6030
6031
6032 typedef struct {
6033         guint       offset;
6034         field_info *finfo;
6035         tvbuff_t   *tvb;
6036 } offset_search_t;
6037
6038 static gboolean
6039 check_for_offset(proto_node *node, const gpointer data)
6040 {
6041         field_info      *fi        = PNODE_FINFO(node);
6042         offset_search_t *offsearch = (offset_search_t *)data;
6043
6044         /* !fi == the top most container node which holds nothing */
6045         if (fi && !PROTO_ITEM_IS_HIDDEN(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
6046                 if (offsearch->offset >= (guint) fi->start &&
6047                                 offsearch->offset < (guint) (fi->start + fi->length)) {
6048
6049                         offsearch->finfo = fi;
6050                         return FALSE; /* keep traversing */
6051                 }
6052         }
6053         return FALSE; /* keep traversing */
6054 }
6055
6056 /* Search a proto_tree backwards (from leaves to root) looking for the field
6057  * whose start/length occupies 'offset' */
6058 /* XXX - I couldn't find an easy way to search backwards, so I search
6059  * forwards, w/o stopping. Therefore, the last finfo I find will the be
6060  * the one I want to return to the user. This algorithm is inefficient
6061  * and could be re-done, but I'd have to handle all the children and
6062  * siblings of each node myself. When I have more time I'll do that.
6063  * (yeah right) */
6064 field_info *
6065 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
6066 {
6067         offset_search_t offsearch;
6068
6069         offsearch.offset = offset;
6070         offsearch.finfo  = NULL;
6071         offsearch.tvb    = tvb;
6072
6073         proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
6074
6075         return offsearch.finfo;
6076 }
6077
6078 /* Dumps the protocols in the registration database to stdout.  An independent
6079  * program can take this output and format it into nice tables or HTML or
6080  * whatever.
6081  *
6082  * There is one record per line. The fields are tab-delimited.
6083  *
6084  * Field 1 = protocol name
6085  * Field 2 = protocol short name
6086  * Field 3 = protocol filter name
6087  */
6088 void
6089 proto_registrar_dump_protocols(void)
6090 {
6091         protocol_t *protocol;
6092         int         i;
6093         void       *cookie = NULL;
6094
6095
6096         i = proto_get_first_protocol(&cookie);
6097         while (i != -1) {
6098                 protocol = find_protocol_by_id(i);
6099                 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
6100                         protocol->filter_name);
6101                 i = proto_get_next_protocol(&cookie);
6102         }
6103 }
6104
6105 /* Dumps the value_strings, extended value string headers, range_strings
6106  * or true/false strings for fields that have them.
6107  * There is one record per line. Fields are tab-delimited.
6108  * There are four types of records: Value String, Extended Value String Header,
6109  * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
6110  * the type of record.
6111  *
6112  * Note that a record will be generated only if the value_string,... is referenced
6113  * in a registered hfinfo entry.
6114  *
6115  *
6116  * Value Strings
6117  * -------------
6118  * Field 1 = 'V'
6119  * Field 2 = Field abbreviation to which this value string corresponds
6120  * Field 3 = Integer value
6121  * Field 4 = String
6122  *
6123  * Extended Value String Headers
6124  * -----------------------------
6125  * Field 1 = 'E'
6126  * Field 2 = Field abbreviation to which this extended value string header corresponds
6127  * Field 3 = Extended Value String "Name"
6128  * Field 4 = Number of entries in the associated value_string array
6129  * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
6130  *
6131  * Range Strings
6132  * -------------
6133  * Field 1 = 'R'
6134  * Field 2 = Field abbreviation to which this range string corresponds
6135  * Field 3 = Integer value: lower bound
6136  * Field 4 = Integer value: upper bound
6137  * Field 5 = String
6138  *
6139  * True/False Strings
6140  * ------------------
6141  * Field 1 = 'T'
6142  * Field 2 = Field abbreviation to which this true/false string corresponds
6143  * Field 3 = True String
6144  * Field 4 = False String
6145  */
6146 void
6147 proto_registrar_dump_values(void)
6148 {
6149         header_field_info       *hfinfo;
6150         int                     i, len, vi;
6151         const value_string      *vals;
6152         const val64_string      *vals64;
6153         const range_string      *range;
6154         const true_false_string *tfs;
6155
6156         len = gpa_hfinfo.len;
6157         for (i = 0; i < len ; i++) {
6158                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
6159
6160                  if (hfinfo->id == hf_text_only) {
6161                          continue;
6162                  }
6163
6164                 /* ignore protocols */
6165                 if (proto_registrar_is_protocol(i)) {
6166                         continue;
6167                 }
6168                 /* process header fields */
6169                 else {
6170                         /*
6171                          * If this field isn't at the head of the list of
6172                          * fields with this name, skip this field - all
6173                          * fields with the same name are really just versions
6174                          * of the same field stored in different bits, and
6175                          * should have the same type/radix/value list, and
6176                          * just differ in their bit masks.      (If a field isn't
6177                          * a bitfield, but can be, say, 1 or 2 bytes long,
6178                          * it can just be made FT_UINT16, meaning the
6179                          * *maximum* length is 2 bytes, and be used
6180                          * for all lengths.)
6181                          */
6182                         if (hfinfo->same_name_prev_id != -1)
6183                                 continue;
6184
6185                         vals   = NULL;
6186                         vals64 = NULL;
6187                         range  = NULL;
6188                         tfs    = NULL;
6189
6190                         if (hfinfo->strings != NULL) {
6191                                 if ((hfinfo->display & BASE_DISPLAY_E_MASK) != BASE_CUSTOM &&
6192                                     (hfinfo->type == FT_UINT8  ||
6193                                      hfinfo->type == FT_UINT16 ||
6194                                      hfinfo->type == FT_UINT24 ||
6195                                      hfinfo->type == FT_UINT32 ||
6196                                      hfinfo->type == FT_UINT64 ||
6197                                      hfinfo->type == FT_INT8   ||
6198                                      hfinfo->type == FT_INT16  ||
6199                                      hfinfo->type == FT_INT24  ||
6200                                      hfinfo->type == FT_INT32  ||
6201                                      hfinfo->type == FT_INT64)) {
6202
6203                                         if (hfinfo->display & BASE_RANGE_STRING) {
6204                                                 range = (const range_string *)hfinfo->strings;
6205                                         } else if (hfinfo->display & BASE_EXT_STRING) {
6206                                                 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
6207                                         } else if (hfinfo->display & BASE_VAL64_STRING) {
6208                                                 vals64 = (const val64_string *)hfinfo->strings;
6209                                         } else {
6210                                                 vals = (const value_string *)hfinfo->strings;
6211                                         }
6212                                 }
6213                                 else if (hfinfo->type == FT_BOOLEAN) {
6214                                         tfs = (const struct true_false_string *)hfinfo->strings;
6215                                 }
6216                         }
6217
6218                         /* Print value strings? */
6219                         if (vals) {
6220                                 if (hfinfo->display & BASE_EXT_STRING) {
6221                                         const value_string_ext *vse_p = (const value_string_ext *)hfinfo->strings;
6222                                         if (!value_string_ext_validate(vse_p)) {
6223                                                 g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
6224                                                 continue;
6225                                         }
6226                                         try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
6227                                         printf("E\t%s\t%d\t%s\t%s\n",
6228                                                hfinfo->abbrev,
6229                                                VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
6230                                                VALUE_STRING_EXT_VS_NAME(vse_p),
6231                                                value_string_ext_match_type_str(vse_p));
6232                                 }
6233                                 vi = 0;
6234                                 while (vals[vi].strptr) {
6235                                         /* Print in the proper base */
6236                                         if (hfinfo->display == BASE_HEX) {
6237                                                 printf("V\t%s\t0x%x\t%s\n",
6238                                                        hfinfo->abbrev,
6239                                                        vals[vi].value,
6240                                                        vals[vi].strptr);
6241                                         }
6242                                         else {
6243                                                 printf("V\t%s\t%u\t%s\n",
6244                                                        hfinfo->abbrev,
6245                                                        vals[vi].value,
6246                                                        vals[vi].strptr);
6247                                         }
6248                                         vi++;
6249                                 }
6250                         }
6251                         else if (vals64) {
6252                                 vi = 0;
6253                                 while (vals64[vi].strptr) {
6254                                         printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
6255                                                 hfinfo->abbrev,
6256                                                 vals64[vi].value,
6257                                                 vals64[vi].strptr);
6258                                         vi++;
6259                                 }
6260                         }
6261
6262                         /* print range strings? */
6263                         else if (range) {
6264                                 vi = 0;
6265                                 while (range[vi].strptr) {
6266                                         /* Print in the proper base */
6267                                         if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_HEX) {
6268                                                 printf("R\t%s\t0x%x\t0x%x\t%s\n",
6269                                                        hfinfo->abbrev,
6270                                                        range[vi].value_min,
6271                                                        range[vi].value_max,
6272                                                        range[vi].strptr);
6273                                         }
6274                                         else {
6275                                                 printf("R\t%s\t%u\t%u\t%s\n",
6276                                                        hfinfo->abbrev,
6277                                                        range[vi].value_min,
6278                                                        range[vi].value_max,
6279                                                        range[vi].strptr);
6280                                         }
6281                                         vi++;
6282                                 }
6283                         }
6284
6285                         /* Print true/false strings? */
6286                         else if (tfs) {
6287                                 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
6288                                        tfs->true_string, tfs->false_string);
6289                         }
6290                 }
6291         }
6292 }
6293
6294 /* Dumps the contents of the registration database to stdout. An independent
6295  * program can take this output and format it into nice tables or HTML or
6296  * whatever.
6297  *
6298  * There is one record per line. Each record is either a protocol or a header
6299  * field, differentiated by the first field. The fields are tab-delimited.
6300  *
6301  * Protocols
6302  * ---------
6303  * Field 1 = 'P'
6304  * Field 2 = descriptive protocol name
6305  * Field 3 = protocol abbreviation
6306  *
6307  * Header Fields
6308  * -------------
6309  * Field 1 = 'F'
6310  * Field 2 = descriptive field name
6311  * Field 3 = field abbreviation
6312  * Field 4 = type ( textual representation of the the ftenum type )
6313  * Field 5 = parent protocol abbreviation
6314  * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
6315  * Field 7 = bitmask: format: hex: 0x....
6316  * Field 8 = blurb describing field
6317  */
6318 void
6319 proto_registrar_dump_fields(void)
6320 {
6321         header_field_info *hfinfo, *parent_hfinfo;
6322         int                i, len;
6323         const char        *enum_name;
6324         const char        *base_name;
6325         const char        *blurb;
6326         char               width[5];
6327
6328         len = gpa_hfinfo.len;
6329         for (i = 0; i < len ; i++) {
6330                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
6331
6332                 /*
6333                  * Skip the pseudo-field for "proto_tree_add_text()" since
6334                  * we don't want it in the list of filterable fields.
6335                  */
6336                 if (hfinfo->id == hf_text_only)
6337                         continue;
6338
6339                 /* format for protocols */
6340                 if (proto_registrar_is_protocol(i)) {
6341                         printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
6342                 }
6343                 /* format for header fields */
6344                 else {
6345                         /*
6346                          * If this field isn't at the head of the list of
6347                          * fields with this name, skip this field - all
6348                          * fields with the same name are really just versions
6349                          * of the same field stored in different bits, and
6350                          * should have the same type/radix/value list, and
6351                          * just differ in their bit masks.      (If a field isn't
6352                          * a bitfield, but can be, say, 1 or 2 bytes long,
6353                          * it can just be made FT_UINT16, meaning the
6354                          * *maximum* length is 2 bytes, and be used
6355                          * for all lengths.)
6356                          */
6357                         if (hfinfo->same_name_prev_id != -1)
6358                                 continue;
6359
6360                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
6361
6362                         enum_name = ftype_name(hfinfo->type);
6363                         base_name = "";
6364
6365                         if (hfinfo->type == FT_UINT8  ||
6366                             hfinfo->type == FT_UINT16 ||
6367                             hfinfo->type == FT_UINT24 ||
6368                             hfinfo->type == FT_UINT32 ||
6369                             hfinfo->type == FT_UINT64 ||
6370                             hfinfo->type == FT_INT8   ||
6371                             hfinfo->type == FT_INT16  ||
6372                             hfinfo->type == FT_INT24  ||
6373                             hfinfo->type == FT_INT32  ||
6374                             hfinfo->type == FT_INT64) {
6375
6376                                 switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
6377                                         case BASE_NONE:
6378                                                 base_name = "BASE_NONE";
6379                                                 break;
6380                                         case BASE_DEC:
6381                                                 base_name = "BASE_DEC";
6382                                                 break;
6383                                         case BASE_HEX:
6384                                                 base_name = "BASE_HEX";
6385                                                 break;
6386                                         case BASE_OCT:
6387                                                 base_name = "BASE_OCT";
6388                                                 break;
6389                                         case BASE_DEC_HEX:
6390                                                 base_name = "BASE_DEC_HEX";
6391                                                 break;
6392                                         case BASE_HEX_DEC:
6393                                                 base_name = "BASE_HEX_DEC";
6394                                                 break;
6395                                         case BASE_CUSTOM:
6396                                                 base_name = "BASE_CUSTOM";
6397                                                 break;
6398                                         default:
6399                                                 base_name = "????";
6400                                                 break;
6401                                 }
6402                         } else if (hfinfo->type == FT_BOOLEAN) {
6403                                 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
6404                                 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
6405                                 base_name = width;
6406                         }
6407
6408                         blurb = hfinfo->blurb;
6409                         if (blurb == NULL)
6410                                 blurb = "";
6411                         else if (strlen(blurb) == 0)
6412                                 blurb = "\"\"";
6413
6414                         printf("F\t%s\t%s\t%s\t%s\t%s\t0x%x\t%s\n",
6415                                 hfinfo->name, hfinfo->abbrev, enum_name,
6416                                 parent_hfinfo->abbrev, base_name, hfinfo->bitmask, blurb);
6417                 }
6418         }
6419 }
6420
6421 /* Dumps field types and descriptive names to stdout. An independent
6422  * program can take this output and format it into nice tables or HTML or
6423  * whatever.
6424  *
6425  * There is one record per line. The fields are tab-delimited.
6426  *
6427  * Field 1 = field type name, e.g. FT_UINT8
6428  * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
6429  */
6430 void
6431 proto_registrar_dump_ftypes(void)
6432 {
6433         int fte;
6434
6435         for (fte = 0; fte < FT_NUM_TYPES; fte++) {
6436                 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
6437         }
6438 }
6439
6440 static const char *
6441 hfinfo_numeric_format(const header_field_info *hfinfo)
6442 {
6443         const char *format = NULL;
6444
6445                 /* Get the underlying BASE_ value */
6446                 switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
6447                         case BASE_DEC:
6448                         case BASE_DEC_HEX:
6449                         case BASE_OCT: /* I'm lazy */
6450                         case BASE_CUSTOM:
6451                                 switch (hfinfo->type) {
6452                                         case FT_UINT64:
6453                                                 format = "%s == %" G_GINT64_MODIFIER "u";
6454                                                 break;
6455                                         case FT_INT64:
6456                                                 format = "%s == %" G_GINT64_MODIFIER "d";
6457                                                 break;
6458                                         default:
6459                                                 DISSECTOR_ASSERT_NOT_REACHED();
6460                                                 ;
6461                                 }
6462                                 break;
6463                         case BASE_HEX:
6464                         case BASE_HEX_DEC:
6465                                 switch (hfinfo->type) {
6466                                         case FT_UINT64:
6467                                         case FT_INT64:
6468                                                 format = "%s == 0x%016" G_GINT64_MODIFIER "x";
6469                                                 break;
6470                                         default:
6471                                                 DISSECTOR_ASSERT_NOT_REACHED();
6472                                                 ;
6473                                 }
6474                                 break;
6475                         default:
6476                                 DISSECTOR_ASSERT_NOT_REACHED();
6477                                 ;
6478                 }
6479         return format;
6480 }
6481
6482 /* This function indicates whether it's possible to construct a
6483  * "match selected" display filter string for the specified field,
6484  * returns an indication of whether it's possible, and, if it's
6485  * possible and "filter" is non-null, constructs the filter and
6486  * sets "*filter" to point to it.
6487  * You do not need to [g_]free() this string since it will be automatically
6488  * freed once the next packet is dissected.
6489  */
6490 static gboolean
6491 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
6492                                 char **filter)
6493 {
6494         header_field_info *hfinfo;
6495         int                abbrev_len;
6496         char              *ptr;
6497         int                buf_len;
6498         int                dfilter_len, i;
6499         gint               start, length, length_remaining;
6500         guint8             c;
6501         gchar              is_signed_num = FALSE;
6502
6503         if (!finfo)
6504                 return FALSE;
6505
6506         hfinfo     = finfo->hfinfo;
6507         DISSECTOR_ASSERT(hfinfo);
6508         abbrev_len = (int) strlen(hfinfo->abbrev);
6509
6510         if (hfinfo->strings && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
6511                 const gchar *str = NULL;
6512
6513                 switch (hfinfo->type) {
6514
6515                 case FT_INT8:
6516                 case FT_INT16:
6517                 case FT_INT24:
6518                 case FT_INT32:
6519                         str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
6520                         break;
6521
6522                 case FT_UINT8:
6523                 case FT_UINT16:
6524                 case FT_UINT24:
6525                 case FT_UINT32:
6526                         str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
6527                         break;
6528
6529                 default:
6530                         break;
6531                 }
6532
6533                 if (str != NULL && filter != NULL) {
6534                         *filter = ep_strdup_printf("%s == \"%s\"", hfinfo->abbrev, str);
6535                         return TRUE;
6536                 }
6537         }
6538
6539         /*
6540          * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
6541          * functions for FT_UINT and FT_INT types, as we choose the base in
6542          * the string expression based on the display base of the field.
6543          *
6544          * Note that the base does matter, as this is also used for
6545          * the protocolinfo tap.
6546          *
6547          * It might be nice to use them in "proto_item_fill_label()"
6548          * as well, although, there, you'd have to deal with the base
6549          * *and* with resolved values for addresses.
6550          *
6551          * Perhaps we need two different val_to_string routines, one
6552          * to generate items for display filters and one to generate
6553          * strings for display, and pass to both of them the
6554          * "display" and "strings" values in the header_field_info
6555          * structure for the field, so they can get the base and,
6556          * if the field is Boolean or an enumerated integer type,
6557          * the tables used to generate human-readable values.
6558          */
6559         switch (hfinfo->type) {
6560
6561                 case FT_INT8:
6562                 case FT_INT16:
6563                 case FT_INT24:
6564                 case FT_INT32:
6565                         is_signed_num = TRUE;
6566                         /* FALLTHRU */
6567                 case FT_UINT8:
6568                 case FT_UINT16:
6569                 case FT_UINT24:
6570                 case FT_UINT32:
6571                 case FT_FRAMENUM:
6572                         if (filter != NULL) {
6573                                 guint32 number;
6574
6575                                 char buf[32];
6576                                 const char *out;
6577
6578                                 if (is_signed_num)
6579                                         number = fvalue_get_sinteger(&finfo->value);
6580                                 else
6581                                         number = fvalue_get_uinteger(&finfo->value);
6582
6583                                 out = hfinfo_numeric_value_format(hfinfo, buf, number);
6584
6585                                 *filter = ep_strdup_printf("%s == %s", hfinfo->abbrev, out);
6586                         }
6587                         break;
6588
6589                 case FT_INT64:
6590                 case FT_UINT64:
6591                         if (filter != NULL) {
6592                                 const char *format = hfinfo_numeric_format(hfinfo);
6593
6594                                 *filter = ep_strdup_printf(format,
6595                                         hfinfo->abbrev,
6596                                         fvalue_get_integer64(&finfo->value));
6597                         }
6598                         break;
6599
6600                 case FT_PROTOCOL:
6601                         if (filter != NULL)
6602                                 *filter = ep_strdup(finfo->hfinfo->abbrev);
6603                         break;
6604
6605                 case FT_NONE:
6606                         /*
6607                          * If the length is 0, just match the name of the
6608                          * field.
6609                          *
6610                          * (Also check for negative values, just in case,
6611                          * as we'll cast it to an unsigned value later.)
6612                          */
6613                         length = finfo->length;
6614                         if (length == 0) {
6615                                 if (filter != NULL)
6616                                         *filter = ep_strdup(finfo->hfinfo->abbrev);
6617                                 break;
6618                         }
6619                         if (length < 0)
6620                                 return FALSE;
6621
6622                         /*
6623                          * This doesn't have a value, so we'd match
6624                          * on the raw bytes at this address.
6625                          *
6626                          * Should we be allowed to access to the raw bytes?
6627                          * If "edt" is NULL, the answer is "no".
6628                          */
6629                         if (edt == NULL)
6630                                 return FALSE;
6631
6632                         /*
6633                          * Is this field part of the raw frame tvbuff?
6634                          * If not, we can't use "frame[N:M]" to match
6635                          * it.
6636                          *
6637                          * XXX - should this be frame-relative, or
6638                          * protocol-relative?
6639                          *
6640                          * XXX - does this fallback for non-registered
6641                          * fields even make sense?
6642                          */
6643                         if (finfo->ds_tvb != edt->tvb)
6644                                 return FALSE;   /* you lose */
6645
6646                         /*
6647                          * Don't go past the end of that tvbuff.
6648                          */
6649                         length_remaining = tvb_length_remaining(finfo->ds_tvb, finfo->start);
6650                         if (length > length_remaining)
6651                                 length = length_remaining;
6652                         if (length <= 0)
6653                                 return FALSE;
6654
6655                         if (filter != NULL) {
6656                                 start = finfo->start;
6657                                 buf_len = 32 + length * 3;
6658                                 *filter = (char *)ep_alloc0(buf_len);
6659                                 ptr = *filter;
6660
6661                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
6662                                         "frame[%d:%d] == ", finfo->start, length);
6663                                 for (i=0; i<length; i++) {
6664                                         c = tvb_get_guint8(finfo->ds_tvb, start);
6665                                         start++;
6666                                         if (i == 0 ) {
6667                                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
6668                                         }
6669                                         else {
6670                                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
6671                                         }
6672                                 }
6673                         }
6674                         break;
6675
6676                 case FT_PCRE:
6677                         /* FT_PCRE never appears as a type for a registered field. It is
6678                          * only used internally. */
6679                         DISSECTOR_ASSERT_NOT_REACHED();
6680                         break;
6681
6682                 /* By default, use the fvalue's "to_string_repr" method. */
6683                 default:
6684                         /* Figure out the string length needed.
6685                          *      The ft_repr length.
6686                          *      4 bytes for " == ".
6687                          *      1 byte for trailing NUL.
6688                          */
6689                         if (filter != NULL) {
6690                                 dfilter_len = fvalue_string_repr_len(&finfo->value,
6691                                                 FTREPR_DFILTER);
6692                                 dfilter_len += abbrev_len + 4 + 1;
6693                                 *filter = (char *)ep_alloc0(dfilter_len);
6694
6695                                 /* Create the string */
6696                                 g_snprintf(*filter, dfilter_len, "%s == ",
6697                                         hfinfo->abbrev);
6698                                 fvalue_to_string_repr(&finfo->value,
6699                                         FTREPR_DFILTER,
6700                                         &(*filter)[abbrev_len + 4]);
6701                         }
6702                         break;
6703         }
6704
6705         return TRUE;
6706 }
6707
6708 /*
6709  * Returns TRUE if we can do a "match selected" on the field, FALSE
6710  * otherwise.
6711  */
6712 gboolean
6713 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
6714 {
6715         return construct_match_selected_string(finfo, edt, NULL);
6716 }
6717
6718 /* This function attempts to construct a "match selected" display filter
6719  * string for the specified field; if it can do so, it returns a pointer
6720  * to the string, otherwise it returns NULL.
6721  *
6722  * The string is allocated with packet lifetime scope.
6723  * You do not need to [g_]free() this string since it will be automatically
6724  * freed once the next packet is dissected.
6725  */
6726 char *
6727 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
6728 {
6729         char *filter;
6730
6731         if (!construct_match_selected_string(finfo, edt, &filter))
6732                 return NULL;
6733         return filter;
6734 }
6735
6736 /* This function is common code for both proto_tree_add_bitmask() and
6737  *      proto_tree_add_bitmask_text() functions.
6738  */
6739
6740 /* NOTE: to support code written when proto_tree_add_bitmask() and
6741  * proto_tree_add_bitmask_text took a
6742  * gboolean as its last argument, with FALSE meaning "big-endian"
6743  * and TRUE meaning "little-endian", we treat any non-zero value of
6744  * "encoding" as meaning "little-endian".
6745  */
6746 static gboolean
6747 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
6748                             const int len, const gint ett, const int **fields,
6749                             const guint encoding, const int flags,
6750                             gboolean first)
6751 {
6752         guint32            value = 0;
6753         guint32            available_bits = 0;
6754         guint32            tmpval;
6755         proto_tree        *tree  = NULL;
6756         header_field_info *hf;
6757
6758         switch (len) {
6759                 case 1:
6760                         value = tvb_get_guint8(tvb, offset);
6761                         available_bits = 0xFF;
6762                         break;
6763                 case 2:
6764                         value = encoding ? tvb_get_letohs(tvb, offset) :
6765                         tvb_get_ntohs(tvb, offset);
6766                         available_bits = 0xFFFF;
6767                         break;
6768                 case 3:
6769                         value = encoding ? tvb_get_letoh24(tvb, offset) :
6770                         tvb_get_ntoh24(tvb, offset);
6771                         available_bits = 0xFFFFFF;
6772                         break;
6773                 case 4:
6774                         value = encoding ? tvb_get_letohl(tvb, offset) :
6775                         tvb_get_ntohl(tvb, offset);
6776                         available_bits = 0xFFFFFFFF;
6777                         break;
6778                 default:
6779                         g_assert_not_reached();
6780         }
6781
6782         tree = proto_item_add_subtree(item, ett);
6783         while (*fields) {
6784                 guint32 present_bits;
6785                 hf = proto_registrar_get_nth(**fields);
6786                 DISSECTOR_ASSERT(hf->bitmask != 0);
6787
6788                 /* Skip fields that aren't fully present */
6789                 present_bits = available_bits & hf->bitmask;
6790                 if (present_bits != hf->bitmask) {
6791                         fields++;
6792                         continue;
6793                 }
6794
6795                 proto_tree_add_item(tree, **fields, tvb, offset, len, encoding);
6796                 if (flags & BMT_NO_APPEND) {
6797                         fields++;
6798                         continue;
6799                 }
6800                 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
6801
6802                 switch (hf->type) {
6803                 case FT_INT8:
6804                 case FT_UINT8:
6805                 case FT_INT16:
6806                 case FT_UINT16:
6807                 case FT_INT24:
6808                 case FT_UINT24:
6809                 case FT_INT32:
6810                 case FT_UINT32:
6811                         if (hf->display == BASE_CUSTOM) {
6812                                 gchar lbl[ITEM_LABEL_LENGTH];
6813                                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
6814
6815                                 DISSECTOR_ASSERT(fmtfunc);
6816                                 fmtfunc(lbl, tmpval);
6817                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
6818                                                 hf->name, lbl);
6819                                 first = FALSE;
6820                         }
6821                         else if (hf->strings) {
6822                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
6823                                                        hf->name, hf_try_val_to_str_const(tmpval, hf, "Unknown"));
6824                                 first = FALSE;
6825                         }
6826                         else if (!(flags & BMT_NO_INT)) {
6827                                 char buf[32];
6828                                 const char *out;
6829
6830                                 if (!first) {
6831                                         proto_item_append_text(item, ", ");
6832                                 }
6833
6834                                 out = hfinfo_number_value_format(hf, buf, tmpval);
6835                                 proto_item_append_text(item, "%s: %s", hf->name, out);
6836                                 first = FALSE;
6837                         }
6838
6839                         break;
6840                 case FT_BOOLEAN:
6841                         if (hf->strings && !(flags & BMT_NO_TFS)) {
6842                                 /* If we have true/false strings, emit full - otherwise messages
6843                                    might look weird */
6844                                 const struct true_false_string *tfs =
6845                                         (const struct true_false_string *)hf->strings;
6846
6847                                 if (tmpval) {
6848                                         proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
6849                                                         hf->name, tfs->true_string);
6850                                         first = FALSE;
6851                                 } else if (!(flags & BMT_NO_FALSE)) {
6852                                         proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
6853                                                         hf->name, tfs->false_string);
6854                                         first = FALSE;
6855                                 }
6856                         } else if (hf->bitmask & value) {
6857                                 /* If the flag is set, show the name */
6858                                 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
6859                                 first = FALSE;
6860                         }
6861                         break;
6862                 default:
6863                         g_assert_not_reached();
6864                 }
6865
6866                 fields++;
6867         }
6868
6869         return first;
6870 }
6871
6872 /* This function will dissect a sequence of bytes that describe a
6873  * bitmask.
6874  * hf_hdr is a 8/16/24/32 bit integer that describes the bitmask to be dissected.
6875  * This field will form an expansion under which the individual fields of the
6876  * bitmask is dissected and displayed.
6877  * This field must be of the type FT_[U]INT{8|16|24|32}.
6878  *
6879  * fields is an array of pointers to int that lists all the fields of the
6880  * bitmask. These fields can be either of the type FT_BOOLEAN for flags
6881  * or another integer of the same type/size as hf_hdr with a mask specified.
6882  * This array is terminated by a NULL entry.
6883  *
6884  * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
6885  * FT_integer fields that have a value_string attached will have the
6886  * matched string displayed on the expansion line.
6887  */
6888 proto_item *
6889 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
6890                        const guint offset, const int hf_hdr,
6891                        const gint ett, const int **fields,
6892                        const guint encoding)
6893 {
6894         proto_item        *item = NULL;
6895         header_field_info *hf;
6896         int                len;
6897
6898         hf = proto_registrar_get_nth(hf_hdr);
6899         DISSECTOR_ASSERT(IS_FT_INT(hf->type) || IS_FT_UINT(hf->type));
6900         len = ftype_length(hf->type);
6901
6902         if (parent_tree) {
6903                 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
6904                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields, encoding,
6905                                             BMT_NO_INT|BMT_NO_TFS, FALSE);
6906         }
6907
6908         return item;
6909 }
6910
6911 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
6912  * This is intended to support bitmask fields whose lengths can vary, perhaps
6913  * as the underlying standard evolves over time.
6914  * With this API there is the possibility of being called to display more or
6915  * less data than the dissector was coded to support.
6916  * In such cases, it is assumed that bitmasks are extended on the MSb end.
6917  * Thus when presented with "too much" or "too little" data, MSbits will be
6918  * ignored or MSfields sacrificed.
6919  *
6920  * Only fields for which all defined bits are available are displayed.
6921  */
6922 proto_item *
6923 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
6924                        const guint offset,  const guint len, const int hf_hdr,
6925                        const gint ett, const int **fields, struct expert_field* exp,
6926                        const guint encoding)
6927 {
6928         proto_item        *item = NULL;
6929         header_field_info *hf;
6930         guint   decodable_len;
6931         guint   decodable_offset;
6932         guint32 decodable_value;
6933
6934         hf = proto_registrar_get_nth(hf_hdr);
6935         DISSECTOR_ASSERT(IS_FT_INT(hf->type) || IS_FT_UINT(hf->type));
6936
6937         decodable_offset = offset;
6938         decodable_len = MIN(len, (guint) ftype_length(hf->type));
6939
6940         /* If we are ftype_length-limited,
6941          * make sure we decode as many LSBs as possible.
6942          */
6943         if (encoding == ENC_BIG_ENDIAN) {
6944                 decodable_offset += (len - decodable_len);
6945         }
6946
6947         if (parent_tree) {
6948                 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
6949                                                  decodable_len, encoding);
6950
6951                 /* The root item covers all the bytes even if we can't decode them all */
6952                 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
6953                                            decodable_value);
6954         }
6955
6956         if (decodable_len < len) {
6957                 /* Dissector likely requires updating for new protocol revision */
6958                 expert_add_info_format(NULL, item, exp,
6959                                        "Only least-significant %d of %d bytes decoded",
6960                                        decodable_len, len);
6961         }
6962
6963         if (item) {
6964                 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
6965                                             ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, FALSE);
6966         }
6967
6968         return item;
6969 }
6970
6971 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
6972 proto_item *
6973 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
6974                             const guint offset, const guint len,
6975                             const char *name, const char *fallback,
6976                             const gint ett, const int **fields,
6977                             const guint encoding, const int flags)
6978 {
6979         proto_item *item = NULL;
6980
6981         if (parent_tree) {
6982                 item = proto_tree_add_text(parent_tree, tvb, offset, len, "%s", name ? name : "");
6983                 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields, encoding,
6984                                         flags, TRUE) && fallback) {
6985                         /* Still at first item - append 'fallback' text if any */
6986                         proto_item_append_text(item, "%s", fallback);
6987                 }
6988         }
6989
6990         return item;
6991 }
6992
6993 proto_item *
6994 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
6995                          const guint bit_offset, const gint no_of_bits,
6996                          const guint encoding)
6997 {
6998         header_field_info *hfinfo;
6999         gint              octet_length;
7000         gint              octet_offset;
7001
7002         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
7003
7004         octet_length = (no_of_bits + 7) >> 3;
7005         octet_offset = bit_offset >> 3;
7006         test_length(hfinfo, tree, tvb, octet_offset, octet_length, encoding);
7007
7008         /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
7009          * but only after doing a bunch more work (which we can, in the common
7010          * case, shortcut here).
7011          */
7012         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
7013
7014         return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
7015 }
7016
7017 /*
7018  * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
7019  * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
7020  * Offset should be given in bits from the start of the tvb.
7021  */
7022
7023 static proto_item *
7024 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
7025                             const guint bit_offset, const gint no_of_bits,
7026                             guint64 *return_value, const guint encoding)
7027 {
7028         gint     offset;
7029         guint    length;
7030         guint8   tot_no_bits;
7031         char    *bf_str;
7032         char     lbl_str[ITEM_LABEL_LENGTH];
7033         guint64  value = 0;
7034
7035         proto_item        *pi;
7036         header_field_info *hf_field;
7037
7038         const true_false_string *tfstring;
7039
7040         /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
7041         PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
7042
7043         if (hf_field->bitmask != 0) {
7044                 REPORT_DISSECTOR_BUG(ep_strdup_printf("Incompatible use of proto_tree_add_bits_ret_val"
7045                                                       " with field '%s' (%s) with bitmask != 0",
7046                                                       hf_field->abbrev, hf_field->name));
7047         }
7048
7049         DISSECTOR_ASSERT(no_of_bits >  0);
7050
7051         /* Byte align offset */
7052         offset = bit_offset>>3;
7053
7054         /*
7055          * Calculate the number of octets used to hold the bits
7056          */
7057         tot_no_bits = ((bit_offset&0x7) + no_of_bits);
7058         length = (tot_no_bits + 7) >> 3;
7059
7060         if (no_of_bits < 65) {
7061                 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
7062         } else {
7063                 DISSECTOR_ASSERT_NOT_REACHED();
7064                 return NULL;
7065         }
7066
7067         /* Sign extend for signed types */
7068         switch (hf_field->type) {
7069                 case FT_INT8:
7070                 case FT_INT16:
7071                 case FT_INT24:
7072                 case FT_INT32:
7073                 case FT_INT64:
7074                         if (value & (G_GINT64_CONSTANT(1) << (no_of_bits-1)))
7075                                 value |= (G_GINT64_CONSTANT(-1) << no_of_bits);
7076                         break;
7077
7078                 default:
7079                         break;
7080         }
7081
7082         if (return_value) {
7083                 *return_value = value;
7084         }
7085
7086         /* Coast clear. Try and fake it */
7087         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7088
7089         bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
7090
7091         switch (hf_field->type) {
7092         case FT_BOOLEAN:
7093                 /* Boolean field */
7094                 tfstring = (const true_false_string *) &tfs_true_false;
7095                 if (hf_field->strings)
7096                         tfstring = (const true_false_string *)hf_field->strings;
7097                 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
7098                         "%s = %s: %s",
7099                         bf_str, hf_field->name,
7100                         (guint32)value ? tfstring->true_string : tfstring->false_string);
7101                 break;
7102
7103         case FT_UINT8:
7104         case FT_UINT16:
7105         case FT_UINT24:
7106         case FT_UINT32:
7107                 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
7108                 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
7109                 break;
7110
7111         case FT_INT8:
7112         case FT_INT16:
7113         case FT_INT24:
7114         case FT_INT32:
7115                 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
7116                 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
7117                 break;
7118
7119         case FT_UINT64:
7120                 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
7121                 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
7122                 break;
7123
7124         case FT_INT64:
7125                 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
7126                 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
7127                 break;
7128
7129         default:
7130                 DISSECTOR_ASSERT_NOT_REACHED();
7131                 return NULL;
7132                 break;
7133         }
7134
7135         proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
7136         return pi;
7137 }
7138
7139 proto_item *
7140 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
7141                                        const guint bit_offset, const crumb_spec_t *crumb_spec,
7142                                        guint64 *return_value)
7143 {
7144         proto_item *pi;
7145         gint        no_of_bits;
7146         gint        octet_offset;
7147         guint       mask_initial_bit_offset;
7148         guint       mask_greatest_bit_offset;
7149         guint       octet_length;
7150         guint8      i;
7151         char       *bf_str;
7152         char        lbl_str[ITEM_LABEL_LENGTH];
7153         guint64     value;
7154         guint64     composite_bitmask;
7155         guint64     composite_bitmap;
7156
7157         header_field_info       *hf_field;
7158         const true_false_string *tfstring;
7159
7160         /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
7161         PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
7162
7163         if (hf_field->bitmask != 0) {
7164                 REPORT_DISSECTOR_BUG(ep_strdup_printf(
7165                                              "Incompatible use of proto_tree_add_split_bits_item_ret_val"
7166                                              " with field '%s' (%s) with bitmask != 0",
7167                                              hf_field->abbrev, hf_field->name));
7168         }
7169
7170         mask_initial_bit_offset = bit_offset % 8;
7171
7172         no_of_bits = 0;
7173         value      = 0;
7174         i          = 0;
7175         mask_greatest_bit_offset = 0;
7176         composite_bitmask        = 0;
7177         composite_bitmap         = 0;
7178
7179         while (crumb_spec[i].crumb_bit_length != 0) {
7180                 guint64 crumb_mask, crumb_value;
7181                 guint8  crumb_end_bit_offset;
7182
7183                 DISSECTOR_ASSERT(i < 64);
7184                 crumb_value = tvb_get_bits64(tvb,
7185                                              bit_offset + crumb_spec[i].crumb_bit_offset,
7186                                              crumb_spec[i].crumb_bit_length,
7187                                              ENC_BIG_ENDIAN);
7188                 value      += crumb_value;
7189                 no_of_bits += crumb_spec[i].crumb_bit_length;
7190
7191                 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
7192                    octet containing the initial offset.
7193                    If the mask is beyond 32 bits, then give up on bit map display.
7194                    This could be improved in future, probably showing a table
7195                    of 32 or 64 bits per row */
7196                 if (mask_greatest_bit_offset < 32) {
7197                         crumb_end_bit_offset = mask_initial_bit_offset
7198                                 + crumb_spec[i].crumb_bit_offset
7199                                 + crumb_spec[i].crumb_bit_length;
7200                         crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
7201
7202                         if (crumb_end_bit_offset > mask_greatest_bit_offset) {
7203                                 mask_greatest_bit_offset = crumb_end_bit_offset;
7204                         }
7205                         composite_bitmask |= (crumb_mask  << (64 - crumb_end_bit_offset));
7206                         composite_bitmap  |= (crumb_value << (64 - crumb_end_bit_offset));
7207                 }
7208                 /* Shift left for the next segment */
7209                 value <<= crumb_spec[++i].crumb_bit_length;
7210         }
7211
7212         /* Sign extend for signed types */
7213         switch (hf_field->type) {
7214                 case FT_INT8:
7215                 case FT_INT16:
7216                 case FT_INT24:
7217                 case FT_INT32:
7218                 case FT_INT64:
7219                         if (no_of_bits && (value & (G_GINT64_CONSTANT(1) << (no_of_bits-1))))
7220                                 value |= (G_GINT64_CONSTANT(-1) << no_of_bits);
7221                         break;
7222                 default:
7223                         break;
7224         }
7225
7226         if (return_value) {
7227                 *return_value = value;
7228         }
7229
7230         /* Coast clear. Try and fake it */
7231         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7232
7233         /* initialise the format string */
7234         bf_str    = (char *)ep_alloc(256);
7235         bf_str[0] = '\0';
7236
7237         octet_offset = bit_offset >> 3;
7238
7239         /* Round up mask length to nearest octet */
7240         octet_length = ((mask_greatest_bit_offset + 7) >> 3);
7241         mask_greatest_bit_offset = octet_length << 3;
7242
7243         /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
7244            It would be a useful enhancement to eliminate this restriction. */
7245         if (mask_greatest_bit_offset <= 32) {
7246                 other_decode_bitfield_value(bf_str,
7247                                             (guint32)(composite_bitmap  >> (64 - mask_greatest_bit_offset)),
7248                                             (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
7249                                             mask_greatest_bit_offset);
7250         }
7251
7252         switch (hf_field->type) {
7253         case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
7254                 /* Boolean field */
7255                 tfstring = (const true_false_string *) &tfs_true_false;
7256                 if (hf_field->strings)
7257                         tfstring = (const true_false_string *) hf_field->strings;
7258                 return proto_tree_add_boolean_format(tree, hfindex,
7259                                                      tvb, octet_offset, octet_length, (guint32)value,
7260                                                      "%s = %s: %s",
7261                                                      bf_str, hf_field->name,
7262                                                      (guint32)value ? tfstring->true_string : tfstring->false_string);
7263                 break;
7264
7265         case FT_UINT8:
7266         case FT_UINT16:
7267         case FT_UINT24:
7268         case FT_UINT32:
7269                 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
7270                 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
7271                 break;
7272
7273         case FT_INT8:
7274         case FT_INT16:
7275         case FT_INT24:
7276         case FT_INT32:
7277                 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
7278                 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
7279                 break;
7280
7281         case FT_UINT64:
7282                 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
7283                 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
7284                 break;
7285
7286         case FT_INT64:
7287                 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
7288                 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
7289                 break;
7290
7291         default:
7292                 DISSECTOR_ASSERT_NOT_REACHED();
7293                 return NULL;
7294                 break;
7295         }
7296         proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
7297         return pi;
7298 }
7299
7300 void
7301 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
7302                                 const crumb_spec_t *crumb_spec, guint16 crumb_index)
7303 {
7304         header_field_info *hfinfo;
7305
7306         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
7307         proto_tree_add_text(tree, tvb,
7308                             bit_offset >> 3,
7309                             ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
7310                             "%s crumb %d of %s (decoded above)",
7311                             decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
7312                                                  tvb_get_bits(tvb,
7313                                                               bit_offset,
7314                                                               crumb_spec[crumb_index].crumb_bit_length,
7315                                                               ENC_BIG_ENDIAN)),
7316                             crumb_index,
7317                             hfinfo->name);
7318 }
7319
7320 proto_item *
7321 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
7322                             const guint bit_offset, const gint no_of_bits,
7323                             guint64 *return_value, const guint encoding)
7324 {
7325         proto_item *item;
7326
7327         if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
7328                                                  bit_offset, no_of_bits,
7329                                                  return_value, encoding))) {
7330                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
7331                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
7332         }
7333         return item;
7334 }
7335
7336 static proto_item *
7337 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
7338                                  tvbuff_t *tvb, const guint bit_offset,
7339                                  const gint no_of_bits, void *value_ptr,
7340                                  gchar *value_str)
7341 {
7342         gint     offset;
7343         guint    length;
7344         guint8   tot_no_bits;
7345         char    *str;
7346         guint64  value = 0;
7347         header_field_info *hf_field;
7348
7349         /* We do not have to return a value, try to fake it as soon as possible */
7350         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7351
7352         if (hf_field->bitmask != 0) {
7353                 REPORT_DISSECTOR_BUG(ep_strdup_printf(
7354                                              "Incompatible use of proto_tree_add_bits_format_value"
7355                                              " with field '%s' (%s) with bitmask != 0",
7356                                              hf_field->abbrev, hf_field->name));
7357         }
7358
7359         DISSECTOR_ASSERT(no_of_bits > 0);
7360
7361         /* Byte align offset */
7362         offset = bit_offset>>3;
7363
7364         /*
7365          * Calculate the number of octets used to hold the bits
7366          */
7367         tot_no_bits = ((bit_offset&0x7) + no_of_bits);
7368         length      = tot_no_bits>>3;
7369         /* If we are using part of the next octet, increase length by 1 */
7370         if (tot_no_bits & 0x07)
7371                 length++;
7372
7373         if (no_of_bits < 65) {
7374                 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
7375         } else {
7376                 DISSECTOR_ASSERT_NOT_REACHED();
7377                 return NULL;
7378         }
7379
7380         str = decode_bits_in_field(bit_offset, no_of_bits, value);
7381
7382         strcat(str, " = ");
7383         strcat(str, hf_field->name);
7384
7385         /*
7386          * This function does not receive an actual value but a dimensionless pointer to that value.
7387          * For this reason, the type of the header field is examined in order to determine
7388          * what kind of value we should read from this address.
7389          * The caller of this function must make sure that for the specific header field type the address of
7390          * a compatible value is provided.
7391          */
7392         switch (hf_field->type) {
7393         case FT_BOOLEAN:
7394                 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
7395                                                      "%s: %s", str, value_str);
7396                 break;
7397
7398         case FT_UINT8:
7399         case FT_UINT16:
7400         case FT_UINT24:
7401         case FT_UINT32:
7402                 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
7403                                                   "%s: %s", str, value_str);
7404                 break;
7405
7406         case FT_UINT64:
7407                 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
7408                                                     "%s: %s", str, value_str);
7409                 break;
7410
7411         case FT_INT8:
7412         case FT_INT16:
7413         case FT_INT24:
7414         case FT_INT32:
7415                 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
7416                                                  "%s: %s", str, value_str);
7417                 break;
7418
7419         case FT_INT64:
7420                 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
7421                                                    "%s: %s", str, value_str);
7422                 break;
7423
7424         case FT_FLOAT:
7425                 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
7426                                                    "%s: %s", str, value_str);
7427                 break;
7428
7429         default:
7430                 DISSECTOR_ASSERT_NOT_REACHED();
7431                 return NULL;
7432                 break;
7433         }
7434 }
7435
7436 static proto_item *
7437 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
7438                                  tvbuff_t *tvb, const guint bit_offset,
7439                                  const gint no_of_bits, void *value_ptr,
7440                                  gchar *value_str)
7441 {
7442         proto_item *item;
7443
7444         if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
7445                                                       tvb, bit_offset, no_of_bits,
7446                                                       value_ptr, value_str))) {
7447                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
7448                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
7449         }
7450         return item;
7451 }
7452
7453 #define CREATE_VALUE_STRING(dst,format,ap) \
7454         va_start(ap, format); \
7455         dst = ep_strdup_vprintf(format, ap); \
7456         va_end(ap);
7457
7458 proto_item *
7459 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
7460                                       tvbuff_t *tvb, const guint bit_offset,
7461                                       const gint no_of_bits, guint32 value,
7462                                       const char *format, ...)
7463 {
7464         va_list ap;
7465         gchar  *dst;
7466         header_field_info *hf_field;
7467
7468         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7469
7470         switch (hf_field->type) {
7471                 case FT_UINT8:
7472                 case FT_UINT16:
7473                 case FT_UINT24:
7474                 case FT_UINT32:
7475                         break;
7476
7477                 default:
7478                         DISSECTOR_ASSERT_NOT_REACHED();
7479                         return NULL;
7480                         break;
7481         }
7482
7483         CREATE_VALUE_STRING(dst, format, ap);
7484
7485         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
7486 }
7487
7488 proto_item *
7489 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
7490                                        tvbuff_t *tvb, const guint bit_offset,
7491                                        const gint no_of_bits, float value,
7492                                        const char *format, ...)
7493 {
7494         va_list ap;
7495         gchar  *dst;
7496         header_field_info *hf_field;
7497
7498         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7499
7500         DISSECTOR_ASSERT(hf_field->type == FT_FLOAT);
7501
7502         CREATE_VALUE_STRING(dst, format, ap);
7503
7504         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
7505 }
7506
7507 proto_item *
7508 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
7509                                      tvbuff_t *tvb, const guint bit_offset,
7510                                      const gint no_of_bits, gint32 value,
7511                                      const char *format, ...)
7512 {
7513         va_list ap;
7514         gchar  *dst;
7515         header_field_info *hf_field;
7516
7517         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7518
7519         switch (hf_field->type) {
7520                 case FT_INT8:
7521                 case FT_INT16:
7522                 case FT_INT24:
7523                 case FT_INT32:
7524                         break;
7525
7526                 default:
7527                         DISSECTOR_ASSERT_NOT_REACHED();
7528                         return NULL;
7529                         break;
7530         }
7531
7532         CREATE_VALUE_STRING(dst, format, ap);
7533
7534         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
7535 }
7536
7537 proto_item *
7538 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
7539                                          tvbuff_t *tvb, const guint bit_offset,
7540                                          const gint no_of_bits, guint32 value,
7541                                          const char *format, ...)
7542 {
7543         va_list ap;
7544         gchar  *dst;
7545         header_field_info *hf_field;
7546
7547         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7548
7549         DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
7550
7551         CREATE_VALUE_STRING(dst, format, ap);
7552
7553         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
7554 }
7555
7556 guchar
7557 proto_check_field_name(const gchar *field_name)
7558 {
7559         return wrs_check_charset(fld_abbrev_chars, field_name);
7560 }
7561
7562 gboolean
7563 tree_expanded(int tree_type)
7564 {
7565         g_assert(tree_type >= 0 && tree_type < num_tree_types);
7566         return tree_is_expanded[tree_type >> 5] & (1 << (tree_type & 31));
7567 }
7568
7569 void
7570 tree_expanded_set(int tree_type, gboolean value)
7571 {
7572         g_assert(tree_type >= 0 && tree_type < num_tree_types);
7573
7574         if (value)
7575                 tree_is_expanded[tree_type >> 5] |= (1 << (tree_type & 31));
7576         else
7577                 tree_is_expanded[tree_type >> 5] &= ~(1 << (tree_type & 31));
7578 }
7579
7580 /*
7581  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
7582  *
7583  * Local variables:
7584  * c-basic-offset: 8
7585  * tab-width: 8
7586  * indent-tabs-mode: t
7587  * End:
7588  *
7589  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
7590  * :indentSize=8:tabSize=8:noTabs=false:
7591  */