From Jiri Engelthaler via
[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 "charsets.h"
45 #include "asm_utils.h"
46 #include "column-utils.h"
47 #include "to_str.h"
48 #include "expert.h"
49 #include "show_exception.h"
50
51 #include "wspython/wspy_register.h"
52
53 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
54 #define SUBTREE_MAX_LEVELS 256
55 /* Throw an exception if we exceed this many tree items. */
56 /* XXX - This should probably be a preference */
57 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
58
59
60 typedef struct __subtree_lvl {
61         gint        cursor_offset;
62         proto_item *it;
63         proto_tree *tree;
64 } subtree_lvl;
65
66 struct ptvcursor {
67         subtree_lvl *pushed_tree;
68         guint8       pushed_tree_index;
69         guint8       pushed_tree_max;
70         proto_tree  *tree;
71         tvbuff_t    *tvb;
72         gint         offset;
73 };
74
75 #define cVALS(x) (const value_string*)(x)
76
77 /** See inlined comments.
78  @param tree the tree to append this item to
79  @param hfindex field index
80  @param hfinfo header_field
81  @return the header field matching 'hfinfo' */
82 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
83         /* If this item is not referenced we dont have to do much work  \
84            at all but we should still return a node so that field items \
85            below this node (think proto_item_add_subtree()) will still  \
86            have somewhere to attach to or else filtering will not work  \
87            (they would be ignored since tree would be NULL).            \
88            DONT try to fake a node where PTREE_FINFO(tree) is NULL      \
89            since dissectors that want to do proto_item_set_len() or     \
90            other operations that dereference this would crash.          \
91            We fake FT_PROTOCOL unless some clients have requested us    \
92            not to do so. \
93         */                                                              \
94         if (!tree)                                                      \
95                 return NULL;                                            \
96         PTREE_DATA(tree)->count++;                                      \
97         if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) {                 \
98                 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
99                         g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
100                 /* Let the exception handler add items to the tree */   \
101                 PTREE_DATA(tree)->count = 0;                            \
102                 THROW_MESSAGE(DissectorError,                           \
103                         ep_strdup_printf("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
104         }                                                               \
105         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);                       \
106         if (!(PTREE_DATA(tree)->visible)) {                             \
107                 if (PTREE_FINFO(tree)) {                                \
108                         if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT)    \
109                             && (hfinfo->type != FT_PROTOCOL ||          \
110                                 PTREE_DATA(tree)->fake_protocols)) {    \
111                                 /* just return tree back to the caller */\
112                                 return tree;                            \
113                         }                                               \
114                 }                                                       \
115         }
116
117 /** See inlined comments.
118  @param pi the created protocol item we're about to return */
119 #define TRY_TO_FAKE_THIS_REPR(pi) \
120         g_assert(pi);                   \
121         if (!(PTREE_DATA(pi)->visible)) { \
122                 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
123                  * items string representation */ \
124                 return pi; \
125         }
126
127 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
128
129 static void fill_label_boolean(field_info *fi, gchar *label_str);
130 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
131 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
132 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
133
134 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
135 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
136 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
137 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
138
139 static const char* hfinfo_uint64_format(const header_field_info *hfinfo);
140 static const char* hfinfo_int64_format(const header_field_info *hfinfo);
141
142 static proto_item *
143 proto_tree_add_node(proto_tree *tree, field_info *fi);
144
145 static void
146 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
147                 gint *item_length);
148
149 static field_info *
150 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
151                const gint start, const gint item_length);
152
153 static field_info *
154 alloc_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
155                  const gint start, gint *length);
156
157 static proto_item *
158 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
159                   gint start, gint *length);
160
161 static void
162 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
163 static void
164 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
165
166 static void
167 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb);
168 static void
169 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
170 static void
171 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
172 static void
173 proto_tree_set_time(field_info *fi, nstime_t *value_ptr);
174 static void
175 proto_tree_set_string(field_info *fi, const char* value);
176 static void
177 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding);
178 static void
179 proto_tree_set_ax25(field_info *fi, const guint8* value);
180 static void
181 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
182 static void
183 proto_tree_set_vines(field_info *fi, const guint8* value);
184 static void
185 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
186 static void
187 proto_tree_set_ether(field_info *fi, const guint8* value);
188 static void
189 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
190 static void
191 proto_tree_set_ipxnet(field_info *fi, guint32 value);
192 static void
193 proto_tree_set_ipv4(field_info *fi, guint32 value);
194 static void
195 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
196 static void
197 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
198 static void
199 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
200 static void
201 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
202 static void
203 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
204 static void
205 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
206 static void
207 proto_tree_set_boolean(field_info *fi, guint32 value);
208 static void
209 proto_tree_set_float(field_info *fi, float value);
210 static void
211 proto_tree_set_double(field_info *fi, double value);
212 static void
213 proto_tree_set_uint(field_info *fi, guint32 value);
214 static void
215 proto_tree_set_int(field_info *fi, gint32 value);
216 static void
217 proto_tree_set_uint64(field_info *fi, guint64 value);
218 static void
219 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, guint length, const guint encoding);
220 static void
221 proto_tree_set_eui64(field_info *fi, const guint64 value);
222 static void
223 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
224 static gboolean
225 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
226                             const int len, const gint ett, const gint **fields,
227                             const guint encoding, const int flags,
228                             gboolean first);
229
230 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
231
232 /* special-case header field used within proto.c */
233 static header_field_info hfi_text_only =
234         { "Text item",  "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
235 int hf_text_only = -1;
236
237 /* Structure for information about a protocol */
238 struct _protocol {
239         const char *name;         /* long description */
240         const char *short_name;   /* short description */
241         const char *filter_name;  /* name of this protocol in filters */
242         int         proto_id;     /* field ID for this protocol */
243         GSList     *fields;       /* fields for this protocol */
244         GSList     *last_field;   /* pointer to end of list of fields */
245         gboolean    is_enabled;   /* TRUE if protocol is enabled */
246         gboolean    can_toggle;   /* TRUE if is_enabled can be changed */
247         gboolean    is_private;   /* TRUE is protocol is private */
248 };
249
250 /* List of all protocols */
251 static GList *protocols = NULL;
252
253 #define INITIAL_NUM_PROTOCOL_HFINFO     1500
254
255 /* Contains information about a field when a dissector calls
256  * proto_tree_add_item.  */
257 #define FIELD_INFO_NEW(fi)  fi = g_slice_new(field_info)
258 #define FIELD_INFO_FREE(fi) g_slice_free(field_info, fi)
259
260 /* Contains the space for proto_nodes. */
261 #define PROTO_NODE_NEW(node)                            \
262         node = g_slice_new(proto_node);                 \
263         node->first_child = NULL;                       \
264         node->last_child = NULL;                        \
265         node->next = NULL;
266
267 #define PROTO_NODE_FREE(node)                           \
268         g_slice_free(proto_node, node)
269
270 /* String space for protocol and field items for the GUI */
271 #define ITEM_LABEL_NEW(il)                              \
272         il = g_slice_new(item_label_t);
273 #define ITEM_LABEL_FREE(il)                             \
274         g_slice_free(item_label_t, il);
275
276 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)                                                \
277         if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG"))      \
278                 g_error("Unregistered hf! index=%d", hfindex);                                  \
279         DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!");     \
280         hfinfo = gpa_hfinfo.hfi[hfindex];
281
282 /* List which stores protocols and fields that have been registered */
283 typedef struct _gpa_hfinfo_t {
284         guint32             len;
285         guint32             allocated_len;
286         header_field_info **hfi;
287 } gpa_hfinfo_t;
288
289 static gpa_hfinfo_t gpa_hfinfo;
290
291 /* Balanced tree of abbreviations and IDs */
292 static GTree *gpa_name_tree = NULL;
293 static header_field_info *same_name_hfinfo;
294
295 static void save_same_name_hfinfo(gpointer data)
296 {
297         same_name_hfinfo = (header_field_info*)data;
298 }
299
300 /* Points to the first element of an array of bits, indexed by
301    a subtree item type; that array element is TRUE if subtrees of
302    an item of that type are to be expanded. */
303 static guint32 *tree_is_expanded;
304
305 /* Number of elements in that array. */
306 int             num_tree_types;
307
308 /* Name hashtables for fast detection of duplicate names */
309 static GHashTable* proto_names        = NULL;
310 static GHashTable* proto_short_names  = NULL;
311 static GHashTable* proto_filter_names = NULL;
312
313 static gint
314 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
315 {
316         const protocol_t *p1 = (const protocol_t *)p1_arg;
317         const protocol_t *p2 = (const protocol_t *)p2_arg;
318
319         return g_ascii_strcasecmp(p1->short_name, p2->short_name);
320 }
321
322
323 /* initialize data structures and register protocols and fields */
324 void
325 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
326            void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
327            register_cb cb,
328            gpointer client_data)
329 {
330         proto_cleanup();
331
332         proto_names        = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
333         proto_short_names  = g_hash_table_new(wrs_str_hash, g_str_equal);
334         proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
335
336         gpa_hfinfo.len           = 0;
337         gpa_hfinfo.allocated_len = 0;
338         gpa_hfinfo.hfi           = NULL;
339         gpa_name_tree            = g_tree_new_full(wrs_strcmp_with_data, NULL, NULL, save_same_name_hfinfo);
340
341         /* Initialize the ftype subsystem */
342         ftypes_initialize();
343
344         /* Register one special-case FT_TEXT_ONLY field for use when
345            converting wireshark to new-style proto_tree. These fields
346            are merely strings on the GUI tree; they are not filterable */
347         hf_text_only = proto_register_field_init(&hfi_text_only, -1);
348
349         /* Register the pseudo-protocols used for exceptions. */
350         register_show_exception();
351
352         /* Have each built-in dissector register its protocols, fields,
353            dissector tables, and dissectors to be called through a
354            handle, and do whatever one-time initialization it needs to
355            do. */
356         register_all_protocols_func(cb, client_data);
357 #ifdef HAVE_PYTHON
358         /* Now scan for python protocols */
359         if (cb)
360                 (*cb)(RA_PYTHON_REGISTER, NULL, client_data);
361         register_all_py_protocols_func();
362 #endif
363
364 #ifdef HAVE_PLUGINS
365         /* Now scan for plugins and load all the ones we find, calling
366            their register routines to do the stuff described above. */
367         if (cb)
368                 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
369         init_plugins();
370         register_all_plugin_registrations();
371 #endif
372
373         /* Now call the "handoff registration" routines of all built-in
374            dissectors; those routines register the dissector in other
375            dissectors' handoff tables, and fetch any dissector handles
376            they need. */
377         register_all_handoffs_func(cb, client_data);
378
379 #ifdef HAVE_PYTHON
380         /* Now do the same with python dissectors */
381         if (cb)
382                 (*cb)(RA_PYTHON_HANDOFF, NULL, client_data);
383         register_all_py_handoffs_func();
384 #endif
385
386 #ifdef HAVE_PLUGINS
387         /* Now do the same with plugins. */
388         if (cb)
389                 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
390         register_all_plugin_handoffs();
391 #endif
392
393         /* sort the protocols by protocol name */
394         protocols = g_list_sort(protocols, proto_compare_name);
395
396         /* We've assigned all the subtree type values; allocate the array
397            for them, and zero it out. */
398         tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
399 }
400
401 void
402 proto_cleanup(void)
403 {
404         /* Free the abbrev/ID GTree */
405         if (gpa_name_tree) {
406                 g_tree_destroy(gpa_name_tree);
407                 gpa_name_tree = NULL;
408         }
409
410         while (protocols) {
411                 protocol_t        *protocol = (protocol_t *)protocols->data;
412                 header_field_info *hfinfo;
413                 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
414                 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
415
416                 g_slice_free(header_field_info, hfinfo);
417                 g_slist_free(protocol->fields);
418                 protocols = g_list_remove(protocols, protocol);
419                 g_free(protocol);
420         }
421
422         if (proto_names) {
423                 g_hash_table_destroy(proto_names);
424                 proto_names = NULL;
425         }
426
427         if (proto_short_names) {
428                 g_hash_table_destroy(proto_short_names);
429                 proto_short_names = NULL;
430         }
431
432         if (proto_filter_names) {
433                 g_hash_table_destroy(proto_filter_names);
434                 proto_filter_names = NULL;
435         }
436
437         if (gpa_hfinfo.allocated_len) {
438                 gpa_hfinfo.len           = 0;
439                 gpa_hfinfo.allocated_len = 0;
440                 g_free(gpa_hfinfo.hfi);
441                 gpa_hfinfo.hfi           = NULL;
442         }
443         g_free(tree_is_expanded);
444         tree_is_expanded = NULL;
445 }
446
447 static gboolean
448 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
449                               gpointer data)
450 {
451         proto_node *pnode = tree;
452         proto_node *child;
453         proto_node *current;
454
455         if (func(pnode, data))
456                 return TRUE;
457
458         child = pnode->first_child;
459         while (child != NULL) {
460                 /*
461                  * The routine we call might modify the child, e.g. by
462                  * freeing it, so we get the child's successor before
463                  * calling that routine.
464                  */
465                 current = child;
466                 child   = current->next;
467                 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
468                         return TRUE;
469         }
470
471         return FALSE;
472 }
473
474 gboolean
475 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
476                                gpointer data)
477 {
478         proto_node *pnode = tree;
479         proto_node *child;
480         proto_node *current;
481
482         child = pnode->first_child;
483         while (child != NULL) {
484                 /*
485                  * The routine we call might modify the child, e.g. by
486                  * freeing it, so we get the child's successor before
487                  * calling that routine.
488                  */
489                 current = child;
490                 child   = current->next;
491                 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
492                         return TRUE;
493         }
494         if (func(pnode, data))
495                 return TRUE;
496
497         return FALSE;
498 }
499
500 void
501 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
502                             gpointer data)
503 {
504         proto_node *node = tree;
505         proto_node *current;
506
507         if (!node)
508                 return;
509
510         node = node->first_child;
511         while (node != NULL) {
512                 current = node;
513                 node    = current->next;
514                 func((proto_tree *)current, data);
515         }
516 }
517
518 static void
519 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
520 {
521         GPtrArray         *ptrs = (GPtrArray *)value;
522         gint               hfid = (gint)(long)key;
523         header_field_info *hfinfo;
524
525         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
526         if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
527                 /* when a field is referenced by a filter this also
528                    affects the refcount for the parent protocol so we need
529                    to adjust the refcount for the parent as well
530                 */
531                 if (hfinfo->parent != -1) {
532                         header_field_info *parent_hfinfo;
533                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
534                         parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
535                 }
536                 hfinfo->ref_type = HF_REF_TYPE_NONE;
537         }
538
539         g_ptr_array_free(ptrs, TRUE);
540 }
541
542 static void
543 free_node_tree_data(tree_data_t *tree_data)
544 {
545         if (tree_data->interesting_hfids) {
546                 /* Free all the GPtrArray's in the interesting_hfids hash. */
547                 g_hash_table_foreach(tree_data->interesting_hfids,
548                         free_GPtrArray_value, NULL);
549
550                 /* And then destroy the hash. */
551                 g_hash_table_destroy(tree_data->interesting_hfids);
552         }
553         if (tree_data->fi_tmp)
554                 FIELD_INFO_FREE(tree_data->fi_tmp);
555
556         /* And finally the tree_data_t itself. */
557         g_free(tree_data);
558 }
559
560 #define FREE_NODE_FIELD_INFO(finfo)     \
561         if (finfo->rep) {                       \
562                 ITEM_LABEL_FREE(finfo->rep);    \
563         }                               \
564         FVALUE_CLEANUP(&finfo->value);  \
565         FIELD_INFO_FREE(finfo);
566
567 static void
568 proto_tree_free_node(proto_node *node, gpointer data _U_)
569 {
570         field_info *finfo  = PNODE_FINFO(node);
571
572         proto_tree_children_foreach(node, proto_tree_free_node, NULL);
573
574         /* free the field_info data. */
575         FREE_NODE_FIELD_INFO(finfo);
576         node->finfo = NULL;
577
578         /* Free the proto_node. */
579         PROTO_NODE_FREE(node);
580 }
581
582 /* frees the resources that the dissection a proto_tree uses */
583 void
584 proto_tree_free(proto_tree *tree)
585 {
586         tree_data_t *tree_data = PTREE_DATA(tree);
587
588         proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
589
590         /* free root node */
591         PROTO_NODE_FREE(tree);
592
593         /* free tree data */
594         free_node_tree_data(tree_data);
595 }
596
597 /* Is the parsing being done for a visible proto_tree or an invisible one?
598  * By setting this correctly, the proto_tree creation is sped up by not
599  * having to call g_vsnprintf and copy strings around.
600  */
601 gboolean
602 proto_tree_set_visible(proto_tree *tree, gboolean visible)
603 {
604         gboolean old_visible = PTREE_DATA(tree)->visible;
605
606         PTREE_DATA(tree)->visible = visible;
607
608         return old_visible;
609 }
610
611 void
612 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
613 {
614         PTREE_DATA(tree)->fake_protocols = fake_protocols;
615 }
616
617 /* Assume dissector set only its protocol fields.
618    This function is called by dissectors and allows the speeding up of filtering
619    in wireshark; if this function returns FALSE it is safe to reset tree to NULL
620    and thus skip calling most of the expensive proto_tree_add_...()
621    functions.
622    If the tree is visible we implicitly assume the field is referenced.
623 */
624 gboolean
625 proto_field_is_referenced(proto_tree *tree, int proto_id)
626 {
627         register header_field_info *hfinfo;
628
629
630         if (!tree)
631                 return FALSE;
632
633         if (PTREE_DATA(tree)->visible)
634                 return TRUE;
635
636         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
637         if (hfinfo->ref_type != HF_REF_TYPE_NONE)
638                 return TRUE;
639
640         if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
641                 return TRUE;
642
643         return FALSE;
644 }
645
646
647 /* Finds a record in the hfinfo array by id. */
648 header_field_info *
649 proto_registrar_get_nth(guint hfindex)
650 {
651         register header_field_info *hfinfo;
652
653         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
654         return hfinfo;
655 }
656
657
658 /*      Prefix initialization
659  *        this allows for a dissector to register a display filter name prefix
660  *        so that it can delay the initialization of the hf array as long as
661  *        possible.
662  */
663
664 /* compute a hash for the part before the dot of a display filter */
665 static guint
666 prefix_hash (gconstpointer key) {
667         /* end the string at the dot and compute its hash */
668         gchar* copy = ep_strdup((const gchar *)key);
669         gchar* c    = copy;
670
671         for (; *c; c++) {
672                 if (*c == '.') {
673                         *c = 0;
674                         break;
675                 }
676         }
677
678         return g_str_hash(copy);
679 }
680
681 /* are both strings equal up to the end or the dot? */
682 static gboolean
683 prefix_equal (gconstpointer ap, gconstpointer bp) {
684         const gchar* a = (const gchar *)ap;
685         const gchar* b = (const gchar *)bp;
686
687         do {
688                 gchar ac = *a++;
689                 gchar bc = *b++;
690
691                 if ( (ac == '.' || ac == '\0') &&   (bc == '.' || bc == '\0') ) return TRUE;
692
693                 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
694                 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
695
696                 if (ac != bc) return FALSE;
697         } while (1);
698
699         return FALSE;
700 }
701
702
703 /* indexed by prefix, contains initializers */
704 static GHashTable* prefixes = NULL;
705
706
707 /* Register a new prefix for "delayed" initialization of field arrays */
708 void
709 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
710         if (! prefixes ) {
711                 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
712         }
713
714         g_hash_table_insert(prefixes, (gpointer)prefix, pi);
715 }
716
717 /* helper to call all prefix initializers */
718 static gboolean
719 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
720         ((prefix_initializer_t)v)((const char *)k);
721         return TRUE;
722 }
723
724 /** Initialize every remaining uninitialized prefix. */
725 void
726 proto_initialize_all_prefixes(void) {
727         g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
728 }
729
730 /* Finds a record in the hfinfo array by name.
731  * If it fails to find it in the already registered fields,
732  * it tries to find and call an initializer in the prefixes
733  * table and if so it looks again.
734  */
735 header_field_info *
736 proto_registrar_get_byname(const char *field_name)
737 {
738         header_field_info    *hfinfo;
739         prefix_initializer_t  pi;
740
741         if (!field_name)
742                 return NULL;
743
744         hfinfo = (header_field_info *)g_tree_lookup(gpa_name_tree, field_name);
745
746         if (hfinfo)
747                 return hfinfo;
748
749         if (!prefixes)
750                 return NULL;
751
752         if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
753                 pi(field_name);
754                 g_hash_table_remove(prefixes, field_name);
755         } else {
756                 return NULL;
757         }
758
759         return (header_field_info *)g_tree_lookup(gpa_name_tree, field_name);
760 }
761
762 int
763 proto_registrar_get_id_byname(const char *field_name)
764 {
765         header_field_info *hfinfo;
766
767         hfinfo = proto_registrar_get_byname(field_name);
768
769         if (!hfinfo)
770                 return -1;
771
772         return hfinfo->id;
773 }
774
775
776 static void
777 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
778 {
779         subtree_lvl *pushed_tree;
780
781         DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
782         ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
783
784         pushed_tree = (subtree_lvl *)ep_alloc(sizeof(subtree_lvl) * ptvc->pushed_tree_max);
785         DISSECTOR_ASSERT(pushed_tree != NULL);
786         if (ptvc->pushed_tree)
787                 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
788         ptvc->pushed_tree = pushed_tree;
789 }
790
791 static void
792 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
793 {
794         ptvc->pushed_tree       = NULL;
795         ptvc->pushed_tree_max   = 0;
796         DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
797         ptvc->pushed_tree_index = 0;
798 }
799
800 /* Allocates an initializes a ptvcursor_t with 3 variables:
801  *      proto_tree, tvbuff, and offset. */
802 ptvcursor_t *
803 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
804 {
805         ptvcursor_t *ptvc;
806
807         ptvc                    = (ptvcursor_t *)ep_alloc(sizeof(ptvcursor_t));
808         ptvc->tree              = tree;
809         ptvc->tvb               = tvb;
810         ptvc->offset            = offset;
811         ptvc->pushed_tree       = NULL;
812         ptvc->pushed_tree_max   = 0;
813         ptvc->pushed_tree_index = 0;
814         return ptvc;
815 }
816
817
818 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
819 void
820 ptvcursor_free(ptvcursor_t *ptvc)
821 {
822         ptvcursor_free_subtree_levels(ptvc);
823         /*g_free(ptvc);*/
824 }
825
826 /* Returns tvbuff. */
827 tvbuff_t *
828 ptvcursor_tvbuff(ptvcursor_t *ptvc)
829 {
830         return ptvc->tvb;
831 }
832
833 /* Returns current offset. */
834 gint
835 ptvcursor_current_offset(ptvcursor_t *ptvc)
836 {
837         return ptvc->offset;
838 }
839
840 proto_tree *
841 ptvcursor_tree(ptvcursor_t *ptvc)
842 {
843         if (!ptvc)
844                 return NULL;
845
846         return ptvc->tree;
847 }
848
849 void
850 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
851 {
852         ptvc->tree = tree;
853 }
854
855 /* creates a subtree, sets it as the working tree and pushes the old working tree */
856 proto_tree *
857 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
858 {
859         subtree_lvl *subtree;
860         if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
861                 ptvcursor_new_subtree_levels(ptvc);
862
863         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
864         subtree->tree = ptvc->tree;
865         subtree->it= NULL;
866         ptvc->pushed_tree_index++;
867         return ptvcursor_set_subtree(ptvc, it, ett_subtree);
868 }
869
870 /* pops a subtree */
871 void
872 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
873 {
874         subtree_lvl *subtree;
875
876         if (ptvc->pushed_tree_index <= 0)
877                 return;
878
879         ptvc->pushed_tree_index--;
880         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
881         if (subtree->it != NULL)
882                 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
883
884         ptvc->tree = subtree->tree;
885 }
886
887 /* saves the current tvb offset and the item in the current subtree level */
888 static void
889 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
890 {
891         subtree_lvl *subtree;
892
893         DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
894
895         subtree                = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
896         subtree->it            = it;
897         subtree->cursor_offset = ptvcursor_current_offset(ptvc);
898 }
899
900 /* Creates a subtree and adds it to the cursor as the working tree but does not
901  * save the old working tree */
902 proto_tree *
903 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
904 {
905         ptvc->tree = proto_item_add_subtree(it, ett_subtree);
906         return ptvc->tree;
907 }
908
909 static proto_tree *
910 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
911 {
912         ptvcursor_push_subtree(ptvc, it, ett_subtree);
913         if (length == SUBTREE_UNDEFINED_LENGTH)
914                 ptvcursor_subtree_set_item(ptvc, it);
915         return ptvcursor_tree(ptvc);
916 }
917
918 /* Add an item to the tree and create a subtree
919  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
920  * In this case, when the subtree will be closed, the parent item length will
921  * be equal to the advancement of the cursor since the creation of the subtree.
922  */
923 proto_tree *
924 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
925                            const guint encoding, gint ett_subtree)
926 {
927         proto_item *it;
928
929         it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
930         return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
931 }
932
933 static proto_item *
934 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
935
936 /* Add a text node to the tree and create a subtree
937  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
938  * In this case, when the subtree will be closed, the item length will be equal
939  * to the advancement of the cursor since the creation of the subtree.
940  */
941 proto_tree *
942 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
943                                 gint ett_subtree, const char *format, ...)
944 {
945         proto_item        *pi;
946         va_list            ap;
947         header_field_info *hfinfo;
948         proto_tree        *tree;
949
950         tree = ptvcursor_tree(ptvc);
951
952         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
953
954         pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
955                                       ptvcursor_current_offset(ptvc), length);
956
957         TRY_TO_FAKE_THIS_REPR(pi);
958
959         va_start(ap, format);
960         proto_tree_set_representation(pi, format, ap);
961         va_end(ap);
962
963         return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
964 }
965
966 /* Add a text-only node, leaving it to our caller to fill the text in */
967 static proto_item *
968 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
969 {
970         proto_item *pi;
971
972         if (tree == NULL)
973                 return NULL;
974
975         pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
976
977         return pi;
978 }
979
980 /* Add a text-only node to the proto_tree */
981 proto_item *
982 proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
983                     const char *format, ...)
984 {
985         proto_item        *pi;
986         va_list            ap;
987         header_field_info *hfinfo;
988
989         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
990
991         pi = proto_tree_add_text_node(tree, tvb, start, length);
992
993         TRY_TO_FAKE_THIS_REPR(pi);
994
995         va_start(ap, format);
996         proto_tree_set_representation(pi, format, ap);
997         va_end(ap);
998
999         return pi;
1000 }
1001
1002 /* Add a text-only node to the proto_tree (va_list version) */
1003 proto_item *
1004 proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start,
1005                            gint length, const char *format, va_list ap)
1006 {
1007         proto_item        *pi;
1008         header_field_info *hfinfo;
1009
1010         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1011
1012         pi = proto_tree_add_text_node(tree, tvb, start, length);
1013
1014         TRY_TO_FAKE_THIS_REPR(pi);
1015
1016         proto_tree_set_representation(pi, format, ap);
1017
1018         return pi;
1019 }
1020
1021 /* Add a text-only node for debugging purposes. The caller doesn't need
1022  * to worry about tvbuff, start, or length. Debug message gets sent to
1023  * STDOUT, too */
1024 proto_item *
1025 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1026 {
1027         proto_item *pi;
1028         va_list     ap;
1029
1030         pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1031
1032         if (pi) {
1033                 va_start(ap, format);
1034                 proto_tree_set_representation(pi, format, ap);
1035                 va_end(ap);
1036         }
1037         va_start(ap, format);
1038         vprintf(format, ap);
1039         va_end(ap);
1040         printf("\n");
1041
1042         return pi;
1043 }
1044
1045 /* We could probably get away with changing is_error to a minimum length value. */
1046 static void
1047 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1048         if (tree) {
1049                 tree_data_t *tree_data = PTREE_DATA(tree);
1050                 field_info *fi_save = tree_data->fi_tmp;
1051
1052                 /* Keep the current item from getting freed by proto_tree_new_item. */
1053                 tree_data->fi_tmp = NULL;
1054
1055                 expert_add_info_format(NULL, tree, PI_MALFORMED, is_error ? PI_ERROR : PI_WARN, "Trying to fetch %s with length %d", descr, length);
1056
1057                 tree_data->fi_tmp = fi_save;
1058         }
1059
1060         if (is_error) {
1061                 THROW(ReportedBoundsError);
1062         }
1063 }
1064
1065 static guint32
1066 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1067 {
1068         guint32 value;
1069         gboolean length_error;
1070
1071         switch (length) {
1072
1073         case 1:
1074                 value = tvb_get_guint8(tvb, offset);
1075                 break;
1076
1077         case 2:
1078                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1079                                                        : tvb_get_ntohs(tvb, offset);
1080                 break;
1081
1082         case 3:
1083                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1084                                                        : tvb_get_ntoh24(tvb, offset);
1085                 break;
1086
1087         case 4:
1088                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1089                                                        : tvb_get_ntohl(tvb, offset);
1090                 break;
1091
1092         default:
1093                 if (length < 1) {
1094                         length_error = TRUE;
1095                         value = 0;
1096                 } else {
1097                         length_error = FALSE;
1098                         value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1099                                                                : tvb_get_ntohl(tvb, offset);
1100                 }
1101                 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1102                 break;
1103         }
1104         return value;
1105 }
1106
1107 /*
1108  * NOTE: to support code written when proto_tree_add_item() took a
1109  * gboolean as its last argument, with FALSE meaning "big-endian"
1110  * and TRUE meaning "little-endian", we treat any non-zero value of
1111  * "encoding" as meaning "little-endian".
1112  */
1113 static gint32
1114 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1115 {
1116         gint32 value;
1117         gboolean length_error;
1118
1119         switch (length) {
1120
1121         case 1:
1122                 value = (gint8)tvb_get_guint8(tvb, offset);
1123                 break;
1124
1125         case 2:
1126                 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1127                                            : tvb_get_ntohs(tvb, offset));
1128                 break;
1129
1130         case 3:
1131                 value = encoding ? tvb_get_letoh24(tvb, offset)
1132                                  : tvb_get_ntoh24(tvb, offset);
1133                 if (value & 0x00800000) {
1134                         /* Sign bit is set; sign-extend it. */
1135                         value |= 0xFF000000;
1136                 }
1137                 break;
1138
1139         case 4:
1140                 value = encoding ? tvb_get_letohl(tvb, offset)
1141                                  : tvb_get_ntohl(tvb, offset);
1142                 break;
1143
1144         default:
1145                 if (length < 1) {
1146                         length_error = TRUE;
1147                         value = 0;
1148                 } else {
1149                         length_error = FALSE;
1150                         value = encoding ? tvb_get_letohl(tvb, offset)
1151                                          : tvb_get_ntohl(tvb, offset);
1152                 }
1153                 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1154                 break;
1155         }
1156         return value;
1157 }
1158
1159 static void
1160 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
1161 {
1162         const header_field_info *hfinfo = fi->hfinfo;
1163
1164         if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
1165                 GPtrArray *ptrs = NULL;
1166
1167                 if (tree_data->interesting_hfids == NULL) {
1168                         /* Initialize the hash because we now know that it is needed */
1169                         tree_data->interesting_hfids =
1170                                 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
1171                 } else
1172                         ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
1173                                            GINT_TO_POINTER(hfinfo->id));
1174                 if (!ptrs) {
1175                         /* First element triggers the creation of pointer array */
1176                         ptrs = g_ptr_array_new();
1177                         g_hash_table_insert(tree_data->interesting_hfids,
1178                                             GINT_TO_POINTER(hfinfo->id), ptrs);
1179                 }
1180
1181                 g_ptr_array_add(ptrs, fi);
1182         }
1183 }
1184
1185 /* Add an item to a proto_tree, using the text label registered to that item;
1186    the item is extracted from the tvbuff handed to it. */
1187 static proto_item *
1188 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
1189                     tvbuff_t *tvb, gint start, gint length,
1190                     guint encoding)
1191 {
1192         tree_data_t *tree_data = PTREE_DATA(tree);
1193         proto_item *pi;
1194         guint32     value, n;
1195         float       floatval;
1196         double      doubleval;
1197         const char *string;
1198         nstime_t    time_stamp;
1199         guint32     tmpsecs;
1200         gboolean    length_error;
1201
1202         /* there is a possibility here that we might raise an exception
1203          * and thus would lose track of the field_info.
1204          * store it in a temp so that if we come here again we can reclaim
1205          * the field_info without leaking memory.
1206          */
1207         if (tree_data->fi_tmp) {
1208                 /* oops, last one we got must have been lost due
1209                  * to an exception.
1210                  * good thing we saved it, now we can reverse the
1211                  * memory leak and reclaim it.
1212                  */
1213                 FIELD_INFO_FREE(tree_data->fi_tmp);
1214         }
1215         /* we might throw an exception, keep track of this one
1216          * across the "dangerous" section below.
1217         */
1218         tree_data->fi_tmp = new_fi;
1219
1220         switch (new_fi->hfinfo->type) {
1221                 case FT_NONE:
1222                         /* no value to set for FT_NONE */
1223                         break;
1224
1225                 case FT_PROTOCOL:
1226                         proto_tree_set_protocol_tvb(new_fi, tvb);
1227                         break;
1228
1229                 case FT_BYTES:
1230                         proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
1231                         break;
1232
1233                 case FT_UINT_BYTES:
1234                         /*
1235                          * Map all non-zero values to little-endian for
1236                          * backwards compatibility.
1237                          */
1238                         if (encoding)
1239                                 encoding = ENC_LITTLE_ENDIAN;
1240                         n = get_uint_value(tree, tvb, start, length, encoding);
1241                         proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
1242
1243                         /* Instead of calling proto_item_set_len(), since we don't yet
1244                          * have a proto_item, we set the field_info's length ourselves. */
1245                         new_fi->length = n + length;
1246                         break;
1247
1248                 case FT_BOOLEAN:
1249                         /*
1250                          * Map all non-zero values to little-endian for
1251                          * backwards compatibility.
1252                          */
1253                         if (encoding)
1254                                 encoding = ENC_LITTLE_ENDIAN;
1255                         proto_tree_set_boolean(new_fi,
1256                                 get_uint_value(tree, tvb, start, length, encoding));
1257                         break;
1258
1259                 /* XXX - make these just FT_UINT? */
1260                 case FT_UINT8:
1261                 case FT_UINT16:
1262                 case FT_UINT24:
1263                 case FT_UINT32:
1264                         /*
1265                          * Map all non-zero values to little-endian for
1266                          * backwards compatibility.
1267                          */
1268                         if (encoding)
1269                                 encoding = ENC_LITTLE_ENDIAN;
1270                         proto_tree_set_uint(new_fi,
1271                                 get_uint_value(tree, tvb, start, length, encoding));
1272                         break;
1273
1274                 case FT_INT64:
1275                 case FT_UINT64:
1276                         /*
1277                          * Map all non-zero values to little-endian for
1278                          * backwards compatibility.
1279                          */
1280                         if (encoding)
1281                                 encoding = ENC_LITTLE_ENDIAN;
1282                         if (length < 1 || length > 8) {
1283                                 length_error = length < 1 ? TRUE : FALSE;
1284                                 report_type_length_mismatch(tree, "a 64-bit integer", length, length_error);
1285                         }
1286                         proto_tree_set_uint64_tvb(new_fi, tvb, start, length, encoding);
1287                         break;
1288
1289                 /* XXX - make these just FT_INT? */
1290                 case FT_INT8:
1291                 case FT_INT16:
1292                 case FT_INT24:
1293                 case FT_INT32:
1294                         /*
1295                          * Map all non-zero values to little-endian for
1296                          * backwards compatibility.
1297                          */
1298                         if (encoding)
1299                                 encoding = ENC_LITTLE_ENDIAN;
1300                         proto_tree_set_int(new_fi,
1301                                 get_int_value(tree, tvb, start, length, encoding));
1302                         break;
1303
1304                 case FT_IPv4:
1305                         /*
1306                          * Map all non-zero values to little-endian for
1307                          * backwards compatibility.
1308                          */
1309                         if (encoding)
1310                                 encoding = ENC_LITTLE_ENDIAN;
1311                         if (length != FT_IPv4_LEN) {
1312                                 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
1313                                 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
1314                         }
1315                         value = tvb_get_ipv4(tvb, start);
1316                         /*
1317                          * NOTE: to support code written when
1318                          * proto_tree_add_item() took a gboolean as its
1319                          * last argument, with FALSE meaning "big-endian"
1320                          * and TRUE meaning "little-endian", we treat any
1321                          * non-zero value of "encoding" as meaning
1322                          * "little-endian".
1323                          */
1324                         proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
1325                         break;
1326
1327                 case FT_IPXNET:
1328                         if (length != FT_IPXNET_LEN) {
1329                                 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
1330                                 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
1331                         }
1332                         proto_tree_set_ipxnet(new_fi,
1333                                 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
1334                         break;
1335
1336                 case FT_IPv6:
1337                         if (length != FT_IPv6_LEN) {
1338                                 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
1339                                 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
1340                         }
1341                         proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
1342                         break;
1343
1344                 case FT_AX25:
1345                         if (length != 7) {
1346                                 length_error = length < 7 ? TRUE : FALSE;
1347                                 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
1348                         }
1349                         proto_tree_set_ax25_tvb(new_fi, tvb, start);
1350                         break;
1351
1352                 case FT_VINES:
1353                         if (length != VINES_ADDR_LEN) {
1354                                 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
1355                                 report_type_length_mismatch(tree, "a Vines address", length, length_error);
1356                         }
1357                         proto_tree_set_vines_tvb(new_fi, tvb, start);
1358                         break;
1359
1360                 case FT_ETHER:
1361                         if (length != FT_ETHER_LEN) {
1362                                 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
1363                                 report_type_length_mismatch(tree, "an Ethernet", length, length_error);
1364                         }
1365                         proto_tree_set_ether_tvb(new_fi, tvb, start);
1366                         break;
1367
1368                 case FT_EUI64:
1369                         /*
1370                          * Map all non-zero values to little-endian for
1371                          * backwards compatibility.
1372                          */
1373                         if (encoding)
1374                                 encoding = ENC_LITTLE_ENDIAN;
1375                         if (length != FT_EUI64_LEN) {
1376                                 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
1377                                 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
1378                         }
1379                         proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
1380                         break;
1381                 case FT_GUID:
1382                         /*
1383                          * Map all non-zero values to little-endian for
1384                          * backwards compatibility.
1385                          */
1386                         if (encoding)
1387                                 encoding = ENC_LITTLE_ENDIAN;
1388                         if (length != FT_GUID_LEN) {
1389                                 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
1390                                 report_type_length_mismatch(tree, "a GUID", length, length_error);
1391                         }
1392                         proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
1393                         break;
1394
1395                 case FT_OID:
1396                         proto_tree_set_oid_tvb(new_fi, tvb, start, length);
1397                         break;
1398
1399                 case FT_FLOAT:
1400                         /*
1401                          * NOTE: to support code written when
1402                          * proto_tree_add_item() took a gboolean as its
1403                          * last argument, with FALSE meaning "big-endian"
1404                          * and TRUE meaning "little-endian", we treat any
1405                          * non-zero value of "encoding" as meaning
1406                          * "little-endian".
1407                          *
1408                          * At some point in the future, we might
1409                          * support non-IEEE-binary floating-point
1410                          * formats in the encoding as well
1411                          * (IEEE decimal, System/3x0, VAX).
1412                          */
1413                         if (encoding)
1414                                 encoding = ENC_LITTLE_ENDIAN;
1415                         if (length != 4) {
1416                                 length_error = length < 4 ? TRUE : FALSE;
1417                                 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
1418                         }
1419                         if (encoding)
1420                                 floatval = tvb_get_letohieee_float(tvb, start);
1421                         else
1422                                 floatval = tvb_get_ntohieee_float(tvb, start);
1423                         proto_tree_set_float(new_fi, floatval);
1424                         break;
1425
1426                 case FT_DOUBLE:
1427                         /*
1428                          * NOTE: to support code written when
1429                          * proto_tree_add_item() took a gboolean as its
1430                          * last argument, with FALSE meaning "big-endian"
1431                          * and TRUE meaning "little-endian", we treat any
1432                          * non-zero value of "encoding" as meaning
1433                          * "little-endian".
1434                          *
1435                          * At some point in the future, we might
1436                          * support non-IEEE-binary floating-point
1437                          * formats in the encoding as well
1438                          * (IEEE decimal, System/3x0, VAX).
1439                          */
1440                         if (encoding == TRUE)
1441                                 encoding = ENC_LITTLE_ENDIAN;
1442                         if (length != 8) {
1443                                 length_error = length < 8 ? TRUE : FALSE;
1444                                 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
1445                         }
1446                         if (encoding)
1447                                 doubleval = tvb_get_letohieee_double(tvb, start);
1448                         else
1449                                 doubleval = tvb_get_ntohieee_double(tvb, start);
1450                         proto_tree_set_double(new_fi, doubleval);
1451                         break;
1452
1453                 case FT_STRING:
1454                         proto_tree_set_string_tvb(new_fi, tvb, start, length,
1455                             encoding);
1456                         break;
1457
1458                 case FT_STRINGZ:
1459                         if (length < -1 ) {
1460                                 report_type_length_mismatch(tree, "a string", length, TRUE);
1461                         }
1462                         /* Instead of calling proto_item_set_len(),
1463                          * since we don't yet have a proto_item, we
1464                          * set the field_info's length ourselves.
1465                          *
1466                          * XXX - our caller can't use that length to
1467                          * advance an offset unless they arrange that
1468                          * there always be a protocol tree into which
1469                          * we're putting this item.
1470                          */
1471                         if (length == -1) {
1472                                 /* This can throw an exception */
1473                                 string = tvb_get_stringz_enc(tvb, start, &length, encoding);
1474                         } else if (length == 0) {
1475                                 string = "[Empty]";
1476                         } else {
1477                                 /* In this case, length signifies
1478                                  * the length of the string.
1479                                  *
1480                                  * This could either be a null-padded
1481                                  * string, which doesn't necessarily
1482                                  * have a '\0' at the end, or a
1483                                  * null-terminated string, with a
1484                                  * trailing '\0'.  (Yes, there are
1485                                  * cases where you have a string
1486                                  * that's both counted and null-
1487                                  * terminated.)
1488                                  *
1489                                  * In the first case, we must
1490                                  * allocate a buffer of length
1491                                  * "length+1", to make room for
1492                                  * a trailing '\0'.
1493                                  *
1494                                  * In the second case, we don't
1495                                  * assume that there is a trailing
1496                                  * '\0' there, as the packet might
1497                                  * be malformed.  (XXX - should we
1498                                  * throw an exception if there's no
1499                                  * trailing '\0'?)      Therefore, we
1500                                  * allocate a buffer of length
1501                                  * "length+1", and put in a trailing
1502                                  * '\0', just to be safe.
1503                                  *
1504                                  * (XXX - this would change if
1505                                  * we made string values counted
1506                                  * rather than null-terminated.)
1507                                  */
1508                                 string = tvb_get_ephemeral_string_enc(tvb, start, length, encoding);
1509                         }
1510                         new_fi->length = length;
1511                         proto_tree_set_string(new_fi, string);
1512                         break;
1513
1514                 case FT_UINT_STRING:
1515                         /*
1516                          * NOTE: to support code written when
1517                          * proto_tree_add_item() took a gboolean as its
1518                          * last argument, with FALSE meaning "big-endian"
1519                          * and TRUE meaning "little-endian", if the
1520                          * encoding value is TRUE, treat that as
1521                          * ASCII with a little-endian length.
1522                          *
1523                          * This won't work for code that passes
1524                          * arbitrary non-zero values; that code
1525                          * will need to be fixed.
1526                          */
1527                         if (encoding == TRUE)
1528                                 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
1529                         n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1530                         proto_tree_set_string_tvb(new_fi, tvb, start + length, n,
1531                             encoding);
1532
1533                         /* Instead of calling proto_item_set_len(), since we
1534                          * don't yet have a proto_item, we set the
1535                          * field_info's length ourselves.
1536                          *
1537                          * XXX - our caller can't use that length to
1538                          * advance an offset unless they arrange that
1539                          * there always be a protocol tree into which
1540                          * we're putting this item.
1541                          */
1542                         new_fi->length = n + length;
1543                         break;
1544
1545                 case FT_ABSOLUTE_TIME:
1546                         /*
1547                          * Absolute times can be in any of a number of
1548                          * formats, and they can be big-endian or
1549                          * little-endian.
1550                          *
1551                          * Historically FT_TIMEs were only timespecs;
1552                          * the only question was whether they were stored
1553                          * in big- or little-endian format.
1554                          *
1555                          * For backwards compatibility, we interpret an
1556                          * encoding of 1 as meaning "little-endian timespec",
1557                          * so that passing TRUE is interpreted as that.
1558                          */
1559                         if (encoding == TRUE)
1560                                 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
1561
1562                         if (length != 8 && length != 4) {
1563                                 length_error = length < 4 ? TRUE : FALSE;
1564                                 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
1565                         }
1566
1567                         switch (encoding) {
1568
1569                         case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1570                                 /*
1571                                  * 4-byte UNIX epoch, possibly followed by
1572                                  * 4-byte fractional time in nanoseconds,
1573                                  * both big-endian.
1574                                  */
1575                                 time_stamp.secs  = tvb_get_ntohl(tvb, start);
1576                                 if (length == 8)
1577                                         time_stamp.nsecs = tvb_get_ntohl(tvb, start+4);
1578                                 else
1579                                         time_stamp.nsecs = 0;
1580                                 break;
1581
1582                         case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1583                                 /*
1584                                  * 4-byte UNIX epoch, possibly followed by
1585                                  * 4-byte fractional time in nanoseconds,
1586                                  * both little-endian.
1587                                  */
1588                                 time_stamp.secs  = tvb_get_letohl(tvb, start);
1589                                 if (length == 8)
1590                                         time_stamp.nsecs = tvb_get_letohl(tvb, start+4);
1591                                 else
1592                                         time_stamp.nsecs = 0;
1593                                 break;
1594
1595                         case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1596                                 /*
1597                                  * NTP time stamp, big-endian.
1598                                  */
1599
1600 /* XXX - where should this go? */
1601 #define NTP_BASETIME 2208988800ul
1602
1603                                 /* We need a temporary variable here so the unsigned math
1604                                  * works correctly (for years > 2036 according to RFC 2030
1605                                  * chapter 3).
1606                                  */
1607                                 tmpsecs  = tvb_get_ntohl(tvb, start);
1608                                 if (tmpsecs)
1609                                         time_stamp.secs = tmpsecs - (guint32)NTP_BASETIME;
1610                                 else
1611                                         time_stamp.secs = tmpsecs; /* 0 */
1612
1613                                 if (length == 8) {
1614                                         /*
1615                                          * We're using nanoseconds here (and we will
1616                                          * display nanoseconds), but NTP's timestamps
1617                                          * have a precision in microseconds or greater.
1618                                          * Round to 1 microsecond.
1619                                          */
1620                                         time_stamp.nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1621                                         time_stamp.nsecs *= 1000;
1622                                 } else {
1623                                         time_stamp.nsecs = 0;
1624                                 }
1625                                 break;
1626
1627                         case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1628                                 /*
1629                                  * NTP time stamp, big-endian.
1630                                  */
1631                                 tmpsecs  = tvb_get_letohl(tvb, start);
1632                                 if (tmpsecs)
1633                                         time_stamp.secs = tmpsecs - (guint32)NTP_BASETIME;
1634                                 else
1635                                         time_stamp.secs = tmpsecs; /* 0 */
1636
1637                                 if (length == 8) {
1638                                         /*
1639                                          * We're using nanoseconds here (and we will
1640                                          * display nanoseconds), but NTP's timestamps
1641                                          * have a precision in microseconds or greater.
1642                                          * Round to 1 microsecond.
1643                                          */
1644                                         time_stamp.nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1645                                         time_stamp.nsecs *= 1000;
1646                                 } else {
1647                                         time_stamp.nsecs = 0;
1648                                 }
1649                                 break;
1650
1651                         default:
1652                                 DISSECTOR_ASSERT_NOT_REACHED();
1653                                 time_stamp.secs = 0;
1654                                 time_stamp.nsecs = 0;
1655                                 break;
1656                         }
1657                         proto_tree_set_time(new_fi, &time_stamp);
1658                         break;
1659
1660                 case FT_RELATIVE_TIME:
1661                         /*
1662                          * Relative times can be in any of a number of
1663                          * formats, and they can be big-endian or
1664                          * little-endian.
1665                          *
1666                          * Historically FT_TIMEs were only timespecs;
1667                          * the only question was whether they were stored
1668                          * in big- or little-endian format.
1669                          *
1670                          * For backwards compatibility, we interpret an
1671                          * encoding of 1 as meaning "little-endian timespec",
1672                          * so that passing TRUE is interpreted as that.
1673                          */
1674                         if (encoding == TRUE)
1675                                 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
1676                         switch (encoding) {
1677
1678                         if (length != 8 && length != 4) {
1679                                 length_error = length < 4 ? TRUE : FALSE;
1680                                 report_type_length_mismatch(tree, "a relative time value", length, length_error);
1681                         }
1682
1683                         case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1684                                 /*
1685                                  * 4-byte UNIX epoch, possibly followed by
1686                                  * 4-byte fractional time in nanoseconds,
1687                                  * both big-endian.
1688                                  */
1689                                 time_stamp.secs  = tvb_get_ntohl(tvb, start);
1690                                 if (length == 8)
1691                                         time_stamp.nsecs = tvb_get_ntohl(tvb, start+4);
1692                                 else
1693                                         time_stamp.nsecs = 0;
1694                                 break;
1695
1696                         case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1697                                 /*
1698                                  * 4-byte UNIX epoch, possibly followed by
1699                                  * 4-byte fractional time in nanoseconds,
1700                                  * both little-endian.
1701                                  */
1702                                 time_stamp.secs  = tvb_get_letohl(tvb, start);
1703                                 if (length == 8)
1704                                         time_stamp.nsecs = tvb_get_letohl(tvb, start+4);
1705                                 else
1706                                         time_stamp.nsecs = 0;
1707                                 break;
1708                         }
1709                         proto_tree_set_time(new_fi, &time_stamp);
1710                         break;
1711
1712                 default:
1713                         g_error("new_fi->hfinfo->type %d (%s) not handled\n",
1714                                         new_fi->hfinfo->type,
1715                                         ftype_name(new_fi->hfinfo->type));
1716                         DISSECTOR_ASSERT_NOT_REACHED();
1717                         break;
1718         }
1719         FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
1720
1721         /* Don't add new node to proto_tree until now so that any exceptions
1722          * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
1723         /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
1724          *      to know which item caused exception? */
1725         pi = proto_tree_add_node(tree, new_fi);
1726
1727         /* we did not raise an exception so we dont have to remember this
1728          * field_info struct any more.
1729          */
1730         tree_data->fi_tmp = NULL;
1731
1732         return pi;
1733 }
1734
1735 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
1736    and returns proto_item* */
1737 proto_item *
1738 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
1739               const guint encoding)
1740 {
1741         field_info        *new_fi;
1742         header_field_info *hfinfo;
1743         gint               item_length;
1744         guint32            n;
1745         int                offset;
1746
1747         /* We can't fake it just yet. We have to advance the cursor
1748         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo); */
1749
1750         offset = ptvc->offset;
1751         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1752         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
1753         ptvc->offset += length;
1754         if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
1755                 /*
1756                  * The length of the rest of the item is in the first N
1757                  * bytes of the item.
1758                  */
1759                 n = get_uint_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
1760                 ptvc->offset += n;
1761         }
1762
1763         /* Coast clear. Try and fake it */
1764         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
1765
1766         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
1767
1768         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
1769                 offset, length, encoding);
1770 }
1771
1772 /*
1773  * Validates that field length bytes are available starting from
1774  * start (pos/neg). Throws an exception if they aren't.
1775  */
1776 static void
1777 test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb,
1778             gint start, gint length, const guint encoding)
1779 {
1780         gint size = length;
1781
1782         if (!tvb)
1783                 return;
1784
1785         if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
1786                 guint32 n;
1787
1788                 n = get_uint_value(tree, tvb, start, length, encoding);
1789                 if (n > size + n) {
1790                         /* If n > size + n then we have an integer overflow, so
1791                          * set size to -1, which will force the
1792                          * tvb_ensure_bytes_exist call below to throw a
1793                          * ReportedBoundsError
1794                          */
1795                         size = -1;
1796                 }
1797                 else {
1798                         size += n;
1799                 }
1800         } else if (hfinfo->type == FT_STRINGZ) {
1801                 /* If we're fetching until the end of the TVB, only validate
1802                  * that the offset is within range.
1803                  */
1804                 if (length == -1)
1805                         size = 0;
1806         }
1807
1808         tvb_ensure_bytes_exist(tvb, start, size);
1809 }
1810
1811 /* Add an item to a proto_tree, using the text label registered to that item;
1812    the item is extracted from the tvbuff handed to it. */
1813 proto_item *
1814 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
1815                     const gint start, gint length, const guint encoding)
1816 {
1817         field_info        *new_fi;
1818         gint              item_length;
1819
1820         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
1821
1822         get_hfi_length(hfinfo, tvb, start, &length, &item_length);
1823         test_length(hfinfo, tree, tvb, start, item_length, encoding);
1824
1825         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
1826
1827         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
1828
1829         if (new_fi == NULL)
1830                 return NULL;
1831
1832         return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
1833 }
1834
1835 proto_item *
1836 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1837                     const gint start, gint length, const guint encoding)
1838 {
1839         return proto_tree_add_item_new(tree, proto_registrar_get_nth(hfindex), tvb, start, length, encoding);
1840 }
1841
1842 /* Add a FT_NONE to a proto_tree */
1843 proto_item *
1844 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
1845                            const gint start, gint length, const char *format,
1846                            ...)
1847 {
1848         proto_item        *pi;
1849         va_list            ap;
1850         header_field_info *hfinfo;
1851
1852         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1853
1854         DISSECTOR_ASSERT(hfinfo->type == FT_NONE);
1855
1856         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
1857
1858         TRY_TO_FAKE_THIS_REPR(pi);
1859
1860         va_start(ap, format);
1861         proto_tree_set_representation(pi, format, ap);
1862         va_end(ap);
1863
1864         /* no value to set for FT_NONE */
1865         return pi;
1866 }
1867
1868 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
1869  * offset, and returns proto_item* */
1870 proto_item *
1871 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
1872                          const guint encoding)
1873 {
1874         proto_item *item;
1875
1876         item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
1877                                    length, encoding);
1878
1879         return item;
1880 }
1881
1882 /* Advance the ptvcursor's offset within its tvbuff without
1883  * adding anything to the proto_tree. */
1884 void
1885 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
1886 {
1887         ptvc->offset += length;
1888 }
1889
1890
1891 static void
1892 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
1893 {
1894         fvalue_set(&fi->value, tvb, TRUE);
1895 }
1896
1897 /* Add a FT_PROTOCOL to a proto_tree */
1898 proto_item *
1899 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1900                                gint start, gint length, const char *format, ...)
1901 {
1902         proto_item        *pi;
1903         va_list            ap;
1904         header_field_info *hfinfo;
1905
1906         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1907
1908         DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
1909
1910         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
1911
1912         proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset(tvb, start, length, length)));
1913
1914         TRY_TO_FAKE_THIS_REPR(pi);
1915
1916         va_start(ap, format);
1917         proto_tree_set_representation(pi, format, ap);
1918         va_end(ap);
1919
1920         return pi;
1921 }
1922
1923
1924 /* Add a FT_BYTES to a proto_tree */
1925 proto_item *
1926 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1927                      gint length, const guint8 *start_ptr)
1928 {
1929         proto_item        *pi;
1930         header_field_info *hfinfo;
1931
1932         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1933
1934         DISSECTOR_ASSERT(hfinfo->type == FT_BYTES);
1935
1936         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
1937         proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
1938
1939         return pi;
1940 }
1941
1942 proto_item *
1943 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1944                                   gint start, gint length,
1945                                   const guint8 *start_ptr,
1946                                   const char *format, ...)
1947 {
1948         proto_item        *pi;
1949         va_list            ap;
1950         header_field_info *hfinfo;
1951
1952         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1953
1954         if (start_ptr)
1955                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1956                                           start_ptr);
1957         else
1958                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1959                                           tvb_get_ptr(tvb, start, length));
1960
1961         va_start(ap, format);
1962         proto_tree_set_representation_value(pi, format, ap);
1963         va_end(ap);
1964
1965         return pi;
1966 }
1967
1968 proto_item *
1969 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1970                             gint start, gint length, const guint8 *start_ptr,
1971                             const char *format, ...)
1972 {
1973         proto_item        *pi;
1974         va_list            ap;
1975         header_field_info *hfinfo;
1976
1977         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1978
1979         if (start_ptr)
1980                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1981                                           start_ptr);
1982         else
1983                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1984                                           tvb_get_ptr(tvb, start, length));
1985
1986         TRY_TO_FAKE_THIS_REPR(pi);
1987
1988         va_start(ap, format);
1989         proto_tree_set_representation(pi, format, ap);
1990         va_end(ap);
1991
1992         return pi;
1993 }
1994
1995 static void
1996 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
1997 {
1998         GByteArray *bytes;
1999
2000         bytes = g_byte_array_new();
2001         if (length > 0) {
2002                 g_byte_array_append(bytes, start_ptr, length);
2003         }
2004         fvalue_set(&fi->value, bytes, TRUE);
2005 }
2006
2007
2008 static void
2009 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
2010 {
2011         proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
2012 }
2013
2014 /* Add a FT_*TIME to a proto_tree */
2015 proto_item *
2016 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2017                     gint length, nstime_t *value_ptr)
2018 {
2019         proto_item        *pi;
2020         header_field_info *hfinfo;
2021
2022         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2023
2024         DISSECTOR_ASSERT(hfinfo->type == FT_ABSOLUTE_TIME ||
2025                          hfinfo->type == FT_RELATIVE_TIME);
2026
2027         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2028         proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
2029
2030         return pi;
2031 }
2032
2033 proto_item *
2034 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2035                                  gint start, gint length, nstime_t *value_ptr,
2036                                  const char *format, ...)
2037 {
2038         proto_item        *pi;
2039         va_list            ap;
2040
2041         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
2042         if (pi != tree) {
2043                 va_start(ap, format);
2044                 proto_tree_set_representation_value(pi, format, ap);
2045                 va_end(ap);
2046         }
2047
2048         return pi;
2049 }
2050
2051 proto_item *
2052 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2053                            gint start, gint length, nstime_t *value_ptr,
2054                            const char *format, ...)
2055 {
2056         proto_item        *pi;
2057         va_list            ap;
2058
2059         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
2060         if (pi != tree) {
2061                 TRY_TO_FAKE_THIS_REPR(pi);
2062
2063                 va_start(ap, format);
2064                 proto_tree_set_representation(pi, format, ap);
2065                 va_end(ap);
2066         }
2067
2068         return pi;
2069 }
2070
2071 /* Set the FT_*TIME value */
2072 static void
2073 proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
2074 {
2075         DISSECTOR_ASSERT(value_ptr != NULL);
2076
2077         fvalue_set(&fi->value, value_ptr, FALSE);
2078 }
2079
2080 /* Add a FT_IPXNET to a proto_tree */
2081 proto_item *
2082 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2083                       gint length, guint32 value)
2084 {
2085         proto_item        *pi;
2086         header_field_info *hfinfo;
2087
2088         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2089
2090         DISSECTOR_ASSERT(hfinfo->type == FT_IPXNET);
2091
2092         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2093         proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
2094
2095         return pi;
2096 }
2097
2098 proto_item *
2099 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2100                                    gint start, gint length, guint32 value,
2101                                    const char *format, ...)
2102 {
2103         proto_item        *pi;
2104         va_list            ap;
2105
2106         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
2107         if (pi != tree) {
2108                 va_start(ap, format);
2109                 proto_tree_set_representation_value(pi, format, ap);
2110                 va_end(ap);
2111         }
2112
2113         return pi;
2114 }
2115
2116 proto_item *
2117 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2118                              gint start, gint length, guint32 value,
2119                              const char *format, ...)
2120 {
2121         proto_item        *pi;
2122         va_list            ap;
2123
2124         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
2125         if (pi != tree) {
2126                 TRY_TO_FAKE_THIS_REPR(pi);
2127
2128                 va_start(ap, format);
2129                 proto_tree_set_representation(pi, format, ap);
2130                 va_end(ap);
2131         }
2132
2133         return pi;
2134 }
2135
2136 /* Set the FT_IPXNET value */
2137 static void
2138 proto_tree_set_ipxnet(field_info *fi, guint32 value)
2139 {
2140         fvalue_set_uinteger(&fi->value, value);
2141 }
2142
2143 /* Add a FT_IPv4 to a proto_tree */
2144 proto_item *
2145 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2146                     gint length, guint32 value)
2147 {
2148         proto_item        *pi;
2149         header_field_info *hfinfo;
2150
2151         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2152
2153         DISSECTOR_ASSERT(hfinfo->type == FT_IPv4);
2154
2155         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2156         proto_tree_set_ipv4(PNODE_FINFO(pi), value);
2157
2158         return pi;
2159 }
2160
2161 proto_item *
2162 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2163                                  gint start, gint length, guint32 value,
2164                                  const char *format, ...)
2165 {
2166         proto_item        *pi;
2167         va_list            ap;
2168
2169         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
2170         if (pi != tree) {
2171                 va_start(ap, format);
2172                 proto_tree_set_representation_value(pi, format, ap);
2173                 va_end(ap);
2174         }
2175
2176         return pi;
2177 }
2178
2179 proto_item *
2180 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2181                            gint start, gint length, guint32 value,
2182                            const char *format, ...)
2183 {
2184         proto_item        *pi;
2185         va_list            ap;
2186
2187         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
2188         if (pi != tree) {
2189                 TRY_TO_FAKE_THIS_REPR(pi);
2190
2191                 va_start(ap, format);
2192                 proto_tree_set_representation(pi, format, ap);
2193                 va_end(ap);
2194         }
2195
2196         return pi;
2197 }
2198
2199 /* Set the FT_IPv4 value */
2200 static void
2201 proto_tree_set_ipv4(field_info *fi, guint32 value)
2202 {
2203         fvalue_set_uinteger(&fi->value, value);
2204 }
2205
2206 /* Add a FT_IPv6 to a proto_tree */
2207 proto_item *
2208 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2209                     gint length, const guint8* value_ptr)
2210 {
2211         proto_item        *pi;
2212         header_field_info *hfinfo;
2213
2214         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2215
2216         DISSECTOR_ASSERT(hfinfo->type == FT_IPv6);
2217
2218         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2219         proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr);
2220
2221         return pi;
2222 }
2223
2224 proto_item *
2225 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2226                                  gint start, gint length,
2227                                  const guint8* value_ptr,
2228                                  const char *format, ...)
2229 {
2230         proto_item        *pi;
2231         va_list            ap;
2232
2233         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
2234         if (pi != tree) {
2235                 va_start(ap, format);
2236                 proto_tree_set_representation_value(pi, format, ap);
2237                 va_end(ap);
2238         }
2239
2240         return pi;
2241 }
2242
2243 proto_item *
2244 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2245                            gint start, gint length, const guint8* value_ptr,
2246                            const char *format, ...)
2247 {
2248         proto_item        *pi;
2249         va_list            ap;
2250
2251         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
2252         if (pi != tree) {
2253                 TRY_TO_FAKE_THIS_REPR(pi);
2254
2255                 va_start(ap, format);
2256                 proto_tree_set_representation(pi, format, ap);
2257                 va_end(ap);
2258         }
2259
2260         return pi;
2261 }
2262
2263 /* Set the FT_IPv6 value */
2264 static void
2265 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
2266 {
2267         DISSECTOR_ASSERT(value_ptr != NULL);
2268         fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
2269 }
2270
2271 static void
2272 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
2273 {
2274         proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
2275 }
2276
2277 /* Add a FT_GUID to a proto_tree */
2278 proto_item *
2279 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2280                     gint length, const e_guid_t *value_ptr)
2281 {
2282         proto_item        *pi;
2283         header_field_info *hfinfo;
2284
2285         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2286
2287         DISSECTOR_ASSERT(hfinfo->type == FT_GUID);
2288
2289         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2290         proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
2291
2292         return pi;
2293 }
2294
2295 proto_item *
2296 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2297                                  gint start, gint length,
2298                                  const e_guid_t *value_ptr,
2299                                  const char *format, ...)
2300 {
2301         proto_item        *pi;
2302         va_list            ap;
2303
2304         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
2305         if (pi != tree) {
2306                 va_start(ap, format);
2307                 proto_tree_set_representation_value(pi, format, ap);
2308                 va_end(ap);
2309         }
2310
2311         return pi;
2312 }
2313
2314 proto_item *
2315 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2316                            gint start, gint length, const e_guid_t *value_ptr,
2317                            const char *format, ...)
2318 {
2319         proto_item        *pi;
2320         va_list            ap;
2321
2322         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
2323         if (pi != tree) {
2324                 TRY_TO_FAKE_THIS_REPR(pi);
2325
2326                 va_start(ap, format);
2327                 proto_tree_set_representation(pi, format, ap);
2328                 va_end(ap);
2329         }
2330
2331         return pi;
2332 }
2333
2334 /* Set the FT_GUID value */
2335 static void
2336 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
2337 {
2338         DISSECTOR_ASSERT(value_ptr != NULL);
2339         fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
2340 }
2341
2342 static void
2343 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
2344                         const guint encoding)
2345 {
2346         e_guid_t guid;
2347
2348         tvb_get_guid(tvb, start, &guid, encoding);
2349         proto_tree_set_guid(fi, &guid);
2350 }
2351
2352 /* Add a FT_OID to a proto_tree */
2353 proto_item *
2354 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2355                    gint length, const guint8* value_ptr)
2356 {
2357         proto_item        *pi;
2358         header_field_info *hfinfo;
2359
2360         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2361
2362         DISSECTOR_ASSERT(hfinfo->type == FT_OID);
2363
2364         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2365         proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
2366
2367         return pi;
2368 }
2369
2370 proto_item *
2371 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2372                                 gint start, gint length,
2373                                 const guint8* value_ptr,
2374                                 const char *format, ...)
2375 {
2376         proto_item        *pi;
2377         va_list            ap;
2378
2379         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
2380         if (pi != tree) {
2381                 va_start(ap, format);
2382                 proto_tree_set_representation_value(pi, format, ap);
2383                 va_end(ap);
2384         }
2385
2386         return pi;
2387 }
2388
2389 proto_item *
2390 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2391                           gint start, gint length, const guint8* value_ptr,
2392                           const char *format, ...)
2393 {
2394         proto_item        *pi;
2395         va_list            ap;
2396
2397         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
2398         if (pi != tree) {
2399                 TRY_TO_FAKE_THIS_REPR(pi);
2400
2401                 va_start(ap, format);
2402                 proto_tree_set_representation(pi, format, ap);
2403                 va_end(ap);
2404         }
2405
2406         return pi;
2407 }
2408
2409 /* Set the FT_OID value */
2410 static void
2411 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
2412 {
2413         GByteArray *bytes;
2414
2415         DISSECTOR_ASSERT(value_ptr != NULL);
2416
2417         bytes = g_byte_array_new();
2418         if (length > 0) {
2419                 g_byte_array_append(bytes, value_ptr, length);
2420         }
2421         fvalue_set(&fi->value, bytes, TRUE);
2422 }
2423
2424 static void
2425 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
2426 {
2427         proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
2428 }
2429
2430 static void
2431 proto_tree_set_uint64(field_info *fi, guint64 value)
2432 {
2433         fvalue_set_integer64(&fi->value, value);
2434 }
2435
2436 /*
2437  * NOTE: to support code written when proto_tree_add_item() took a
2438  * gboolean as its last argument, with FALSE meaning "big-endian"
2439  * and TRUE meaning "little-endian", we treat any non-zero value of
2440  * "encoding" as meaning "little-endian".
2441  */
2442 static void
2443 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start,
2444                           guint length, const guint encoding)
2445 {
2446         guint64 value = 0;
2447         guint8* b = (guint8 *)ep_tvb_memdup(tvb, start, length);
2448
2449         if (encoding) {
2450                 b += length;
2451                 switch (length) {
2452                         default: DISSECTOR_ASSERT_NOT_REACHED();
2453                         case 8: value <<= 8; value += *--b;
2454                         case 7: value <<= 8; value += *--b;
2455                         case 6: value <<= 8; value += *--b;
2456                         case 5: value <<= 8; value += *--b;
2457                         case 4: value <<= 8; value += *--b;
2458                         case 3: value <<= 8; value += *--b;
2459                         case 2: value <<= 8; value += *--b;
2460                         case 1: value <<= 8; value += *--b;
2461                                 break;
2462                 }
2463         } else {
2464                 switch (length) {
2465                         default: DISSECTOR_ASSERT_NOT_REACHED();
2466                         case 8: value <<= 8; value += *b++;
2467                         case 7: value <<= 8; value += *b++;
2468                         case 6: value <<= 8; value += *b++;
2469                         case 5: value <<= 8; value += *b++;
2470                         case 4: value <<= 8; value += *b++;
2471                         case 3: value <<= 8; value += *b++;
2472                         case 2: value <<= 8; value += *b++;
2473                         case 1: value <<= 8; value += *b++;
2474                                 break;
2475                 }
2476         }
2477
2478         proto_tree_set_uint64(fi, value);
2479 }
2480
2481 /* Add a FT_STRING or FT_STRINGZ to a proto_tree. Creates own copy of string,
2482  * and frees it when the proto_tree is destroyed. */
2483 proto_item *
2484 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2485                       gint length, const char* value)
2486 {
2487         proto_item        *pi;
2488         header_field_info *hfinfo;
2489
2490         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2491
2492         DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
2493
2494         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2495         DISSECTOR_ASSERT(length >= 0);
2496         proto_tree_set_string(PNODE_FINFO(pi), value);
2497
2498         return pi;
2499 }
2500
2501 proto_item *
2502 proto_tree_add_unicode_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2503                       gint length, const char* value)
2504 {
2505         DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
2506         return proto_tree_add_string_format_value(tree, hfindex, tvb, start, length, value, "%s", value);
2507 }
2508
2509 proto_item *
2510 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2511                                    gint start, gint length, const char* value,
2512                                    const char *format,
2513                                    ...)
2514 {
2515         proto_item        *pi;
2516         va_list            ap;
2517
2518         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
2519         if (pi != tree) {
2520                 va_start(ap, format);
2521                 proto_tree_set_representation_value(pi, format, ap);
2522                 va_end(ap);
2523         }
2524
2525         return pi;
2526 }
2527
2528 proto_item *
2529 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2530                              gint start, gint length, const char* value,
2531                              const char *format, ...)
2532 {
2533         proto_item        *pi;
2534         va_list            ap;
2535
2536         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
2537         if (pi != tree) {
2538                 TRY_TO_FAKE_THIS_REPR(pi);
2539
2540                 va_start(ap, format);
2541                 proto_tree_set_representation(pi, format, ap);
2542                 va_end(ap);
2543         }
2544
2545         return pi;
2546 }
2547
2548 /* Appends string data to a FT_STRING or FT_STRINGZ, allowing progressive
2549  * field info update instead of only updating the representation as does
2550  * proto_item_append_text()
2551  */
2552 /* NOTE: this function will break with the TRY_TO_FAKE_THIS_ITEM()
2553  * speed optimization.
2554  * Currently only WSP use this function so it is not that bad but try to
2555  * avoid using this one if possible.
2556  * IF you must use this function you MUST also disable the
2557  * TRY_TO_FAKE_THIS_ITEM() optimization for your dissector/function
2558  * using proto_item_append_string().
2559  * Do that by faking that the tree is visible by calling
2560  * proto_tree_set_visible(tree, TRUE) (see packet-wsp.c)
2561  * BEFORE you create the item you are later going to use
2562  * proto_item_append_string() on.
2563  */
2564 void
2565 proto_item_append_string(proto_item *pi, const char *str)
2566 {
2567         field_info        *fi;
2568         header_field_info *hfinfo;
2569         const gchar       *old_str, *new_str;
2570
2571         if (!pi)
2572                 return;
2573         if (!*str)
2574                 return;
2575
2576         fi = PITEM_FINFO(pi);
2577         DISSECTOR_ASSERT_HINT(fi, "proto_tree_set_visible(tree, TRUE) should have been called previously");
2578
2579         hfinfo = fi->hfinfo;
2580         if (hfinfo->type == FT_PROTOCOL) {
2581                 /* TRY_TO_FAKE_THIS_ITEM() speed optimization: silently skip */
2582                 return;
2583         }
2584         DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
2585         old_str = (guint8 *)fvalue_get(&fi->value);
2586         if (old_str && old_str[0])
2587                 new_str = ep_strconcat(old_str, str, NULL);
2588         else
2589                 new_str = str;
2590         fvalue_set(&fi->value, (gpointer) new_str, FALSE);
2591 }
2592
2593 /* Set the FT_STRING value */
2594 static void
2595 proto_tree_set_string(field_info *fi, const char* value)
2596 {
2597         if (value) {
2598                 fvalue_set(&fi->value, (gpointer) value, FALSE);
2599         } else {
2600                 fvalue_set(&fi->value, (gpointer) "[ Null ]", FALSE);
2601         }
2602 }
2603
2604 static void
2605 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding)
2606 {
2607         gchar   *string;
2608
2609         if (length == -1) {
2610                 length = tvb_ensure_length_remaining(tvb, start);
2611         }
2612
2613         string = tvb_get_ephemeral_string_enc(tvb, start, length, encoding);
2614         proto_tree_set_string(fi, string);
2615 }
2616
2617
2618 /* Add a FT_AX25 to a proto_tree */
2619 proto_item *
2620 proto_tree_add_ax25(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2621                 const guint8* value)
2622 {
2623         proto_item              *pi;
2624         header_field_info       *hfinfo;
2625
2626         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2627
2628         DISSECTOR_ASSERT(hfinfo->type == FT_AX25);
2629
2630         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2631         proto_tree_set_ax25(PNODE_FINFO(pi), value);
2632
2633         return pi;
2634 }
2635
2636 /* Set the FT_AX25 value */
2637 static void
2638 proto_tree_set_ax25(field_info *fi, const guint8* value)
2639 {
2640         fvalue_set(&fi->value, (gpointer) value, FALSE);
2641 }
2642
2643 static void
2644 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
2645 {
2646         proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
2647 }
2648
2649 /* Set the FT_VINES value */
2650 static void
2651 proto_tree_set_vines(field_info *fi, const guint8* value)
2652 {
2653         fvalue_set(&fi->value, (gpointer) value, FALSE);
2654 }
2655
2656 static void
2657 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
2658 {
2659         proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
2660 }
2661
2662 /* Add a FT_ETHER to a proto_tree */
2663 proto_item *
2664 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2665                      gint length, const guint8* value)
2666 {
2667         proto_item        *pi;
2668         header_field_info *hfinfo;
2669
2670         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2671
2672         DISSECTOR_ASSERT(hfinfo->type == FT_ETHER);
2673
2674         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2675         proto_tree_set_ether(PNODE_FINFO(pi), value);
2676
2677         return pi;
2678 }
2679
2680 proto_item *
2681 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2682                                   gint start, gint length, const guint8* value,
2683                                   const char *format, ...)
2684 {
2685         proto_item        *pi;
2686         va_list            ap;
2687
2688         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
2689         if (pi != tree) {
2690                 va_start(ap, format);
2691                 proto_tree_set_representation_value(pi, format, ap);
2692                 va_end(ap);
2693         }
2694
2695         return pi;
2696 }
2697
2698 proto_item *
2699 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2700                             gint start, gint length, const guint8* value,
2701                             const char *format, ...)
2702 {
2703         proto_item        *pi;
2704         va_list            ap;
2705
2706         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
2707         if (pi != tree) {
2708                 TRY_TO_FAKE_THIS_REPR(pi);
2709
2710                 va_start(ap, format);
2711                 proto_tree_set_representation(pi, format, ap);
2712                 va_end(ap);
2713         }
2714
2715         return pi;
2716 }
2717
2718 /* Set the FT_ETHER value */
2719 static void
2720 proto_tree_set_ether(field_info *fi, const guint8* value)
2721 {
2722         fvalue_set(&fi->value, (gpointer) value, FALSE);
2723 }
2724
2725 static void
2726 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
2727 {
2728         proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
2729 }
2730
2731 /* Add a FT_BOOLEAN to a proto_tree */
2732 proto_item *
2733 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2734                        gint length, guint32 value)
2735 {
2736         proto_item        *pi;
2737         header_field_info *hfinfo;
2738
2739         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2740
2741         DISSECTOR_ASSERT(hfinfo->type == FT_BOOLEAN);
2742
2743         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2744         proto_tree_set_boolean(PNODE_FINFO(pi), value);
2745
2746         return pi;
2747 }
2748
2749 proto_item *
2750 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
2751                                     tvbuff_t *tvb, gint start, gint length,
2752                                     guint32 value, const char *format, ...)
2753 {
2754         proto_item        *pi;
2755         va_list            ap;
2756
2757         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
2758         if (pi != tree) {
2759                 va_start(ap, format);
2760                 proto_tree_set_representation_value(pi, format, ap);
2761                 va_end(ap);
2762         }
2763
2764         return pi;
2765 }
2766
2767 proto_item *
2768 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2769                               gint start, gint length, guint32 value,
2770                               const char *format, ...)
2771 {
2772         proto_item        *pi;
2773         va_list            ap;
2774
2775         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
2776         if (pi != tree) {
2777                 TRY_TO_FAKE_THIS_REPR(pi);
2778
2779                 va_start(ap, format);
2780                 proto_tree_set_representation(pi, format, ap);
2781                 va_end(ap);
2782         }
2783
2784         return pi;
2785 }
2786
2787 /* Set the FT_BOOLEAN value */
2788 static void
2789 proto_tree_set_boolean(field_info *fi, guint32 value)
2790 {
2791         proto_tree_set_uint(fi, value);
2792 }
2793
2794 /* Add a FT_FLOAT to a proto_tree */
2795 proto_item *
2796 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2797                      gint length, float value)
2798 {
2799         proto_item        *pi;
2800         header_field_info *hfinfo;
2801
2802         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2803
2804         DISSECTOR_ASSERT(hfinfo->type == FT_FLOAT);
2805
2806         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2807         proto_tree_set_float(PNODE_FINFO(pi), value);
2808
2809         return pi;
2810 }
2811
2812 proto_item *
2813 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2814                                   gint start, gint length, float value,
2815                                   const char *format, ...)
2816 {
2817         proto_item        *pi;
2818         va_list            ap;
2819
2820         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
2821         if (pi != tree) {
2822                 va_start(ap, format);
2823                 proto_tree_set_representation_value(pi, format, ap);
2824                 va_end(ap);
2825         }
2826
2827         return pi;
2828 }
2829
2830 proto_item *
2831 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2832                             gint start, gint length, float value,
2833                             const char *format, ...)
2834 {
2835         proto_item        *pi;
2836         va_list            ap;
2837
2838         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
2839         if (pi != tree) {
2840                 TRY_TO_FAKE_THIS_REPR(pi);
2841
2842                 va_start(ap, format);
2843                 proto_tree_set_representation(pi, format, ap);
2844                 va_end(ap);
2845         }
2846
2847         return pi;
2848 }
2849
2850 /* Set the FT_FLOAT value */
2851 static void
2852 proto_tree_set_float(field_info *fi, float value)
2853 {
2854         fvalue_set_floating(&fi->value, value);
2855 }
2856
2857 /* Add a FT_DOUBLE to a proto_tree */
2858 proto_item *
2859 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2860                       gint length, double value)
2861 {
2862         proto_item        *pi;
2863         header_field_info *hfinfo;
2864
2865         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2866
2867         DISSECTOR_ASSERT(hfinfo->type == FT_DOUBLE);
2868
2869         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2870         proto_tree_set_double(PNODE_FINFO(pi), value);
2871
2872         return pi;
2873 }
2874
2875 proto_item *
2876 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2877                                    gint start, gint length, double value,
2878                                    const char *format, ...)
2879 {
2880         proto_item        *pi;
2881         va_list            ap;
2882
2883         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
2884         if (pi != tree) {
2885                 va_start(ap, format);
2886                 proto_tree_set_representation_value(pi, format, ap);
2887                 va_end(ap);
2888         }
2889
2890         return pi;
2891 }
2892
2893 proto_item *
2894 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2895                              gint start, gint length, double value,
2896                              const char *format, ...)
2897 {
2898         proto_item        *pi;
2899         va_list            ap;
2900
2901         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
2902         if (pi != tree) {
2903                 TRY_TO_FAKE_THIS_REPR(pi);
2904
2905                 va_start(ap, format);
2906                 proto_tree_set_representation(pi, format, ap);
2907                 va_end(ap);
2908         }
2909
2910         return pi;
2911 }
2912
2913 /* Set the FT_DOUBLE value */
2914 static void
2915 proto_tree_set_double(field_info *fi, double value)
2916 {
2917         fvalue_set_floating(&fi->value, value);
2918 }
2919
2920 /* Add FT_UINT{8,16,24,32} to a proto_tree */
2921 proto_item *
2922 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2923                     gint length, guint32 value)
2924 {
2925         proto_item        *pi = NULL;
2926         header_field_info *hfinfo;
2927
2928         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2929
2930         switch (hfinfo->type) {
2931                 case FT_UINT8:
2932                 case FT_UINT16:
2933                 case FT_UINT24:
2934                 case FT_UINT32:
2935                 case FT_FRAMENUM:
2936                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2937                         proto_tree_set_uint(PNODE_FINFO(pi), value);
2938                         break;
2939
2940                 default:
2941                         DISSECTOR_ASSERT_NOT_REACHED();
2942         }
2943
2944         return pi;
2945 }
2946
2947 proto_item *
2948 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2949                                  gint start, gint length, guint32 value,
2950                                  const char *format, ...)
2951 {
2952         proto_item        *pi;
2953         va_list            ap;
2954
2955         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
2956         if (pi != tree) {
2957                 va_start(ap, format);
2958                 proto_tree_set_representation_value(pi, format, ap);
2959                 va_end(ap);
2960         }
2961
2962         return pi;
2963 }
2964
2965 proto_item *
2966 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2967                            gint start, gint length, guint32 value,
2968                            const char *format, ...)
2969 {
2970         proto_item        *pi;
2971         va_list            ap;
2972
2973         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
2974         if (pi != tree) {
2975                 TRY_TO_FAKE_THIS_REPR(pi);
2976
2977                 va_start(ap, format);
2978                 proto_tree_set_representation(pi, format, ap);
2979                 va_end(ap);
2980         }
2981
2982         return pi;
2983 }
2984
2985 /* Set the FT_UINT{8,16,24,32} value */
2986 static void
2987 proto_tree_set_uint(field_info *fi, guint32 value)
2988 {
2989         header_field_info *hfinfo;
2990         guint32            integer;
2991
2992         hfinfo = fi->hfinfo;
2993         integer = value;
2994
2995         if (hfinfo->bitmask) {
2996                 /* Mask out irrelevant portions */
2997                 integer &= hfinfo->bitmask;
2998
2999                 /* Shift bits */
3000                 integer >>= hfinfo_bitshift(hfinfo);
3001         }
3002
3003         fvalue_set_uinteger(&fi->value, integer);
3004 }
3005
3006 /* Add FT_UINT64 to a proto_tree */
3007 proto_item *
3008 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3009                       gint length, guint64 value)
3010 {
3011         proto_item        *pi;
3012         header_field_info *hfinfo;
3013
3014         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3015
3016         DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
3017
3018         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3019         proto_tree_set_uint64(PNODE_FINFO(pi), value);
3020
3021         return pi;
3022 }
3023
3024 proto_item *
3025 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3026                                    gint start, gint length, guint64 value,
3027                                    const char *format, ...)
3028 {
3029         proto_item        *pi;
3030         va_list            ap;
3031
3032         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
3033         if (pi != tree) {
3034                 va_start(ap, format);
3035                 proto_tree_set_representation_value(pi, format, ap);
3036                 va_end(ap);
3037         }
3038
3039         return pi;
3040 }
3041
3042 proto_item *
3043 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3044                              gint start, gint length, guint64 value,
3045                              const char *format, ...)
3046 {
3047         proto_item        *pi;
3048         va_list            ap;
3049
3050         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
3051         if (pi != tree) {
3052                 TRY_TO_FAKE_THIS_REPR(pi);
3053
3054                 va_start(ap, format);
3055                 proto_tree_set_representation(pi, format, ap);
3056                 va_end(ap);
3057         }
3058
3059         return pi;
3060 }
3061
3062 /* Add FT_INT{8,16,24,32} to a proto_tree */
3063 proto_item *
3064 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3065                    gint length, gint32 value)
3066 {
3067         proto_item        *pi = NULL;
3068         header_field_info *hfinfo;
3069
3070         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3071
3072         switch (hfinfo->type) {
3073                 case FT_INT8:
3074                 case FT_INT16:
3075                 case FT_INT24:
3076                 case FT_INT32:
3077                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3078                         proto_tree_set_int(PNODE_FINFO(pi), value);
3079                         break;
3080
3081                 default:
3082                         DISSECTOR_ASSERT_NOT_REACHED();
3083         }
3084
3085         return pi;
3086 }
3087
3088 proto_item *
3089 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3090                                 gint start, gint length, gint32 value,
3091                                 const char *format, ...)
3092 {
3093         proto_item  *pi;
3094         va_list      ap;
3095
3096         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
3097         if (pi != tree) {
3098                 va_start(ap, format);
3099                 proto_tree_set_representation_value(pi, format, ap);
3100                 va_end(ap);
3101         }
3102
3103         return pi;
3104 }
3105
3106 proto_item *
3107 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3108                           gint start, gint length, gint32 value,
3109                           const char *format, ...)
3110 {
3111         proto_item *pi;
3112         va_list     ap;
3113
3114         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
3115         if (pi != tree) {
3116                 TRY_TO_FAKE_THIS_REPR(pi);
3117
3118                 va_start(ap, format);
3119                 proto_tree_set_representation(pi, format, ap);
3120                 va_end(ap);
3121         }
3122
3123         return pi;
3124 }
3125
3126 /* Set the FT_INT{8,16,24,32} value */
3127 static void
3128 proto_tree_set_int(field_info *fi, gint32 value)
3129 {
3130         header_field_info *hfinfo;
3131         guint32            integer;
3132         gint               no_of_bits;
3133
3134         hfinfo = fi->hfinfo;
3135         integer = (guint32) value;
3136
3137         if (hfinfo->bitmask) {
3138                 /* Mask out irrelevant portions */
3139                 integer &= hfinfo->bitmask;
3140
3141                 /* Shift bits */
3142                 integer >>= hfinfo_bitshift(hfinfo);
3143
3144                 no_of_bits = swar_count_bits(hfinfo->bitmask);
3145                 if (integer & (1 << (no_of_bits-1)))
3146                         integer |= (-1 << no_of_bits);
3147         }
3148
3149         fvalue_set_sinteger(&fi->value, integer);
3150 }
3151
3152 /* Add FT_INT64 to a proto_tree */
3153 proto_item *
3154 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3155                      gint length, gint64 value)
3156 {
3157         proto_item        *pi;
3158         header_field_info *hfinfo;
3159
3160         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3161
3162         DISSECTOR_ASSERT(hfinfo->type == FT_INT64);
3163
3164         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3165         proto_tree_set_uint64(PNODE_FINFO(pi), (guint64)value);
3166
3167         return pi;
3168 }
3169
3170 proto_item *
3171 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3172                                   gint start, gint length, gint64 value,
3173                                   const char *format, ...)
3174 {
3175         proto_item        *pi;
3176         va_list            ap;
3177
3178         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
3179         if (pi != tree) {
3180                 va_start(ap, format);
3181                 proto_tree_set_representation_value(pi, format, ap);
3182                 va_end(ap);
3183         }
3184
3185         return pi;
3186 }
3187
3188 proto_item *
3189 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3190                            gint start, gint length, gint64 value,
3191                            const char *format, ...)
3192 {
3193         proto_item        *pi;
3194         va_list            ap;
3195
3196         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
3197         if (pi != tree) {
3198                 TRY_TO_FAKE_THIS_REPR(pi);
3199
3200                 va_start(ap, format);
3201                 proto_tree_set_representation(pi, format, ap);
3202                 va_end(ap);
3203         }
3204
3205         return pi;
3206 }
3207 /* Add a FT_EUI64 to a proto_tree */
3208 proto_item *
3209 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3210                      gint length, const guint64 value)
3211 {
3212         proto_item        *pi;
3213         header_field_info *hfinfo;
3214
3215         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3216
3217         DISSECTOR_ASSERT(hfinfo->type == FT_EUI64);
3218
3219         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3220         proto_tree_set_eui64(PNODE_FINFO(pi), value);
3221
3222         return pi;
3223 }
3224
3225 proto_item *
3226 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3227                                   gint start, gint length, const guint64 value,
3228                                   const char *format, ...)
3229 {
3230         proto_item        *pi;
3231         va_list            ap;
3232
3233         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
3234         if (pi != tree) {
3235                 va_start(ap, format);
3236                 proto_tree_set_representation_value(pi, format, ap);
3237                 va_end(ap);
3238         }
3239
3240         return pi;
3241 }
3242
3243 proto_item *
3244 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3245                             gint start, gint length, const guint64 value,
3246                             const char *format, ...)
3247 {
3248         proto_item        *pi;
3249         va_list            ap;
3250
3251         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
3252         if (pi != tree) {
3253                 TRY_TO_FAKE_THIS_REPR(pi);
3254
3255                 va_start(ap, format);
3256                 proto_tree_set_representation(pi, format, ap);
3257                 va_end(ap);
3258         }
3259
3260         return pi;
3261 }
3262
3263 /* Set the FT_EUI64 value */
3264 static void
3265 proto_tree_set_eui64(field_info *fi, const guint64 value)
3266 {
3267         fvalue_set_integer64(&fi->value, value);
3268 }
3269 static void
3270 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
3271 {
3272         if (encoding)
3273         {
3274                 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
3275         } else {
3276                 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
3277         }
3278 }
3279
3280 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
3281 static proto_item *
3282 proto_tree_add_node(proto_tree *tree, field_info *fi)
3283 {
3284         proto_node *pnode, *tnode, *sibling;
3285         field_info *tfi;
3286
3287         /*
3288          * Make sure "tree" is ready to have subtrees under it, by
3289          * checking whether it's been given an ett_ value.
3290          *
3291          * "PNODE_FINFO(tnode)" may be null; that's the case for the root
3292          * node of the protocol tree.  That node is not displayed,
3293          * so it doesn't need an ett_ value to remember whether it
3294          * was expanded.
3295          */
3296         tnode = tree;
3297         tfi = PNODE_FINFO(tnode);
3298         if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
3299                 REPORT_DISSECTOR_BUG(ep_strdup_printf("\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
3300                                      fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
3301                 /* XXX - is it safe to continue here? */
3302         }
3303
3304         PROTO_NODE_NEW(pnode);
3305         pnode->parent = tnode;
3306         PNODE_FINFO(pnode) = fi;
3307         pnode->tree_data = PTREE_DATA(tree);
3308
3309         if (tnode->last_child != NULL) {
3310                 sibling = tnode->last_child;
3311                 DISSECTOR_ASSERT(sibling->next == NULL);
3312                 sibling->next = pnode;
3313         } else
3314                 tnode->first_child = pnode;
3315         tnode->last_child = pnode;
3316
3317         tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
3318
3319         return (proto_item *)pnode;
3320 }
3321
3322
3323 /* Generic way to allocate field_info and add to proto_tree.
3324  * Sets *pfi to address of newly-allocated field_info struct */
3325 static proto_item *
3326 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
3327                   gint *length)
3328 {
3329         proto_item *pi;
3330         field_info *fi;
3331
3332         fi = alloc_field_info(tree, hfinfo, tvb, start, length);
3333         pi = proto_tree_add_node(tree, fi);
3334
3335         return pi;
3336 }
3337
3338
3339 static void
3340 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
3341                    gint *item_length)
3342 {
3343         gint length_remaining;
3344
3345         /*
3346          * We only allow a null tvbuff if the item has a zero length,
3347          * i.e. if there's no data backing it.
3348          */
3349         DISSECTOR_ASSERT(tvb != NULL || *length == 0);
3350
3351         /*
3352          * XXX - in some protocols, there are 32-bit unsigned length
3353          * fields, so lengths in protocol tree and tvbuff routines
3354          * should really be unsigned.  We should have, for those
3355          * field types for which "to the end of the tvbuff" makes sense,
3356          * additional routines that take no length argument and
3357          * add fields that run to the end of the tvbuff.
3358          */
3359         if (*length == -1) {
3360                 /*
3361                  * For FT_NONE, FT_PROTOCOL, FT_BYTES, and FT_STRING fields,
3362                  * a length of -1 means "set the length to what remains in
3363                  * the tvbuff".
3364                  *
3365                  * The assumption is either that
3366                  *
3367                  *      1) the length of the item can only be determined
3368                  *         by dissection (typically true of items with
3369                  *         subitems, which are probably FT_NONE or
3370                  *         FT_PROTOCOL)
3371                  *
3372                  * or
3373                  *
3374                  *      2) if the tvbuff is "short" (either due to a short
3375                  *         snapshot length or due to lack of reassembly of
3376                  *         fragments/segments/whatever), we want to display
3377                  *         what's available in the field (probably FT_BYTES
3378                  *         or FT_STRING) and then throw an exception later
3379                  *
3380                  * or
3381                  *
3382                  *      3) the field is defined to be "what's left in the
3383                  *         packet"
3384                  *
3385                  * so we set the length to what remains in the tvbuff so
3386                  * that, if we throw an exception while dissecting, it
3387                  * has what is probably the right value.
3388                  *
3389                  * For FT_STRINGZ, it means "the string is null-terminated,
3390                  * not null-padded; set the length to the actual length
3391                  * of the string", and if the tvbuff if short, we just
3392                  * throw an exception.
3393                  *
3394                  * It's not valid for any other type of field.
3395                  */
3396     &nb