2 * Routines for protocol tree
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #ifdef NEED_SNPRINTF_H
36 # include "snprintf.h"
41 #include "addr_resolv.h"
43 #include "ipv6-utils.h"
45 #include "epan_dissect.h"
49 #define cVALS(x) (const value_string*)(x)
52 proto_tree_free_node(proto_node *node, gpointer data);
54 static void fill_label_boolean(field_info *fi, gchar *label_str);
55 static void fill_label_uint(field_info *fi, gchar *label_str);
56 static void fill_label_uint64(field_info *fi, gchar *label_str);
57 static void fill_label_enumerated_uint(field_info *fi, gchar *label_str);
58 static void fill_label_enumerated_bitfield(field_info *fi, gchar *label_str);
59 static void fill_label_numeric_bitfield(field_info *fi, gchar *label_str);
60 static void fill_label_int(field_info *fi, gchar *label_str);
61 static void fill_label_int64(field_info *fi, gchar *label_str);
62 static void fill_label_enumerated_int(field_info *fi, gchar *label_str);
64 int hfinfo_bitwidth(header_field_info *hfinfo);
65 static char* hfinfo_uint_vals_format(header_field_info *hfinfo);
66 static char* hfinfo_uint_format(header_field_info *hfinfo);
67 static char* hfinfo_uint64_format(header_field_info *hfinfo);
68 static char* hfinfo_int_vals_format(header_field_info *hfinfo);
69 static char* hfinfo_int_format(header_field_info *hfinfo);
70 static char* hfinfo_int64_format(header_field_info *hfinfo);
73 proto_tree_add_node(proto_tree *tree, field_info *fi);
76 alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb,
77 gint start, gint *length);
80 proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb,
81 gint start, gint *length, field_info **pfi);
84 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
87 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb);
89 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
91 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
93 proto_tree_set_time(field_info *fi, nstime_t *value_ptr);
95 proto_tree_set_string(field_info *fi, const char* value, gboolean);
97 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
99 proto_tree_set_ether(field_info *fi, const guint8* value);
101 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
103 proto_tree_set_ipxnet(field_info *fi, guint32 value);
105 proto_tree_set_ipv4(field_info *fi, guint32 value);
107 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
109 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start);
111 proto_tree_set_boolean(field_info *fi, guint32 value);
113 proto_tree_set_float(field_info *fi, float value);
115 proto_tree_set_double(field_info *fi, double value);
117 proto_tree_set_uint(field_info *fi, guint32 value);
119 proto_tree_set_int(field_info *fi, gint32 value);
121 proto_tree_set_uint64(field_info *fi, guint64 value);
123 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian);
125 static int proto_register_field_init(header_field_info *hfinfo, int parent);
127 /* Comparision function for tree insertion. A wrapper around strcmp() */
128 static int g_strcmp(gconstpointer a, gconstpointer b);
130 /* special-case header field used within proto.c */
131 int hf_text_only = -1;
133 /* Structure for information about a protocol */
135 char *name; /* long description */
136 char *short_name; /* short description */
137 char *filter_name; /* name of this protocol in filters */
138 int proto_id; /* field ID for this protocol */
139 GList *fields; /* fields for this protocol */
140 GList *last_field; /* pointer to end of list of fields */
141 gboolean is_enabled; /* TRUE if protocol is enabled */
142 gboolean can_toggle; /* TRUE if is_enabled can be changed */
145 /* List of all protocols */
146 static GList *protocols;
148 #define INITIAL_NUM_PROTOCOL_HFINFO 200
151 /* Contains information about protocols and header fields. Used when
152 * dissectors register their data */
153 static GMemChunk *gmc_hfinfo = NULL;
155 /* Contains information about a field when a dissector calls
156 * proto_tree_add_item. */
157 SLAB_ITEM_TYPE_DEFINE(field_info)
158 static SLAB_FREE_LIST_DEFINE(field_info)
159 static field_info *field_info_tmp=NULL;
160 #define FIELD_INFO_NEW(fi) \
161 SLAB_ALLOC(fi, field_info)
162 #define FIELD_INFO_FREE(fi) \
163 SLAB_FREE(fi, field_info)
167 /* Contains the space for proto_nodes. */
168 SLAB_ITEM_TYPE_DEFINE(proto_node)
169 static SLAB_FREE_LIST_DEFINE(proto_node)
170 #define PROTO_NODE_NEW(node) \
171 SLAB_ALLOC(node, proto_node) \
172 node->first_child = NULL; \
173 node->last_child = NULL; \
176 #define PROTO_NODE_FREE(node) \
177 SLAB_FREE(node, proto_node)
181 /* String space for protocol and field items for the GUI */
182 SLAB_ITEM_TYPE_DEFINE(item_label_t)
183 static SLAB_FREE_LIST_DEFINE(item_label_t)
184 #define ITEM_LABEL_NEW(il) \
185 SLAB_ALLOC(il, item_label_t)
186 #define ITEM_LABEL_FREE(il) \
187 SLAB_FREE(il, item_label_t)
191 /* List which stores protocols and fields that have been registered */
192 typedef struct _gpa_hfinfo_t {
194 guint32 allocated_len;
195 header_field_info **hfi;
197 gpa_hfinfo_t gpa_hfinfo;
199 /* Balanced tree of abbreviations and IDs */
200 static GTree *gpa_name_tree = NULL;
202 /* Points to the first element of an array of Booleans, indexed by
203 a subtree item type; that array element is TRUE if subtrees of
204 an item of that type are to be expanded. */
205 gboolean *tree_is_expanded;
207 /* Number of elements in that array. */
210 /* initialize data structures and register protocols and fields */
212 proto_init(const char *plugin_dir
217 void (register_all_protocols)(void),
218 void (register_all_protocol_handoffs)(void))
220 static hf_register_info hf[] = {
222 { "", "", FT_NONE, BASE_NONE, NULL, 0x0,
228 gmc_hfinfo = g_mem_chunk_new("gmc_hfinfo",
229 sizeof(header_field_info),
230 INITIAL_NUM_PROTOCOL_HFINFO * sizeof(header_field_info),
234 gpa_hfinfo.allocated_len=0;
236 gpa_name_tree = g_tree_new(g_strcmp);
238 /* Initialize the ftype subsystem */
241 /* Register one special-case FT_TEXT_ONLY field for use when
242 converting ethereal to new-style proto_tree. These fields
243 are merely strings on the GUI tree; they are not filterable */
244 proto_register_field_array(-1, hf, array_length(hf));
246 /* Have each built-in dissector register its protocols, fields,
247 dissector tables, and dissectors to be called through a
248 handle, and do whatever one-time initialization it needs to
250 register_all_protocols();
253 /* Now scan for plugins and load all the ones we find, calling
254 their register routines to do the stuff described above. */
255 init_plugins(plugin_dir);
258 /* Now call the "handoff registration" routines of all built-in
259 dissectors; those routines register the dissector in other
260 dissectors' handoff tables, and fetch any dissector handles
262 register_all_protocol_handoffs();
265 /* Now do the same with plugins. */
266 register_all_plugin_handoffs();
269 /* We've assigned all the subtree type values; allocate the array
270 for them, and zero it out. */
271 tree_is_expanded = g_malloc(num_tree_types*sizeof (gint *));
272 memset(tree_is_expanded, 0, num_tree_types*sizeof (gint *));
275 /* String comparison func for dfilter_token GTree */
277 g_strcmp(gconstpointer a, gconstpointer b)
279 return strcmp((const char*)a, (const char*)b);
285 /* Free the abbrev/ID GTree */
287 g_tree_destroy(gpa_name_tree);
288 gpa_name_tree = NULL;
292 g_mem_chunk_destroy(gmc_hfinfo);
294 if(gpa_hfinfo.allocated_len){
296 gpa_hfinfo.allocated_len=0;
297 g_free(gpa_hfinfo.hfi);
300 if (tree_is_expanded != NULL)
301 g_free(tree_is_expanded);
305 typedef gboolean (*proto_tree_traverse_func)(proto_node *, gpointer);
308 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
311 proto_node *pnode = tree;
315 if (func(pnode, data))
318 child = pnode->first_child;
319 while (child != NULL) {
321 * The routine we call might modify the child, e.g. by
322 * freeing it, so we get the child's successor before
323 * calling that routine.
326 child = current->next;
327 if (proto_tree_traverse_pre_order((proto_tree *)current, func,
336 proto_tree_traverse_in_order(proto_tree *tree, proto_tree_traverse_func func,
339 proto_node *pnode = tree;
343 child = pnode->first_child;
346 * The routine we call might modify the child, e.g. by
347 * freeing it, so we get the child's successor before
348 * calling that routine.
351 child = current->next;
353 if (proto_tree_traverse_in_order((proto_tree *)current, func,
357 if (func(pnode, data))
360 while (child != NULL) {
362 * The routine we call might modify the child, e.g. by
363 * freeing it, so we get the child's successor before
364 * calling that routine.
367 child = current->next;
368 if (proto_tree_traverse_in_order((proto_tree *)current,
373 if (func(pnode, data))
381 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
384 proto_node *node = tree;
387 node = node->first_child;
388 while (node != NULL) {
390 node = current->next;
391 func((proto_tree *)current, data);
395 /* frees the resources that the dissection a proto_tree uses */
397 proto_tree_free(proto_tree *tree)
399 proto_tree_traverse_in_order(tree, proto_tree_free_node, NULL);
403 free_GPtrArray_value(gpointer key _U_, gpointer value, gpointer user_data _U_)
405 GPtrArray *ptrs = value;
407 g_ptr_array_free(ptrs, TRUE);
411 free_node_tree_data(tree_data_t *tree_data)
413 /* Free all the GPtrArray's in the interesting_hfids hash. */
414 g_hash_table_foreach(tree_data->interesting_hfids,
415 free_GPtrArray_value, NULL);
417 /* And then destroy the hash. */
418 g_hash_table_destroy(tree_data->interesting_hfids);
420 /* And finally the tree_data_t itself. */
424 #define FREE_NODE_FIELD_INFO(finfo) \
426 ITEM_LABEL_FREE(finfo->rep); \
428 FVALUE_CLEANUP(&finfo->value); \
429 FIELD_INFO_FREE(finfo);
432 proto_tree_free_node(proto_node *node, gpointer data _U_)
434 field_info *finfo = PITEM_FINFO(node);
437 /* This is the root node. Destroy the per-tree data.
438 * There is no field_info to destroy. */
439 free_node_tree_data(PTREE_DATA(node));
442 /* This is a child node. Don't free the per-tree data, but
443 * do free the field_info data. */
444 FREE_NODE_FIELD_INFO(finfo);
447 /* Free the proto_node. */
448 PROTO_NODE_FREE(node);
450 return FALSE; /* FALSE = do not end traversal of protocol tree */
453 /* Is the parsing being done for a visible proto_tree or an invisible one?
454 * By setting this correctly, the proto_tree creation is sped up by not
455 * having to call vsnprintf and copy strings around.
458 proto_tree_set_visible(proto_tree *tree, gboolean visible)
460 PTREE_DATA(tree)->visible = visible;
463 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
464 g_assert((guint)hfindex < gpa_hfinfo.len); \
465 hfinfo=gpa_hfinfo.hfi[hfindex];
467 /* Finds a record in the hf_info_records array by id. */
469 proto_registrar_get_nth(guint hfindex)
471 register header_field_info *hfinfo;
473 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
477 /* Finds a record in the hf_info_records array by name.
480 proto_registrar_get_byname(char *field_name)
482 g_assert(field_name != NULL);
483 return g_tree_lookup(gpa_name_tree, field_name);
486 /* Add a text-only node, leaving it to our caller to fill the text in */
488 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
492 pi = proto_tree_add_pi(tree, hf_text_only, tvb, start, &length, NULL);
499 /* Add a text-only node to the proto_tree */
501 proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
502 const char *format, ...)
507 pi = proto_tree_add_text_node(tree, tvb, start, length);
511 va_start(ap, format);
512 proto_tree_set_representation(pi, format, ap);
518 /* Add a text-only node to the proto_tree (va_list version) */
520 proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start,
521 gint length, const char *format, va_list ap)
525 pi = proto_tree_add_text_node(tree, tvb, start, length);
529 proto_tree_set_representation(pi, format, ap);
534 /* Add a text-only node for debugging purposes. The caller doesn't need
535 * to worry about tvbuff, start, or length. Debug message gets sent to
538 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
543 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
547 va_start(ap, format);
548 proto_tree_set_representation(pi, format, ap);
558 get_uint_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian)
565 value = tvb_get_guint8(tvb, offset);
569 value = little_endian ? tvb_get_letohs(tvb, offset)
570 : tvb_get_ntohs(tvb, offset);
574 value = little_endian ? tvb_get_letoh24(tvb, offset)
575 : tvb_get_ntoh24(tvb, offset);
579 value = little_endian ? tvb_get_letohl(tvb, offset)
580 : tvb_get_ntohl(tvb, offset);
584 g_assert_not_reached();
592 get_int_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian)
599 value = (gint8)tvb_get_guint8(tvb, offset);
603 value = (gint16) (little_endian ? tvb_get_letohs(tvb, offset)
604 : tvb_get_ntohs(tvb, offset));
608 value = little_endian ? tvb_get_letoh24(tvb, offset)
609 : tvb_get_ntoh24(tvb, offset);
610 if (value & 0x00800000) {
611 /* Sign bit is set; sign-extend it. */
617 value = little_endian ? tvb_get_letohl(tvb, offset)
618 : tvb_get_ntohl(tvb, offset);
622 g_assert_not_reached();
629 /* Add an item to a proto_tree, using the text label registered to that item;
630 the item is extracted from the tvbuff handed to it. */
632 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
633 gint start, gint length, gboolean little_endian)
647 new_fi = alloc_field_info(tree, hfindex, tvb, start, &length);
652 /* there is a possibility here that we might raise an exception
653 * and thus would lose track of the field_info.
654 * store it in a temp so that if we come here again we can reclaim
655 * the field_info without leaking memory.
657 /* XXX this only keeps track of one field_info struct,
658 if we ever go multithreaded for calls to this function
659 we have to change this code to use per thread variable.
662 /* oops, last one we got must have been lost due
664 * good thing we saved it, now we can reverse the
665 * memory leak and reclaim it.
667 SLAB_FREE(field_info_tmp, field_info);
669 /* we might throw an exception, keep track of this one
670 * across the "dangerous" section below.
672 field_info_tmp=new_fi;
674 switch(new_fi->hfinfo->type) {
676 /* no value to set for FT_NONE */
680 proto_tree_set_protocol_tvb(new_fi, tvb);
684 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
688 n = get_uint_value(tvb, start, length, little_endian);
689 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
691 /* Instead of calling proto_item_set_len(), since we don't yet
692 * have a proto_item, we set the field_info's length ourselves. */
693 new_fi->length = n + length;
697 proto_tree_set_boolean(new_fi,
698 get_uint_value(tvb, start, length, little_endian));
701 /* XXX - make these just FT_UINT? */
706 proto_tree_set_uint(new_fi,
707 get_uint_value(tvb, start, length, little_endian));
712 g_assert(length == 8);
713 proto_tree_set_uint64_tvb(new_fi, tvb, start, little_endian);
716 /* XXX - make these just FT_INT? */
721 proto_tree_set_int(new_fi,
722 get_int_value(tvb, start, length, little_endian));
726 g_assert(length == 4);
727 tvb_memcpy(tvb, (guint8 *)&value, start, 4);
728 proto_tree_set_ipv4(new_fi, little_endian ? GUINT32_SWAP_LE_BE(value) : value);
732 g_assert(length == 4);
733 proto_tree_set_ipxnet(new_fi,
734 get_uint_value(tvb, start, 4, FALSE));
738 g_assert(length == 16);
739 proto_tree_set_ipv6_tvb(new_fi, tvb, start);
743 g_assert(length == 6);
744 proto_tree_set_ether_tvb(new_fi, tvb, start);
748 g_assert(length == 4);
750 floatval = tvb_get_letohieee_float(tvb, start);
752 floatval = tvb_get_ntohieee_float(tvb, start);
753 proto_tree_set_float(new_fi, floatval);
757 g_assert(length == 8);
759 doubleval = tvb_get_letohieee_double(tvb, start);
761 doubleval = tvb_get_ntohieee_double(tvb, start);
762 proto_tree_set_double(new_fi, doubleval);
766 /* This g_strdup'ed memory is freed in proto_tree_free_node() */
767 proto_tree_set_string_tvb(new_fi, tvb, start, length);
771 if (length != 0) { /* XXX - Should we throw an exception instead? */
772 /* Instead of calling proto_item_set_len(),
773 * since we don't yet have a proto_item, we
774 * set the field_info's length ourselves.
776 * XXX - our caller can't use that length to
777 * advance an offset unless they arrange that
778 * there always be a protocol tree into which
779 * we're putting this item.
782 /* This can throw an exception */
783 length = tvb_strsize(tvb, start);
785 /* This g_malloc'ed memory is freed
786 in proto_tree_free_node() */
787 string = g_malloc(length);
789 tvb_memcpy(tvb, string, start, length);
790 new_fi->length = length;
793 /* In this case, length signifies
794 * the length of the string.
796 * This could either be a null-padded
797 * string, which doesn't necessarily
798 * have a '\0' at the end, or a
799 * null-terminated string, with a
800 * trailing '\0'. (Yes, there are
801 * cases where you have a string
802 * that's both counted and null-
805 * In the first case, we must
806 * allocate a buffer of length
807 * "length+1", to make room for
810 * In the second case, we don't
811 * assume that there is a trailing
812 * '\0' there, as the packet might
813 * be malformed. (XXX - should we
814 * throw an exception if there's no
815 * trailing '\0'?) Therefore, we
816 * allocate a buffer of length
817 * "length+1", and put in a trailing
818 * '\0', just to be safe.
820 * (XXX - this would change if
821 * we made string values counted
822 * rather than null-terminated.)
825 /* This g_malloc'ed memory is freed
826 * in proto_tree_free_node() */
827 string = tvb_get_string(tvb, start,
829 new_fi->length = length;
831 proto_tree_set_string(new_fi, string, TRUE);
836 /* This g_strdup'ed memory is freed in proto_tree_free_node() */
837 n = get_uint_value(tvb, start, length, little_endian);
838 proto_tree_set_string_tvb(new_fi, tvb, start + length, n);
840 /* Instead of calling proto_item_set_len(), since we
841 * don't yet have a proto_item, we set the
842 * field_info's length ourselves.
844 * XXX - our caller can't use that length to
845 * advance an offset unless they arrange that
846 * there always be a protocol tree into which
847 * we're putting this item.
849 new_fi->length = n + length;
853 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
854 new_fi->hfinfo->type,
855 ftype_name(new_fi->hfinfo->type));
856 g_assert_not_reached();
860 /* Don't add new node to proto_tree until now so that any exceptions
861 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
862 pi = proto_tree_add_node(tree, new_fi);
864 /* we did not raise an exception so we dont have to remember this
865 * field_info struct any more.
869 /* If the proto_tree wants to keep a record of this finfo
870 * for quick lookup, then record it. */
871 hash = PTREE_DATA(tree)->interesting_hfids;
872 ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
874 g_ptr_array_add(ptrs, new_fi);
881 proto_tree_add_item_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb,
882 gint start, gint length, gboolean little_endian)
886 pi = proto_tree_add_item(tree, hfindex, tvb, start, length, little_endian);
890 PROTO_ITEM_SET_HIDDEN(pi);
896 /* Add a FT_NONE to a proto_tree */
898 proto_tree_add_none_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
899 gint length, const char *format, ...)
903 header_field_info *hfinfo;
908 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
909 g_assert(hfinfo->type == FT_NONE);
911 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, NULL);
913 va_start(ap, format);
914 proto_tree_set_representation(pi, format, ap);
917 /* no value to set for FT_NONE */
923 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
925 fvalue_set(&fi->value, tvb, TRUE);
928 /* Add a FT_PROTOCOL to a proto_tree */
930 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
931 gint length, const char *format, ...)
935 header_field_info *hfinfo;
941 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
942 g_assert(hfinfo->type == FT_PROTOCOL);
944 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
946 va_start(ap, format);
947 proto_tree_set_representation(pi, format, ap);
951 proto_tree_set_protocol_tvb(new_fi, tvb);
954 proto_tree_set_protocol_tvb(new_fi, NULL);
960 /* Add a FT_BYTES to a proto_tree */
962 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
963 gint length, const guint8 *start_ptr)
967 header_field_info *hfinfo;
972 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
973 g_assert(hfinfo->type == FT_BYTES);
975 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
976 proto_tree_set_bytes(new_fi, start_ptr, length);
982 proto_tree_add_bytes_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
983 gint length, const guint8 *start_ptr)
987 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
991 PROTO_ITEM_SET_HIDDEN(pi);
997 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
998 gint length, const guint8 *start_ptr, const char *format, ...)
1003 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
1007 va_start(ap, format);
1008 proto_tree_set_representation(pi, format, ap);
1015 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
1019 bytes = g_byte_array_new();
1021 g_byte_array_append(bytes, start_ptr, length);
1023 fvalue_set(&fi->value, bytes, TRUE);
1028 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
1030 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
1033 /* Add a FT_*TIME to a proto_tree */
1035 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1036 nstime_t *value_ptr)
1040 header_field_info *hfinfo;
1045 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1046 g_assert(hfinfo->type == FT_ABSOLUTE_TIME ||
1047 hfinfo->type == FT_RELATIVE_TIME);
1049 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1050 proto_tree_set_time(new_fi, value_ptr);
1056 proto_tree_add_time_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1057 nstime_t *value_ptr)
1061 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
1065 PROTO_ITEM_SET_HIDDEN(pi);
1071 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1072 nstime_t *value_ptr, const char *format, ...)
1077 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
1081 va_start(ap, format);
1082 proto_tree_set_representation(pi, format, ap);
1088 /* Set the FT_*TIME value */
1090 proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
1092 fvalue_set(&fi->value, value_ptr, FALSE);
1095 /* Add a FT_IPXNET to a proto_tree */
1097 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1102 header_field_info *hfinfo;
1107 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1108 g_assert(hfinfo->type == FT_IPXNET);
1110 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1111 proto_tree_set_ipxnet(new_fi, value);
1117 proto_tree_add_ipxnet_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1122 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
1126 PROTO_ITEM_SET_HIDDEN(pi);
1132 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1133 guint32 value, const char *format, ...)
1138 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
1142 va_start(ap, format);
1143 proto_tree_set_representation(pi, format, ap);
1149 /* Set the FT_IPXNET value */
1151 proto_tree_set_ipxnet(field_info *fi, guint32 value)
1153 fvalue_set_integer(&fi->value, value);
1156 /* Add a FT_IPv4 to a proto_tree */
1158 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1163 header_field_info *hfinfo;
1168 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1169 g_assert(hfinfo->type == FT_IPv4);
1171 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1172 proto_tree_set_ipv4(new_fi, value);
1178 proto_tree_add_ipv4_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1183 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
1187 PROTO_ITEM_SET_HIDDEN(pi);
1193 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1194 guint32 value, const char *format, ...)
1199 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
1203 va_start(ap, format);
1204 proto_tree_set_representation(pi, format, ap);
1210 /* Set the FT_IPv4 value */
1212 proto_tree_set_ipv4(field_info *fi, guint32 value)
1214 fvalue_set_integer(&fi->value, value);
1217 /* Add a FT_IPv6 to a proto_tree */
1219 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1220 const guint8* value_ptr)
1224 header_field_info *hfinfo;
1229 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1230 g_assert(hfinfo->type == FT_IPv6);
1232 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1233 proto_tree_set_ipv6(new_fi, value_ptr);
1239 proto_tree_add_ipv6_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1240 const guint8* value_ptr)
1244 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1248 PROTO_ITEM_SET_HIDDEN(pi);
1254 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1255 const guint8* value_ptr, const char *format, ...)
1260 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1264 va_start(ap, format);
1265 proto_tree_set_representation(pi, format, ap);
1271 /* Set the FT_IPv6 value */
1273 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
1275 fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
1279 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start)
1281 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, 16));
1285 proto_tree_set_uint64(field_info *fi, guint64 value)
1287 fvalue_set_integer64(&fi->value, value);
1291 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian)
1295 value = little_endian ? tvb_get_letoh64(tvb, start)
1296 : tvb_get_ntoh64(tvb, start);
1298 proto_tree_set_uint64(fi, value);
1301 /* Add a FT_STRING or FT_STRINGZ to a proto_tree. Creates own copy of string,
1302 * and frees it when the proto_tree is destroyed. */
1304 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1305 gint length, const char* value)
1309 header_field_info *hfinfo;
1314 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1315 g_assert(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
1317 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1318 proto_tree_set_string(new_fi, value, FALSE);
1324 proto_tree_add_string_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1325 gint length, const char* value)
1329 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
1333 PROTO_ITEM_SET_HIDDEN(pi);
1339 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1340 gint length, const char* value, const char *format, ...)
1345 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
1349 va_start(ap, format);
1350 proto_tree_set_representation(pi, format, ap);
1356 /* Appends string data to a FT_STRING or FT_STRINGZ, allowing progressive
1357 * field info update instead of only updating the representation as does
1358 * proto_item_append_text()
1361 proto_item_append_string(proto_item *pi, const char *str)
1364 header_field_info *hfinfo;
1365 gchar *old_str, *new_str;
1372 fi = PITEM_FINFO(pi);
1373 hfinfo = fi->hfinfo;
1374 g_assert(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
1375 old_str = fvalue_get(&fi->value);
1376 new_str = g_malloc(strlen(old_str) + strlen(str) + 1);
1377 sprintf(new_str, "%s%s", old_str, str);
1378 fvalue_set(&fi->value, new_str, TRUE);
1381 /* Set the FT_STRING value */
1383 proto_tree_set_string(field_info *fi, const char* value,
1384 gboolean already_allocated)
1386 fvalue_set(&fi->value, (gpointer) value, already_allocated);
1390 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
1395 length = tvb_ensure_length_remaining(tvb, start);
1398 /* This memory is freed in proto_tree_free_node() */
1399 string = tvb_get_string(tvb, start, length);
1400 proto_tree_set_string(fi, string, TRUE);
1403 /* Add a FT_ETHER to a proto_tree */
1405 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1406 const guint8* value)
1410 header_field_info *hfinfo;
1415 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1416 g_assert(hfinfo->type == FT_ETHER);
1418 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1419 proto_tree_set_ether(new_fi, value);
1425 proto_tree_add_ether_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1426 const guint8* value)
1430 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
1434 PROTO_ITEM_SET_HIDDEN(pi);
1440 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1441 const guint8* value, const char *format, ...)
1446 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
1450 va_start(ap, format);
1451 proto_tree_set_representation(pi, format, ap);
1457 /* Set the FT_ETHER value */
1459 proto_tree_set_ether(field_info *fi, const guint8* value)
1461 fvalue_set(&fi->value, (gpointer) value, FALSE);
1465 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
1467 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, 6));
1470 /* Add a FT_BOOLEAN to a proto_tree */
1472 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1477 header_field_info *hfinfo;
1482 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1483 g_assert(hfinfo->type == FT_BOOLEAN);
1485 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1486 proto_tree_set_boolean(new_fi, value);
1492 proto_tree_add_boolean_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1497 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
1501 PROTO_ITEM_SET_HIDDEN(pi);
1507 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1508 guint32 value, const char *format, ...)
1513 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
1517 va_start(ap, format);
1518 proto_tree_set_representation(pi, format, ap);
1524 /* Set the FT_BOOLEAN value */
1526 proto_tree_set_boolean(field_info *fi, guint32 value)
1528 proto_tree_set_uint(fi, value);
1531 /* Add a FT_FLOAT to a proto_tree */
1533 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1538 header_field_info *hfinfo;
1543 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1544 g_assert(hfinfo->type == FT_FLOAT);
1546 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1547 proto_tree_set_float(new_fi, value);
1553 proto_tree_add_float_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1558 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
1562 PROTO_ITEM_SET_HIDDEN(pi);
1568 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1569 float value, const char *format, ...)
1574 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
1578 va_start(ap, format);
1579 proto_tree_set_representation(pi, format, ap);
1585 /* Set the FT_FLOAT value */
1587 proto_tree_set_float(field_info *fi, float value)
1589 fvalue_set_floating(&fi->value, value);
1592 /* Add a FT_DOUBLE to a proto_tree */
1594 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1599 header_field_info *hfinfo;
1604 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1605 g_assert(hfinfo->type == FT_DOUBLE);
1607 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1608 proto_tree_set_double(new_fi, value);
1614 proto_tree_add_double_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1619 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
1623 PROTO_ITEM_SET_HIDDEN(pi);
1629 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1630 double value, const char *format, ...)
1635 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
1639 va_start(ap, format);
1640 proto_tree_set_representation(pi, format, ap);
1646 /* Set the FT_DOUBLE value */
1648 proto_tree_set_double(field_info *fi, double value)
1650 fvalue_set_floating(&fi->value, value);
1653 /* Add FT_UINT{8,16,24,32} to a proto_tree */
1655 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1658 proto_item *pi = NULL;
1660 header_field_info *hfinfo;
1665 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1666 switch(hfinfo->type) {
1672 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length,
1674 proto_tree_set_uint(new_fi, value);
1678 g_assert_not_reached();
1685 proto_tree_add_uint_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1690 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
1694 PROTO_ITEM_SET_HIDDEN(pi);
1700 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1701 guint32 value, const char *format, ...)
1706 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
1710 va_start(ap, format);
1711 proto_tree_set_representation(pi, format, ap);
1717 /* Set the FT_UINT{8,16,24,32} value */
1719 proto_tree_set_uint(field_info *fi, guint32 value)
1721 header_field_info *hfinfo;
1724 hfinfo = fi->hfinfo;
1727 if (hfinfo->bitmask) {
1728 /* Mask out irrelevant portions */
1729 integer &= hfinfo->bitmask;
1732 if (hfinfo->bitshift > 0) {
1733 integer >>= hfinfo->bitshift;
1736 fvalue_set_integer(&fi->value, integer);
1739 /* Add FT_UINT64 to a proto_tree */
1741 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1744 proto_item *pi = NULL;
1746 header_field_info *hfinfo;
1751 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1752 g_assert(hfinfo->type == FT_UINT64);
1754 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1755 proto_tree_set_uint64(new_fi, value);
1761 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1762 guint64 value, const char *format, ...)
1767 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
1771 va_start(ap, format);
1772 proto_tree_set_representation(pi, format, ap);
1778 /* Add FT_INT{8,16,24,32} to a proto_tree */
1780 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1783 proto_item *pi = NULL;
1785 header_field_info *hfinfo;
1790 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1791 switch(hfinfo->type) {
1796 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length,
1798 proto_tree_set_int(new_fi, value);
1802 g_assert_not_reached();
1809 proto_tree_add_int_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1814 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
1818 PROTO_ITEM_SET_HIDDEN(pi);
1824 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1825 gint32 value, const char *format, ...)
1827 proto_item *pi = NULL;
1830 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
1834 va_start(ap, format);
1835 proto_tree_set_representation(pi, format, ap);
1841 /* Set the FT_INT{8,16,24,32} value */
1843 proto_tree_set_int(field_info *fi, gint32 value)
1845 header_field_info *hfinfo;
1848 hfinfo = fi->hfinfo;
1849 integer = (guint32) value;
1851 if (hfinfo->bitmask) {
1852 /* Mask out irrelevant portions */
1853 integer &= hfinfo->bitmask;
1856 if (hfinfo->bitshift > 0) {
1857 integer >>= hfinfo->bitshift;
1860 fvalue_set_integer(&fi->value, integer);
1863 /* Add FT_INT64 to a proto_tree */
1865 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1868 proto_item *pi = NULL;
1870 header_field_info *hfinfo;
1875 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1876 g_assert(hfinfo->type == FT_INT64);
1878 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1879 proto_tree_set_uint64(new_fi, (guint64)value);
1885 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1886 gint64 value, const char *format, ...)
1891 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
1895 va_start(ap, format);
1896 proto_tree_set_representation(pi, format, ap);
1903 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
1905 proto_tree_add_node(proto_tree *tree, field_info *fi)
1907 proto_node *pnode, *tnode, *sibling;
1911 * Make sure "tree" is ready to have subtrees under it, by
1912 * checking whether it's been given an ett_ value.
1914 * "tnode->finfo" may be null; that's the case for the root
1915 * node of the protocol tree. That node is not displayed,
1916 * so it doesn't need an ett_ value to remember whether it
1921 g_assert(tfi == NULL ||
1922 (tfi->tree_type >= 0 && tfi->tree_type < num_tree_types));
1924 PROTO_NODE_NEW(pnode);
1925 pnode->parent = tnode;
1927 pnode->tree_data = PTREE_DATA(tree);
1929 if (tnode->last_child != NULL) {
1930 sibling = tnode->last_child;
1931 g_assert(sibling->next == NULL);
1932 sibling->next = pnode;
1934 tnode->first_child = pnode;
1935 tnode->last_child = pnode;
1937 return (proto_item*)pnode;
1941 /* Generic way to allocate field_info and add to proto_tree.
1942 * Sets *pfi to address of newly-allocated field_info struct, if pfi is
1945 proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1946 gint *length, field_info **pfi)
1956 fi = alloc_field_info(tree, hfindex, tvb, start, length);
1957 pi = proto_tree_add_node(tree, fi);
1959 /* If the proto_tree wants to keep a record of this finfo
1960 * for quick lookup, then record it. */
1961 hash = PTREE_DATA(tree)->interesting_hfids;
1962 ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
1964 g_ptr_array_add(ptrs, fi);
1967 /* Does the caller want to know the fi pointer? */
1976 alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1979 header_field_info *hfinfo;
1983 * We only allow a null tvbuff if the item has a zero length,
1984 * i.e. if there's no data backing it.
1986 g_assert(tvb != NULL || *length == 0);
1988 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1990 if (*length == -1) {
1992 * For FT_NONE, FT_PROTOCOL, FT_BYTES, and FT_STRING fields,
1993 * a length of -1 means "set the length to what remains in
1996 * The assumption is either that
1998 * 1) the length of the item can only be determined
1999 * by dissection (typically true of items with
2000 * subitems, which are probably FT_NONE or
2005 * 2) if the tvbuff is "short" (either due to a short
2006 * snapshot length or due to lack of reassembly of
2007 * fragments/segments/whatever), we want to display
2008 * what's available in the field (probably FT_BYTES
2009 * or FT_STRING) and then throw an exception later
2013 * 3) the field is defined to be "what's left in the
2016 * so we set the length to what remains in the tvbuff so
2017 * that, if we throw an exception while dissecting, it
2018 * has what is probably the right value.
2020 * For FT_STRINGZ, it means "the string is null-terminated,
2021 * not null-padded; set the length to the actual length
2022 * of the string", and if the tvbuff if short, we just
2023 * throw an exception.
2025 * It's not valid for any other type of field.
2027 switch (hfinfo->type) {
2031 * We allow this to be zero-length - for
2032 * example, an ONC RPC NULL procedure has
2033 * neither arguments nor reply, so the
2034 * payload for that protocol is empty.
2036 * However, if the length is negative, the
2037 * start offset is *past* the byte past the
2038 * end of the tvbuff, so we throw an
2041 *length = tvb_length_remaining(tvb, start);
2044 * Use "tvb_ensure_bytes_exist()"
2045 * to force the appropriate exception
2048 tvb_ensure_bytes_exist(tvb, start, 0);
2055 *length = tvb_ensure_length_remaining(tvb, start);
2060 * Leave the length as -1, so our caller knows
2066 g_assert_not_reached();
2072 fi->hfinfo = hfinfo;
2074 fi->start+=(tvb)?TVB_RAW_OFFSET(tvb):0;
2075 fi->length = *length;
2078 if(!PTREE_DATA(tree)->visible) {
2079 FI_SET_FLAG(fi, FI_HIDDEN);
2081 fvalue_init(&fi->value, fi->hfinfo->type);
2084 /* add the data source tvbuff */
2085 fi->ds_tvb=tvb?TVB_GET_DS_TVB(tvb):NULL;
2090 /* Set representation of a proto_tree entry, if the protocol tree is to
2093 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
2095 int ret; /*tmp return value */
2096 field_info *fi = PITEM_FINFO(pi);
2098 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
2099 ITEM_LABEL_NEW(fi->rep);
2100 ret = vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH, format, ap);
2101 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2102 fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
2106 /* Set text of proto_item after having already been created. */
2108 proto_item_set_text(proto_item *pi, const char *format, ...)
2110 field_info *fi = NULL;
2117 fi = PITEM_FINFO(pi);
2120 ITEM_LABEL_FREE(fi->rep);
2123 va_start(ap, format);
2124 proto_tree_set_representation(pi, format, ap);
2128 /* Append to text of proto_item after having already been created. */
2130 proto_item_append_text(proto_item *pi, const char *format, ...)
2132 field_info *fi = NULL;
2135 int ret; /*tmp return value */
2141 fi = PITEM_FINFO(pi);
2143 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
2144 va_start(ap, format);
2147 * If we don't already have a representation,
2148 * generate the default representation.
2150 if (fi->rep == NULL) {
2151 ITEM_LABEL_NEW(fi->rep);
2152 proto_item_fill_label(fi, fi->rep->representation);
2155 curlen = strlen(fi->rep->representation);
2156 if (ITEM_LABEL_LENGTH > curlen) {
2157 ret = vsnprintf(fi->rep->representation + curlen,
2158 ITEM_LABEL_LENGTH - curlen, format, ap);
2159 if ((ret == -1) || (ret >= (int)(ITEM_LABEL_LENGTH - curlen)))
2160 fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
2167 proto_item_set_len(proto_item *pi, gint length)
2173 fi = PITEM_FINFO(pi);
2174 fi->length = length;
2178 * Sets the length of the item based on its start and on the specified
2179 * offset, which is the offset past the end of the item; as the start
2180 * in the item is relative to the beginning of the data source tvbuff,
2181 * we need to pass in a tvbuff - the end offset is relative to the beginning
2185 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
2191 fi = PITEM_FINFO(pi);
2192 end += TVB_RAW_OFFSET(tvb);
2193 fi->length = end - fi->start;
2197 proto_item_get_len(proto_item *pi)
2199 field_info *fi = PITEM_FINFO(pi);
2204 proto_tree_create_root(void)
2208 /* Initialize the proto_node */
2209 PROTO_NODE_NEW(pnode);
2210 pnode->parent = NULL;
2211 pnode->finfo = NULL;
2212 pnode->tree_data = g_new(tree_data_t, 1);
2214 /* Initialize the tree_data_t */
2215 pnode->tree_data->interesting_hfids =
2216 g_hash_table_new(g_direct_hash, g_direct_equal);
2218 /* Set the default to FALSE so it's easier to
2219 * find errors; if we expect to see the protocol tree
2220 * but for some reason the default 'visible' is not
2221 * changed, then we'll find out very quickly. */
2222 pnode->tree_data->visible = FALSE;
2224 return (proto_tree*) pnode;
2228 /* "prime" a proto_tree with a single hfid that a dfilter
2229 * is interested in. */
2231 proto_tree_prime_hfid(proto_tree *tree, gint hfid)
2233 g_hash_table_insert(PTREE_DATA(tree)->interesting_hfids,
2234 GINT_TO_POINTER(hfid), g_ptr_array_new());
2239 proto_item_add_subtree(proto_item *pi, gint idx) {
2245 fi = PITEM_FINFO(pi);
2246 g_assert(idx >= 0 && idx < num_tree_types);
2247 fi->tree_type = idx;
2248 return (proto_tree*) pi;
2252 proto_item_get_subtree(proto_item *pi) {
2257 fi = PITEM_FINFO(pi);
2258 if (fi->tree_type == -1)
2260 return (proto_tree*) pi;
2264 proto_item_get_parent(proto_item *ti) {
2271 proto_item_get_parent_nth(proto_item *ti, int gen) {
2284 proto_tree_get_parent(proto_tree *tree) {
2287 return (proto_item*) tree;
2291 proto_match_short_name(gconstpointer p_arg, gconstpointer name_arg)
2293 const protocol_t *p = p_arg;
2294 const char *name = name_arg;
2296 return g_strcasecmp(p->short_name, name);
2300 proto_match_name(gconstpointer p_arg, gconstpointer name_arg)
2302 const protocol_t *p = p_arg;
2303 const char *name = name_arg;
2305 return g_strcasecmp(p->name, name);
2309 proto_match_filter_name(gconstpointer p_arg, gconstpointer name_arg)
2311 const protocol_t *p = p_arg;
2312 const char *name = name_arg;
2314 return g_strcasecmp(p->filter_name, name);
2318 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
2320 const protocol_t *p1 = p1_arg;
2321 const protocol_t *p2 = p2_arg;
2323 return g_strcasecmp(p1->short_name, p2->short_name);
2327 proto_register_protocol(char *name, char *short_name, char *filter_name)
2329 protocol_t *protocol;
2330 header_field_info *hfinfo;
2334 * Make sure there's not already a protocol with any of those
2335 * names. Crash if there is, as that's an error in the code,
2336 * and the code has to be fixed not to register more than one
2337 * protocol with the same name.
2339 g_assert(g_list_find_custom(protocols, name, proto_match_name) == NULL);
2340 g_assert(g_list_find_custom(protocols, short_name, proto_match_short_name) == NULL);
2341 g_assert(g_list_find_custom(protocols, filter_name, proto_match_filter_name) == NULL);
2343 /* Add this protocol to the list of known protocols; the list
2344 is sorted by protocol short name. */
2345 protocol = g_malloc(sizeof (protocol_t));
2346 protocol->name = name;
2347 protocol->short_name = short_name;
2348 protocol->filter_name = filter_name;
2349 protocol->fields = NULL;
2350 protocol->is_enabled = TRUE; /* protocol is enabled by default */
2351 protocol->can_toggle = TRUE;
2352 protocols = g_list_insert_sorted(protocols, protocol,
2353 proto_compare_name);
2355 /* Here we do allocate a new header_field_info struct */
2356 hfinfo = g_mem_chunk_alloc(gmc_hfinfo);
2357 hfinfo->name = name;
2358 hfinfo->abbrev = filter_name;
2359 hfinfo->type = FT_PROTOCOL;
2360 hfinfo->strings = NULL;
2361 hfinfo->bitmask = 0;
2362 hfinfo->bitshift = 0;
2364 hfinfo->parent = -1; /* this field differentiates protos and fields */
2366 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
2367 protocol->proto_id = proto_id;
2372 * Routines to use to iterate over the protocols.
2373 * The argument passed to the iterator routines is an opaque cookie to
2374 * their callers; it's the GList pointer for the current element in
2376 * The ID of the protocol is returned, or -1 if there is no protocol.
2379 proto_get_first_protocol(void **cookie)
2381 protocol_t *protocol;
2383 if (protocols == NULL)
2385 *cookie = protocols;
2386 protocol = protocols->data;
2387 return protocol->proto_id;
2391 proto_get_next_protocol(void **cookie)
2393 GList *list_item = *cookie;
2394 protocol_t *protocol;
2396 list_item = g_list_next(list_item);
2397 if (list_item == NULL)
2399 *cookie = list_item;
2400 protocol = list_item->data;
2401 return protocol->proto_id;
2405 proto_get_first_protocol_field(int proto_id, void **cookie)
2407 protocol_t *protocol = find_protocol_by_id(proto_id);
2408 hf_register_info *ptr;
2410 if ((protocol == NULL) || (protocol->fields == NULL))
2413 *cookie = protocol->fields;
2414 ptr = protocol->fields->data;
2415 return &ptr->hfinfo;
2419 proto_get_next_protocol_field(void **cookie)
2421 GList *list_item = *cookie;
2422 hf_register_info *ptr;
2424 list_item = g_list_next(list_item);
2425 if (list_item == NULL)
2428 *cookie = list_item;
2429 ptr = list_item->data;
2430 return &ptr->hfinfo;
2434 * Find the protocol list entry for a protocol given its field ID.
2437 compare_proto_id(gconstpointer proto_arg, gconstpointer id_arg)
2439 const protocol_t *protocol = proto_arg;
2440 const int *id_ptr = id_arg;
2442 return (protocol->proto_id == *id_ptr) ? 0 : 1;
2446 find_protocol_by_id(int proto_id)
2450 list_entry = g_list_find_custom(protocols, &proto_id, compare_proto_id);
2451 if (list_entry == NULL)
2453 return list_entry->data;
2456 static gint compare_filter_name(gconstpointer proto_arg,
2457 gconstpointer filter_name)
2459 const protocol_t *protocol = proto_arg;
2460 const gchar* f_name = filter_name;
2462 return (strcmp(protocol->filter_name, f_name));
2466 proto_get_id(protocol_t *protocol)
2468 return protocol->proto_id;
2471 int proto_get_id_by_filter_name(gchar* filter_name)
2474 protocol_t *protocol;
2476 list_entry = g_list_find_custom(protocols, filter_name,
2477 compare_filter_name);
2478 if (list_entry == NULL)
2480 protocol = list_entry->data;
2481 return protocol->proto_id;
2485 proto_get_protocol_name(int proto_id)
2487 protocol_t *protocol;
2489 protocol = find_protocol_by_id(proto_id);
2490 return protocol->name;
2494 proto_get_protocol_short_name(protocol_t *protocol)
2496 if (protocol == NULL)
2498 return protocol->short_name;
2502 proto_get_protocol_filter_name(int proto_id)
2504 protocol_t *protocol;
2506 protocol = find_protocol_by_id(proto_id);
2507 return protocol->filter_name;
2511 proto_is_protocol_enabled(protocol_t *protocol)
2513 return protocol->is_enabled;
2517 proto_can_toggle_protocol(int proto_id)
2519 protocol_t *protocol;
2521 protocol = find_protocol_by_id(proto_id);
2522 return protocol->can_toggle;
2526 proto_set_decoding(int proto_id, gboolean enabled)
2528 protocol_t *protocol;
2530 protocol = find_protocol_by_id(proto_id);
2531 g_assert(protocol->can_toggle);
2532 protocol->is_enabled = enabled;
2536 proto_set_cant_toggle(int proto_id)
2538 protocol_t *protocol;
2540 protocol = find_protocol_by_id(proto_id);
2541 protocol->can_toggle = FALSE;
2544 /* for use with static arrays only, since we don't allocate our own copies
2545 of the header_field_info struct contained within the hf_register_info struct */
2547 proto_register_field_array(int parent, hf_register_info *hf, int num_records)
2550 hf_register_info *ptr = hf;
2553 proto = find_protocol_by_id(parent);
2554 for (i = 0; i < num_records; i++, ptr++) {
2556 * Make sure we haven't registered this yet.
2557 * Most fields have variables associated with them
2558 * that are initialized to -1; some have array elements,
2559 * or possibly uninitialized variables, so we also allow
2560 * 0 (which is unlikely to be the field ID we get back
2561 * from "proto_register_field_init()").
2563 g_assert(*ptr->p_id == -1 || *ptr->p_id == 0);
2565 if (proto != NULL) {
2566 if (proto->fields == NULL) {
2567 proto->fields = g_list_append(NULL, ptr);
2568 proto->last_field = proto->fields;
2571 g_list_append(proto->last_field, ptr)->next;
2574 field_id = proto_register_field_init(&ptr->hfinfo, parent);
2575 *ptr->p_id = field_id;
2580 proto_register_field_init(header_field_info *hfinfo, int parent)
2582 /* The field must have names */
2583 g_assert(hfinfo->name);
2584 g_assert(hfinfo->abbrev);
2586 /* These types of fields are allowed to have value_strings or true_false_strings */
2587 g_assert((hfinfo->strings == NULL) || (
2588 (hfinfo->type == FT_UINT8) ||
2589 (hfinfo->type == FT_UINT16) ||
2590 (hfinfo->type == FT_UINT24) ||
2591 (hfinfo->type == FT_UINT32) ||
2592 (hfinfo->type == FT_INT8) ||
2593 (hfinfo->type == FT_INT16) ||
2594 (hfinfo->type == FT_INT24) ||
2595 (hfinfo->type == FT_INT32) ||
2596 (hfinfo->type == FT_BOOLEAN) ||
2597 (hfinfo->type == FT_FRAMENUM) ));
2599 switch (hfinfo->type) {
2609 /* Require integral types (other than frame number, which is
2610 always displayed in decimal) to have a number base */
2611 g_assert(hfinfo->display != BASE_NONE);
2615 /* Don't allow bitfields or value strings for frame numbers */
2616 g_assert(hfinfo->bitmask == 0);
2617 g_assert(hfinfo->strings == NULL);
2623 /* if this is a bitfield, compute bitshift */
2624 if (hfinfo->bitmask) {
2625 while ((hfinfo->bitmask & (1 << hfinfo->bitshift)) == 0)
2629 hfinfo->parent = parent;
2630 hfinfo->same_name_next = NULL;
2631 hfinfo->same_name_prev = NULL;
2633 /* if we always add and never delete, then id == len - 1 is correct */
2634 if(gpa_hfinfo.len>=gpa_hfinfo.allocated_len){
2635 if(!gpa_hfinfo.hfi){
2636 gpa_hfinfo.allocated_len=1000;
2637 gpa_hfinfo.hfi=g_malloc(sizeof(header_field_info *)*1000);
2639 gpa_hfinfo.allocated_len+=1000;
2640 gpa_hfinfo.hfi=g_realloc(gpa_hfinfo.hfi, sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
2643 gpa_hfinfo.hfi[gpa_hfinfo.len]=hfinfo;
2645 hfinfo->id = gpa_hfinfo.len - 1;
2647 /* if we have real names, enter this field in the name tree */
2648 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
2650 header_field_info *same_name_hfinfo, *same_name_next_hfinfo;
2654 /* Check that the filter name (abbreviation) is legal;
2655 * it must contain only alphanumerics, '-', "_", and ".". */
2656 for (p = hfinfo->abbrev; (c = *p) != '\0'; p++)
2657 g_assert(isalnum(c) || c == '-' || c == '_' ||
2660 /* We allow multiple hfinfo's to be registered under the same
2661 * abbreviation. This was done for X.25, as, depending
2662 * on whether it's modulo-8 or modulo-128 operation,
2663 * some bitfield fields may be in different bits of
2664 * a byte, and we want to be able to refer to that field
2665 * with one name regardless of whether the packets
2666 * are modulo-8 or modulo-128 packets. */
2667 same_name_hfinfo = g_tree_lookup(gpa_name_tree, hfinfo->abbrev);
2668 if (same_name_hfinfo) {
2669 /* There's already a field with this name.
2670 * Put it after that field in the list of
2671 * fields with this name, then allow the code
2672 * after this if{} block to replace the old
2673 * hfinfo with the new hfinfo in the GTree. Thus,
2674 * we end up with a linked-list of same-named hfinfo's,
2675 * with the root of the list being the hfinfo in the GTree */
2676 same_name_next_hfinfo =
2677 same_name_hfinfo->same_name_next;
2679 hfinfo->same_name_next = same_name_next_hfinfo;
2680 if (same_name_next_hfinfo)
2681 same_name_next_hfinfo->same_name_prev = hfinfo;
2683 same_name_hfinfo->same_name_next = hfinfo;
2684 hfinfo->same_name_prev = same_name_hfinfo;
2686 g_tree_insert(gpa_name_tree, hfinfo->abbrev, hfinfo);
2693 proto_register_subtree_array(gint **indices, int num_indices)
2696 gint **ptr = indices;
2699 * Make sure we haven't already allocated the array of "tree is
2702 * XXX - if it's *really* important to allow more ett_ values to
2703 * be given out after "proto_init()" is called, we could expand
2706 g_assert(tree_is_expanded == NULL);
2709 * Assign "num_indices" subtree numbers starting at "num_tree_types",
2710 * returning the indices through the pointers in the array whose
2711 * first element is pointed to by "indices", and update
2712 * "num_tree_types" appropriately.
2714 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++)
2715 **ptr = num_tree_types;
2719 proto_item_fill_label(field_info *fi, gchar *label_str)
2721 header_field_info *hfinfo = fi->hfinfo;
2726 guint32 n_addr; /* network-order IPv4 address */
2727 int ret; /*tmp return value */
2729 switch(hfinfo->type) {
2732 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2733 "%s", hfinfo->name);
2734 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2735 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2739 fill_label_boolean(fi, label_str);
2744 bytes = fvalue_get(&fi->value);
2746 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2747 "%s: %s", hfinfo->name,
2748 bytes_to_str(bytes, fvalue_length(&fi->value)));
2749 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2750 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2753 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2754 "%s: <MISSING>", hfinfo->name);
2755 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2756 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2760 /* Four types of integers to take care of:
2761 * Bitfield, with val_string
2762 * Bitfield, w/o val_string
2763 * Non-bitfield, with val_string
2764 * Non-bitfield, w/o val_string
2771 if (hfinfo->bitmask) {
2772 if (hfinfo->strings) {
2773 fill_label_enumerated_bitfield(fi, label_str);
2776 fill_label_numeric_bitfield(fi, label_str);
2780 if (hfinfo->strings) {
2781 fill_label_enumerated_uint(fi, label_str);
2784 fill_label_uint(fi, label_str);
2790 fill_label_uint64(fi, label_str);
2797 g_assert(!hfinfo->bitmask);
2798 if (hfinfo->strings) {
2799 fill_label_enumerated_int(fi, label_str);
2802 fill_label_int(fi, label_str);
2807 fill_label_int64(fi, label_str);
2811 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2812 "%s: %." STRINGIFY(FLT_DIG) "f",
2813 hfinfo->name, fvalue_get_floating(&fi->value));
2814 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2815 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2819 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2820 "%s: %." STRINGIFY(DBL_DIG) "g",
2821 hfinfo->name, fvalue_get_floating(&fi->value));
2822 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2823 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2826 case FT_ABSOLUTE_TIME:
2827 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2828 "%s: %s", hfinfo->name,
2829 abs_time_to_str(fvalue_get(&fi->value)));
2830 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2831 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2834 case FT_RELATIVE_TIME:
2835 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2836 "%s: %s seconds", hfinfo->name,
2837 rel_time_to_secs_str(fvalue_get(&fi->value)));
2838 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2839 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2843 integer = fvalue_get_integer(&fi->value);
2844 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2845 "%s: 0x%08X (%s)", hfinfo->name,
2846 integer, get_ipxnet_name(integer));
2847 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2848 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2852 bytes = fvalue_get(&fi->value);
2853 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2854 "%s: %s (%s)", hfinfo->name,
2855 ether_to_str(bytes),
2856 get_ether_name(bytes));
2857 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2858 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2862 ipv4 = fvalue_get(&fi->value);
2863 n_addr = ipv4_get_net_order_addr(ipv4);
2864 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2865 "%s: %s (%s)", hfinfo->name,
2866 get_hostname(n_addr),
2867 ip_to_str((guint8*)&n_addr));
2868 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2869 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2873 bytes = fvalue_get(&fi->value);
2874 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2875 "%s: %s (%s)", hfinfo->name,
2876 get_hostname6((struct e_in6_addr *)bytes),
2877 ip6_to_str((struct e_in6_addr*)bytes));
2878 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2879 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2884 case FT_UINT_STRING:
2885 bytes = fvalue_get(&fi->value);
2886 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2887 "%s: %s", hfinfo->name,
2888 format_text(bytes, strlen(bytes)));
2889 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2890 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2894 g_error("hfinfo->type %d (%s) not handled\n",
2896 ftype_name(hfinfo->type));
2897 g_assert_not_reached();
2903 fill_label_boolean(field_info *fi, gchar *label_str)
2905 char *p = label_str;
2906 int bitfield_byte_length = 0, bitwidth;
2907 guint32 unshifted_value;
2909 int ret; /*tmp return value */
2911 header_field_info *hfinfo = fi->hfinfo;
2912 static const true_false_string default_tf = { "True", "False" };
2913 const true_false_string *tfstring = &default_tf;
2915 if (hfinfo->strings) {
2916 tfstring = (const struct true_false_string*) hfinfo->strings;
2919 value = fvalue_get_integer(&fi->value);
2920 if (hfinfo->bitmask) {
2921 /* Figure out the bit width */
2922 bitwidth = hfinfo_bitwidth(hfinfo);
2925 unshifted_value = value;
2926 if (hfinfo->bitshift > 0) {
2927 unshifted_value <<= hfinfo->bitshift;
2930 /* Create the bitfield first */
2931 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
2932 bitfield_byte_length = p - label_str;
2935 /* Fill in the textual info */
2936 ret = snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
2937 "%s: %s", hfinfo->name,
2938 value ? tfstring->true_string : tfstring->false_string);
2939 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
2940 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2944 /* Fills data for bitfield ints with val_strings */
2946 fill_label_enumerated_bitfield(field_info *fi, gchar *label_str)
2948 char *format = NULL, *p;
2949 int bitfield_byte_length, bitwidth;
2950 guint32 unshifted_value;
2952 int ret; /*tmp return value */
2954 header_field_info *hfinfo = fi->hfinfo;
2956 /* Figure out the bit width */
2957 bitwidth = hfinfo_bitwidth(hfinfo);
2959 /* Pick the proper format string */
2960 format = hfinfo_uint_vals_format(hfinfo);
2963 unshifted_value = fvalue_get_integer(&fi->value);
2964 value = unshifted_value;
2965 if (hfinfo->bitshift > 0) {
2966 unshifted_value <<= hfinfo->bitshift;
2969 /* Create the bitfield first */
2970 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
2971 bitfield_byte_length = p - label_str;
2973 /* Fill in the textual info using stored (shifted) value */
2974 ret = snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
2975 format, hfinfo->name,
2976 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
2977 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
2978 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2982 fill_label_numeric_bitfield(field_info *fi, gchar *label_str)
2984 char *format = NULL, *p;
2985 int bitfield_byte_length, bitwidth;
2986 guint32 unshifted_value;
2988 int ret; /*tmp return value */
2990 header_field_info *hfinfo = fi->hfinfo;
2992 /* Figure out the bit width */
2993 bitwidth = hfinfo_bitwidth(hfinfo);
2995 /* Pick the proper format string */
2996 format = hfinfo_uint_format(hfinfo);
2999 unshifted_value = fvalue_get_integer(&fi->value);
3000 value = unshifted_value;
3001 if (hfinfo->bitshift > 0) {
3002 unshifted_value <<= hfinfo->bitshift;
3005 /* Create the bitfield using */
3006 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
3007 bitfield_byte_length = p - label_str;
3009 /* Fill in the textual info using stored (shifted) value */
3010 ret = snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
3011 format, hfinfo->name, value);
3012 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
3013 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3018 fill_label_enumerated_uint(field_info *fi, gchar *label_str)
3020 char *format = NULL;
3021 header_field_info *hfinfo = fi->hfinfo;
3023 int ret; /*tmp return value */
3025 /* Pick the proper format string */
3026 format = hfinfo_uint_vals_format(hfinfo);
3028 value = fvalue_get_integer(&fi->value);
3030 /* Fill in the textual info */
3031 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3032 format, hfinfo->name,
3033 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
3034 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3035 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3039 fill_label_uint(field_info *fi, gchar *label_str)
3041 char *format = NULL;
3042 header_field_info *hfinfo = fi->hfinfo;
3044 int ret; /*tmp return value */
3046 /* Pick the proper format string */
3047 format = hfinfo_uint_format(hfinfo);
3048 value = fvalue_get_integer(&fi->value);
3050 /* Fill in the textual info */
3051 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3052 format, hfinfo->name, value);
3053 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3054 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3058 fill_label_uint64(field_info *fi, gchar *label_str)
3060 char *format = NULL;
3061 header_field_info *hfinfo = fi->hfinfo;
3063 int ret; /*tmp return value */
3065 /* Pick the proper format string */
3066 format = hfinfo_uint64_format(hfinfo);
3067 value = fvalue_get_integer64(&fi->value);
3069 /* Fill in the textual info */
3070 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3071 format, hfinfo->name, value);
3072 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3073 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3077 fill_label_enumerated_int(field_info *fi, gchar *label_str)
3079 char *format = NULL;
3080 header_field_info *hfinfo = fi->hfinfo;
3082 int ret; /*tmp return value */
3084 /* Pick the proper format string */
3085 format = hfinfo_int_vals_format(hfinfo);
3086 value = fvalue_get_integer(&fi->value);
3088 /* Fill in the textual info */
3089 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3090 format, hfinfo->name,
3091 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
3092 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3093 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3097 fill_label_int(field_info *fi, gchar *label_str)
3099 char *format = NULL;
3100 header_field_info *hfinfo = fi->hfinfo;
3102 int ret; /*tmp return value */
3104 /* Pick the proper format string */
3105 format = hfinfo_int_format(hfinfo);
3106 value = fvalue_get_integer(&fi->value);
3108 /* Fill in the textual info */
3109 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3110 format, hfinfo->name, value);
3111 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3112 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3116 fill_label_int64(field_info *fi, gchar *label_str)
3118 char *format = NULL;
3119 header_field_info *hfinfo = fi->hfinfo;
3121 int ret; /*tmp return value */
3123 /* Pick the proper format string */
3124 format = hfinfo_int64_format(hfinfo);
3125 value = fvalue_get_integer64(&fi->value);
3127 /* Fill in the textual info */
3128 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3129 format, hfinfo->name, value);
3130 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3131 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3135 hfinfo_bitwidth(header_field_info *hfinfo)
3139 if (!hfinfo->bitmask) {
3143 switch(hfinfo->type) {
3161 bitwidth = hfinfo->display; /* hacky? :) */
3164 g_assert_not_reached();
3171 hfinfo_uint_vals_format(header_field_info *hfinfo)
3173 char *format = NULL;
3175 switch(hfinfo->display) {
3177 format = "%s: %s (%u)";
3179 case BASE_OCT: /* I'm lazy */
3180 format = "%s: %s (%o)";
3183 switch(hfinfo->type) {
3185 format = "%s: %s (0x%02x)";
3188 format = "%s: %s (0x%04x)";
3191 format = "%s: %s (0x%06x)";
3194 format = "%s: %s (0x%08x)";
3197 g_assert_not_reached();
3202 g_assert_not_reached();
3209 hfinfo_uint_format(header_field_info *hfinfo)
3211 char *format = NULL;
3213 /* Pick the proper format string */
3214 if (hfinfo->type == FT_FRAMENUM) {
3216 * Frame numbers are always displayed in decimal.
3220 switch(hfinfo->display) {
3224 case BASE_OCT: /* I'm lazy */
3228 switch(hfinfo->type) {
3230 format = "%s: 0x%02x";
3233 format = "%s: 0x%04x";
3236 format = "%s: 0x%06x";
3239 format = "%s: 0x%08x";
3242 g_assert_not_reached();
3247 g_assert_not_reached();
3255 hfinfo_int_vals_format(header_field_info *hfinfo)
3257 char *format = NULL;
3259 switch(hfinfo->display) {
3261 format = "%s: %s (%d)";
3263 case BASE_OCT: /* I'm lazy */
3264 format = "%s: %s (%o)";
3267 switch(hfinfo->type) {
3269 format = "%s: %s (0x%02x)";
3272 format = "%s: %s (0x%04x)";
3275 format = "%s: %s (0x%06x)";
3278 format = "%s: %s (0x%08x)";
3281 g_assert_not_reached();
3286 g_assert_not_reached();
3293 hfinfo_uint64_format(header_field_info *hfinfo)
3295 char *format = NULL;
3297 /* Pick the proper format string */
3298 switch(hfinfo->display) {
3300 format = "%s: %" PRIu64;
3302 case BASE_OCT: /* I'm lazy */
3303 format = "%s: %" PRIo64;
3306 format = "%s: 0x%016" PRIx64;
3309 g_assert_not_reached();
3316 hfinfo_int_format(header_field_info *hfinfo)
3318 char *format = NULL;
3320 /* Pick the proper format string */
3321 switch(hfinfo->display) {
3325 case BASE_OCT: /* I'm lazy */
3329 switch(hfinfo->type) {
3331 format = "%s: 0x%02x";
3334 format = "%s: 0x%04x";
3337 format = "%s: 0x%06x";
3340 format = "%s: 0x%08x";
3343 g_assert_not_reached();
3348 g_assert_not_reached();
3355 hfinfo_int64_format(header_field_info *hfinfo)
3357 char *format = NULL;
3359 /* Pick the proper format string */
3360 switch(hfinfo->display) {
3362 format = "%s: %" PRId64;
3364 case BASE_OCT: /* I'm lazy */
3365 format = "%s: %" PRIo64;
3368 format = "%s: 0x%016" PRIx64;
3371 g_assert_not_reached();
3380 proto_registrar_n(void)
3382 return gpa_hfinfo.len;
3386 proto_registrar_get_name(int n)
3388 header_field_info *hfinfo;
3390 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3391 return hfinfo->name;
3395 proto_registrar_get_abbrev(int n)
3397 header_field_info *hfinfo;
3399 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3400 return hfinfo->abbrev;
3404 proto_registrar_get_ftype(int n)
3406 header_field_info *hfinfo;
3408 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3409 return hfinfo->type;
3413 proto_registrar_get_parent(int n)
3415 header_field_info *hfinfo;
3417 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3418 return hfinfo->parent;
3422 proto_registrar_is_protocol(int n)
3424 header_field_info *hfinfo;
3426 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3427 return (hfinfo->parent == -1 ? TRUE : FALSE);
3430 /* Returns length of field in packet (not necessarily the length
3431 * in our internal representation, as in the case of IPv4).
3432 * 0 means undeterminable at time of registration
3433 * -1 means the field is not registered. */
3435 proto_registrar_get_length(int n)
3437 header_field_info *hfinfo;
3439 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3440 return ftype_length(hfinfo->type);
3445 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
3446 * it exists anywhere, or FALSE if it exists nowhere. */
3448 proto_check_for_protocol_or_field(proto_tree* tree, int id)
3450 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
3455 else if (g_ptr_array_len(ptrs) > 0) {
3463 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
3464 * This only works if the hfindex was "primed" before the dissection
3465 * took place, as we just pass back the already-created GPtrArray*.
3466 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
3469 proto_get_finfo_ptr_array(proto_tree *tree, int id)
3471 return g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
3472 GINT_TO_POINTER(id));
3476 /* Helper struct and function for proto_find_info() */
3483 find_finfo(proto_node *node, gpointer data)
3485 field_info *fi = PITEM_FINFO(node);
3486 if (fi && fi->hfinfo) {
3487 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
3488 g_ptr_array_add(((ffdata_t*)data)->array, fi);
3492 /* Don't stop traversing. */
3496 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
3497 * This works on any proto_tree, primed or unprimed, but actually searches
3498 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
3499 * The caller does need to free the returned GPtrArray with
3500 * g_ptr_array_free(<array>, FALSE).
3503 proto_find_finfo(proto_tree *tree, int id)
3507 ffdata.array = g_ptr_array_new();
3510 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
3512 return ffdata.array;
3523 check_for_offset(proto_node *node, gpointer data)
3525 field_info *fi = PITEM_FINFO(node);
3526 offset_search_t *offsearch = data;
3528 /* !fi == the top most container node which holds nothing */
3529 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
3530 if (offsearch->offset >= (guint) fi->start &&
3531 offsearch->offset < (guint) (fi->start + fi->length)) {
3533 offsearch->finfo = fi;
3534 return FALSE; /* keep traversing */
3537 return FALSE; /* keep traversing */
3540 /* Search a proto_tree backwards (from leaves to root) looking for the field
3541 * whose start/length occupies 'offset' */
3542 /* XXX - I couldn't find an easy way to search backwards, so I search
3543 * forwards, w/o stopping. Therefore, the last finfo I find will the be
3544 * the one I want to return to the user. This algorithm is inefficient
3545 * and could be re-done, but I'd have to handle all the children and
3546 * siblings of each node myself. When I have more time I'll do that.
3549 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
3551 offset_search_t offsearch;
3553 offsearch.offset = offset;
3554 offsearch.finfo = NULL;
3555 offsearch.tvb = tvb;
3557 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
3559 return offsearch.finfo;
3562 /* Dumps the protocols in the registration database to stdout. An independent
3563 * program can take this output and format it into nice tables or HTML or
3566 * There is one record per line. The fields are tab-delimited.
3568 * Field 1 = protocol name
3569 * Field 2 = protocol short name
3570 * Field 3 = protocol filter name
3573 proto_registrar_dump_protocols(void)
3575 protocol_t *protocol;
3579 for (i = proto_get_first_protocol(&cookie); i != -1;
3580 i = proto_get_next_protocol(&cookie)) {
3581 protocol = find_protocol_by_id(i);
3582 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
3583 protocol->filter_name);
3587 /* Dumps the value_string and true/false strings for fields that have
3588 * them. There is one record per line. Fields are tab-delimited.
3589 * There are two types of records, Value String records and True/False
3590 * String records. The first field, 'V' or 'T', indicates the type
3596 * Field 2 = field abbreviation to which this value string corresponds
3597 * Field 3 = Integer value
3600 * True/False Strings
3601 * ------------------
3603 * Field 2 = field abbreviation to which this true/false string corresponds
3604 * Field 3 = True String
3605 * Field 4 = False String
3608 proto_registrar_dump_values(void)
3610 header_field_info *hfinfo, *parent_hfinfo;
3612 const value_string *vals;
3613 const true_false_string *tfs;
3615 len = gpa_hfinfo.len;
3616 for (i = 0; i < len ; i++) {
3617 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
3619 if (hfinfo->id == hf_text_only) {
3623 /* ignore protocols */
3624 if (proto_registrar_is_protocol(i)) {
3627 /* process header fields */
3630 * If this field isn't at the head of the list of
3631 * fields with this name, skip this field - all
3632 * fields with the same name are really just versions
3633 * of the same field stored in different bits, and
3634 * should have the same type/radix/value list, and
3635 * just differ in their bit masks. (If a field isn't
3636 * a bitfield, but can be, say, 1 or 2 bytes long,
3637 * it can just be made FT_UINT16, meaning the
3638 * *maximum* length is 2 bytes, and be used
3641 if (hfinfo->same_name_prev != NULL)
3644 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
3649 if (hfinfo->type == FT_UINT8 ||
3650 hfinfo->type == FT_UINT16 ||
3651 hfinfo->type == FT_UINT24 ||
3652 hfinfo->type == FT_UINT32 ||
3653 hfinfo->type == FT_UINT64 ||
3654 hfinfo->type == FT_INT8 ||
3655 hfinfo->type == FT_INT16 ||
3656 hfinfo->type == FT_INT24 ||
3657 hfinfo->type == FT_INT32 ||
3658 hfinfo->type == FT_INT64) {
3660 vals = hfinfo->strings;
3662 else if (hfinfo->type == FT_BOOLEAN) {
3663 tfs = hfinfo->strings;
3666 /* Print value strings? */
3669 while (vals[vi].strptr) {
3670 /* Print in the proper base */
3671 if (hfinfo->display == BASE_HEX) {
3672 printf("V\t%s\t0x%x\t%s\n",
3678 printf("V\t%s\t%u\t%s\n",
3687 /* Print true/false strings? */
3689 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
3690 tfs->true_string, tfs->false_string);
3696 /* Dumps the contents of the registration database to stdout. An indepedent
3697 * program can take this output and format it into nice tables or HTML or
3700 * There is one record per line. Each record is either a protocol or a header
3701 * field, differentiated by the first field. The fields are tab-delimited.
3706 * Field 2 = descriptive protocol name
3707 * Field 3 = protocol abbreviation
3713 * Field 2 = descriptive field name
3714 * Field 3 = field abbreviation
3715 * Field 4 = type ( textual representation of the the ftenum type )
3716 * Field 5 = parent protocol abbreviation
3718 * (format 2 adds these fields:)
3719 * Field 6 = base for display (for integer types)
3720 * Field 7 = blurb describing field
3723 proto_registrar_dump_fields(int format)
3725 header_field_info *hfinfo, *parent_hfinfo;
3727 const char *enum_name;
3728 const char *base_name;
3730 len = gpa_hfinfo.len;
3731 for (i = 0; i < len ; i++) {
3732 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
3735 * Skip fields with zero-length names or abbreviations;
3736 * the pseudo-field for "proto_tree_add_text()" is such
3737 * a field, and we don't want it in the list of filterable
3741 * XXX - perhaps the name and abbrev field should be null
3742 * pointers rather than null strings for that pseudo-field,
3743 * but we'd have to add checks for null pointers in some
3744 * places if we did that.
3746 * Or perhaps protocol tree items added with
3747 * "proto_tree_add_text()" should have -1 as the field index,
3748 * with no pseudo-field being used, but that might also
3749 * require special checks for -1 to be added.
3751 /* XXX - we could just skip the special text
3752 * pseudo-field by testing: if (hfinfo->id == hf_text_only)
3754 if (hfinfo->name[0] == 0 || hfinfo->abbrev[0] == 0)
3757 /* format for protocols */
3758 if (proto_registrar_is_protocol(i)) {
3759 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
3761 /* format for header fields */
3764 * If this field isn't at the head of the list of
3765 * fields with this name, skip this field - all
3766 * fields with the same name are really just versions
3767 * of the same field stored in different bits, and
3768 * should have the same type/radix/value list, and
3769 * just differ in their bit masks. (If a field isn't
3770 * a bitfield, but can be, say, 1 or 2 bytes long,
3771 * it can just be made FT_UINT16, meaning the
3772 * *maximum* length is 2 bytes, and be used
3775 if (hfinfo->same_name_prev != NULL)
3778 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
3780 enum_name = ftype_name(hfinfo->type);
3784 if (hfinfo->type == FT_UINT8 ||
3785 hfinfo->type == FT_UINT16 ||
3786 hfinfo->type == FT_UINT24 ||
3787 hfinfo->type == FT_UINT32 ||
3788 hfinfo->type == FT_UINT64 ||
3789 hfinfo->type == FT_INT8 ||
3790 hfinfo->type == FT_INT16 ||
3791 hfinfo->type == FT_INT24 ||
3792 hfinfo->type == FT_INT32 ||
3793 hfinfo->type == FT_INT64) {
3796 switch(hfinfo->display) {
3798 base_name = "BASE_NONE";
3801 base_name = "BASE_DEC";
3804 base_name = "BASE_HEX";
3807 base_name = "BASE_OCT";
3814 printf("F\t%s\t%s\t%s\t%s\t%s\n", hfinfo->name, hfinfo->abbrev,
3815 enum_name,parent_hfinfo->abbrev, hfinfo->blurb);
3817 else if (format == 2) {
3818 printf("F\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
3819 hfinfo->name, hfinfo->abbrev,
3820 enum_name,parent_hfinfo->abbrev, hfinfo->blurb,
3821 base_name, hfinfo->blurb);
3828 hfinfo_numeric_format(header_field_info *hfinfo)
3830 char *format = NULL;
3832 /* Pick the proper format string */
3833 if (hfinfo->type == FT_FRAMENUM) {
3835 * Frame numbers are always displayed in decimal.
3837 format = "%s == %u";
3839 /* Pick the proper format string */
3840 switch(hfinfo->display) {
3842 case BASE_OCT: /* I'm lazy */
3843 switch(hfinfo->type) {
3848 format = "%s == %u";
3851 format = "%s == %" PRIu64;
3857 format = "%s == %d";
3860 format = "%s == %" PRId64;
3863 g_assert_not_reached();
3868 switch(hfinfo->type) {
3870 format = "%s == 0x%02x";
3873 format = "%s == 0x%04x";
3876 format = "%s == 0x%06x";
3879 format = "%s == 0x%08x";
3882 format = "%s == 0x%016" PRIx64;
3885 g_assert_not_reached();
3890 g_assert_not_reached();
3898 * Returns TRUE if we can do a "match selected" on the field, FALSE
3902 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
3904 header_field_info *hfinfo;
3907 hfinfo = finfo->hfinfo;
3910 switch(hfinfo->type) {
3929 case FT_ABSOLUTE_TIME:
3930 case FT_RELATIVE_TIME:
3933 case FT_UINT_STRING:
3939 * These all have values, so we can match.
3945 * This doesn't have a value, so we'd match
3946 * on the raw bytes at this address.
3948 * Should we be allowed to access to the raw bytes?
3949 * If "edt" is NULL, the answer is "no".
3955 * Is this field part of the raw frame tvbuff?
3956 * If not, we can't use "frame[N:M]" to match
3959 * XXX - should this be frame-relative, or
3960 * protocol-relative?
3962 * XXX - does this fallback for non-registered
3963 * fields even make sense?
3965 if (finfo->ds_tvb != edt->tvb)
3969 * If the length is 0, there's nothing to match, so
3970 * we can't match. (Also check for negative values,
3971 * just in case, as we'll cast it to an unsigned
3974 length = finfo->length;
3979 * Don't go past the end of that tvbuff.
3981 if ((guint)length > tvb_length(finfo->ds_tvb))
3982 length = tvb_length(finfo->ds_tvb);
3990 proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
3992 header_field_info *hfinfo;
3994 char *buf, *stringified, *format, *ptr;
3996 gint start, length, length_remaining;
3999 hfinfo = finfo->hfinfo;
4001 abbrev_len = strlen(hfinfo->abbrev);
4004 * XXX - we should add "val_to_string_repr" and "string_repr_len"
4005 * functions for more types, and use them whenever possible.
4007 * The FT_UINT and FT_INT types are the only tricky ones, as
4008 * we choose the base in the string expression based on the
4009 * display base of the field.
4011 * Note that the base does matter, as this is also used for
4012 * the protocolinfo tap.
4014 * It might be nice to use that in "proto_item_fill_label()"
4015 * as well, although, there, you'd have to deal with the base
4016 * *and* with resolved values for addresses.
4018 * Perhaps we need two different val_to_string routines, one
4019 * to generate items for display filters and one to generate
4020 * strings for display, and pass to both of them the
4021 * "display" and "strings" values in the header_field_info
4022 * structure for the field, so they can get the base and,
4023 * if the field is Boolean or an enumerated integer type,
4024 * the tables used to generate human-readable values.
4026 switch(hfinfo->type) {
4038 * 4 bytes for " == ".
4041 * a sign + up to 10 digits of 32-bit integer,
4044 * "0x" + 8 digits of 32-bit integer, in hex;
4046 * 11 digits of 32-bit integer, in octal.
4047 * (No, we don't do octal, but this way,
4048 * we know that if we do, this will still
4051 * 1 byte for the trailing '\0'.
4053 dfilter_len = abbrev_len + 4 + 11 + 1;
4054 buf = g_malloc0(dfilter_len);
4055 format = hfinfo_numeric_format(hfinfo);
4056 snprintf(buf, dfilter_len, format, hfinfo->abbrev, fvalue_get_integer(&finfo->value));
4062 * 4 bytes for " == ".
4065 * a sign + up to 20 digits of 32-bit integer,
4068 * "0x" + 16 digits of 32-bit integer, in hex;
4070 * 22 digits of 32-bit integer, in octal.
4071 * (No, we don't do octal, but this way,
4072 * we know that if we do, this will still
4075 * 1 byte for the trailing '\0'.
4077 dfilter_len = abbrev_len + 4 + 22 + 1;
4078 buf = g_malloc0(dfilter_len);
4079 format = hfinfo_numeric_format(hfinfo);
4080 snprintf(buf, dfilter_len, format, hfinfo->abbrev, fvalue_get_integer64(&finfo->value));
4085 * 4 bytes for " == ".
4087 * 8 bytes for 8 digits of 32-bit hex number.
4088 * 1 byte for the trailing '\0'.
4090 dfilter_len = abbrev_len + 4 + 2 + 8 + 1;
4091 buf = g_malloc0(dfilter_len);
4092 snprintf(buf, dfilter_len, "%s == 0x%08x", hfinfo->abbrev,
4093 fvalue_get_integer(&finfo->value));
4098 * 4 bytes for " == ".
4099 * N bytes for the string for the address.
4100 * 1 byte for the trailing '\0'.
4102 stringified = ip6_to_str((struct e_in6_addr*) fvalue_get(&finfo->value));
4103 dfilter_len = abbrev_len + 4 + strlen(stringified) + 1;
4104 buf = g_malloc0(dfilter_len);
4105 snprintf(buf, dfilter_len, "%s == %s", hfinfo->abbrev,
4109 /* These use the fvalue's "to_string_repr" method. */
4117 case FT_ABSOLUTE_TIME:
4118 case FT_RELATIVE_TIME:
4120 /* Figure out the string length needed.
4121 * The ft_repr length.
4122 * 4 bytes for " == ".
4123 * 1 byte for trailing NUL.
4125 dfilter_len = fvalue_string_repr_len(&finfo->value,
4127 dfilter_len += abbrev_len + 4 + 1;
4128 buf = g_malloc0(dfilter_len);
4130 /* Create the string */
4131 snprintf(buf, dfilter_len, "%s == ", hfinfo->abbrev);
4132 fvalue_to_string_repr(&finfo->value,
4134 &buf[abbrev_len + 4]);
4138 buf = g_strdup(finfo->hfinfo->abbrev);
4143 * This doesn't have a value, so we'd match
4144 * on the raw bytes at this address.
4146 * Should we be allowed to access to the raw bytes?
4147 * If "edt" is NULL, the answer is "no".
4153 * Is this field part of the raw frame tvbuff?
4154 * If not, we can't use "frame[N:M]" to match
4157 * XXX - should this be frame-relative, or
4158 * protocol-relative?
4160 * XXX - does this fallback for non-registered
4161 * fields even make sense?
4163 if (finfo->ds_tvb != edt->tvb)
4164 return NULL; /* you lose */
4167 * If the length is 0, there's nothing to match, so
4168 * we can't match. (Also check for negative values,
4169 * just in case, as we'll cast it to an unsigned
4172 length = finfo->length;
4177 * Don't go past the end of that tvbuff.
4179 length_remaining = tvb_length_remaining(finfo->ds_tvb, finfo->start);
4180 if (length > length_remaining)
4181 length = length_remaining;
4185 start = finfo->start;
4186 buf = g_malloc0(32 + length * 3);
4189 sprintf(ptr, "frame[%d:%d] == ", finfo->start, length);
4190 ptr = buf+strlen(buf);
4192 for (i=0;i<length; i++) {
4193 c = tvb_get_guint8(finfo->ds_tvb, start);
4196 sprintf(ptr, "%02x", c);
4199 sprintf(ptr, ":%02x", c);
4201 ptr = buf+strlen(buf);